Skip to content

Commit be321aa

Browse files
committed
resolve: Replace visibility table in resolver outputs with query feeding
Also feed missing visibilities for import stems and trait impl items, which were previously evaluated lazily.
1 parent 6a62871 commit be321aa

File tree

8 files changed

+49
-82
lines changed

8 files changed

+49
-82
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,8 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5959
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
6060
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
6161
use rustc_index::{Idx, IndexSlice, IndexVec};
62-
use rustc_middle::{
63-
span_bug,
64-
ty::{ResolverAstLowering, TyCtxt},
65-
};
62+
use rustc_middle::span_bug;
63+
use rustc_middle::ty::{ResolverAstLowering, TyCtxt, Visibility};
6664
use rustc_session::parse::{add_feature_diagnostics, feature_err};
6765
use rustc_span::symbol::{kw, sym, Ident, Symbol};
6866
use rustc_span::{DesugaringKind, Span, DUMMY_SP};
@@ -1653,6 +1651,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16531651
);
16541652
debug!(?opaque_ty_def_id);
16551653

1654+
// Meaningless, but provided so that all items have visibilities.
1655+
let parent_mod = self.tcx.parent_module_from_def_id(opaque_ty_def_id).to_def_id();
1656+
self.tcx.feed_local_def_id(opaque_ty_def_id).visibility(Visibility::Restricted(parent_mod));
1657+
16561658
// Map from captured (old) lifetime to synthetic (new) lifetime.
16571659
// Used to resolve lifetimes in the bounds of the opaque.
16581660
let mut captured_to_synthesized_mapping = FxHashMap::default();

compiler/rustc_middle/src/hir/map/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,10 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
11421142
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
11431143
tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher);
11441144
// Hash visibility information since it does not appear in HIR.
1145-
resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher);
1145+
// FIXME: Figure out how to remove `visibilities_for_hashing` by hashing visibilities on
1146+
// the fly in the resolver, storing only their accumulated hash in `ResolverGlobalCtxt`,
1147+
// and combining it with other hashes here.
1148+
resolutions.visibilities_for_hashing.hash_stable(&mut hcx, &mut stable_hasher);
11461149
stable_hasher.finish()
11471150
});
11481151

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub struct ResolverOutputs {
152152

153153
#[derive(Debug)]
154154
pub struct ResolverGlobalCtxt {
155-
pub visibilities: FxHashMap<LocalDefId, Visibility>,
155+
pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>,
156156
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
157157
pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
158158
pub effective_visibilities: EffectiveVisibilities,

compiler/rustc_privacy/src/lib.rs

+10-53
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ use rustc_hir as hir;
2323
use rustc_hir::def::{DefKind, Res};
2424
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, CRATE_DEF_ID};
2525
use rustc_hir::intravisit::{self, Visitor};
26-
use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, Node, PatKind};
26+
use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, PatKind};
2727
use rustc_middle::bug;
2828
use rustc_middle::hir::nested_filter;
2929
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
3030
use rustc_middle::query::Providers;
31-
use rustc_middle::span_bug;
3231
use rustc_middle::ty::GenericArgs;
3332
use rustc_middle::ty::{self, Const, GenericParamDefKind};
3433
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -1766,64 +1765,22 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
17661765

17671766
pub fn provide(providers: &mut Providers) {
17681767
*providers = Providers {
1769-
visibility,
1768+
visibility: |tcx, def_id| {
1769+
// Unique types created for closures participate in type privacy checking.
1770+
// They have visibilities inherited from the module they are defined in.
1771+
// FIXME: Consider evaluating visibilities for closures eagerly, like for all
1772+
// other nodes. However, unlike for others, for closures it may cause a perf
1773+
// regression, because closure visibilities are not commonly queried.
1774+
assert_eq!(tcx.def_kind(def_id), DefKind::Closure);
1775+
ty::Visibility::Restricted(tcx.parent_module_from_def_id(def_id).to_def_id())
1776+
},
17701777
effective_visibilities,
17711778
check_private_in_public,
17721779
check_mod_privacy,
17731780
..*providers
17741781
};
17751782
}
17761783

1777-
fn visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility<DefId> {
1778-
local_visibility(tcx, def_id).to_def_id()
1779-
}
1780-
1781-
fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
1782-
match tcx.resolutions(()).visibilities.get(&def_id) {
1783-
Some(vis) => *vis,
1784-
None => {
1785-
let hir_id = tcx.local_def_id_to_hir_id(def_id);
1786-
match tcx.hir_node(hir_id) {
1787-
// Unique types created for closures participate in type privacy checking.
1788-
// They have visibilities inherited from the module they are defined in.
1789-
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure{..}, .. })
1790-
// - AST lowering creates dummy `use` items which don't
1791-
// get their entries in the resolver's visibility table.
1792-
// - AST lowering also creates opaque type items with inherited visibilities.
1793-
// Visibility on them should have no effect, but to avoid the visibility
1794-
// query failing on some items, we provide it for opaque types as well.
1795-
| Node::Item(hir::Item {
1796-
kind: hir::ItemKind::Use(_, hir::UseKind::ListStem)
1797-
| hir::ItemKind::OpaqueTy(..),
1798-
..
1799-
}) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_local_def_id()),
1800-
// Visibilities of trait impl items are inherited from their traits
1801-
// and are not filled in resolve.
1802-
Node::ImplItem(impl_item) => {
1803-
match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(hir_id).def_id) {
1804-
Node::Item(hir::Item {
1805-
kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }),
1806-
..
1807-
}) => tr.path.res.opt_def_id().map_or_else(
1808-
|| {
1809-
tcx.sess.span_delayed_bug(tr.path.span, "trait without a def-id");
1810-
ty::Visibility::Public
1811-
},
1812-
|def_id| tcx.visibility(def_id).expect_local(),
1813-
),
1814-
_ => span_bug!(impl_item.span, "the parent is not a trait impl"),
1815-
}
1816-
}
1817-
_ => span_bug!(
1818-
tcx.def_span(def_id),
1819-
"visibility table unexpectedly missing a def-id: {:?}",
1820-
def_id,
1821-
),
1822-
}
1823-
}
1824-
}
1825-
}
1826-
18271784
fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
18281785
// Check privacy of names not checked in previous compilation stages.
18291786
let mut visitor = NamePrivacyVisitor {

compiler/rustc_resolve/src/build_reduced_graph.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
236236
// (i.e. variants, fields, and trait items) inherits from the visibility
237237
// of the enum or trait.
238238
ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => {
239-
self.r.visibilities[&def_id.expect_local()]
239+
self.r.tcx.visibility(def_id).expect_local()
240240
}
241241
// Otherwise, the visibility is restricted to the nearest parent `mod` item.
242242
_ => ty::Visibility::Restricted(
@@ -404,6 +404,10 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
404404
parent_prefix, use_tree, nested
405405
);
406406

407+
if nested {
408+
self.r.feed_visibility(self.r.local_def_id(id), vis);
409+
}
410+
407411
let mut prefix_iter = parent_prefix
408412
.iter()
409413
.cloned()
@@ -442,8 +446,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
442446
let mut source = module_path.pop().unwrap();
443447
let mut type_ns_only = false;
444448

445-
self.r.visibilities.insert(self.r.local_def_id(id), vis);
446-
447449
if nested {
448450
// Correctly handle `self`
449451
if source.ident.name == kw::SelfLower {
@@ -557,7 +559,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
557559
max_vis: Cell::new(None),
558560
id,
559561
};
560-
self.r.visibilities.insert(self.r.local_def_id(id), vis);
562+
561563
self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis);
562564
}
563565
ast::UseTreeKind::Nested(ref items) => {
@@ -636,7 +638,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
636638
let def_kind = self.r.tcx.def_kind(def_id);
637639
let res = Res::Def(def_kind, def_id);
638640

639-
self.r.visibilities.insert(local_def_id, vis);
641+
self.r.feed_visibility(local_def_id, vis);
640642

641643
match item.kind {
642644
ItemKind::Use(ref use_tree) => {
@@ -753,7 +755,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
753755
let ctor_def_id = self.r.local_def_id(ctor_node_id);
754756
let ctor_res = self.res(ctor_def_id);
755757
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
756-
self.r.visibilities.insert(ctor_def_id, ctor_vis);
758+
self.r.feed_visibility(ctor_def_id, ctor_vis);
757759
// We need the field visibility spans also for the constructor for E0603.
758760
self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata);
759761

@@ -897,7 +899,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
897899
let expansion = self.parent_scope.expansion;
898900
let vis = self.resolve_visibility(&item.vis);
899901
self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion));
900-
self.r.visibilities.insert(local_def_id, vis);
902+
self.r.feed_visibility(local_def_id, vis);
901903
}
902904

903905
fn build_reduced_graph_for_block(&mut self, block: &Block) {
@@ -1228,7 +1230,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
12281230
self.r.check_reserved_macro_name(ident, res);
12291231
self.insert_unused_macro(ident, def_id, item.id);
12301232
}
1231-
self.r.visibilities.insert(def_id, vis);
1233+
self.r.feed_visibility(def_id, vis);
12321234
let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding(
12331235
self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding {
12341236
parent_macro_rules_scope: parent_scope.macro_rules,
@@ -1252,7 +1254,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
12521254
self.insert_unused_macro(ident, def_id, item.id);
12531255
}
12541256
self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
1255-
self.r.visibilities.insert(def_id, vis);
1257+
self.r.feed_visibility(def_id, vis);
12561258
self.parent_scope.macro_rules
12571259
}
12581260
}
@@ -1354,7 +1356,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
13541356
// Trait impl item visibility is inherited from its trait when not specified
13551357
// explicitly. In that case we cannot determine it here in early resolve,
13561358
// so we leave a hole in the visibility table to be filled later.
1357-
self.r.visibilities.insert(local_def_id, vis);
1359+
self.r.feed_visibility(local_def_id, vis);
13581360
}
13591361

13601362
if ctxt == AssocCtxt::Trait {
@@ -1432,7 +1434,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
14321434
self.visit_invoc(sf.id);
14331435
} else {
14341436
let vis = self.resolve_visibility(&sf.vis);
1435-
self.r.visibilities.insert(self.r.local_def_id(sf.id), vis);
1437+
self.r.feed_visibility(self.r.local_def_id(sf.id), vis);
14361438
visit::walk_field_def(self, sf);
14371439
}
14381440
}
@@ -1453,7 +1455,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
14531455
let def_id = self.r.local_def_id(variant.id);
14541456
let vis = self.resolve_visibility(&variant.vis);
14551457
self.r.define(parent, ident, TypeNS, (self.res(def_id), vis, variant.span, expn_id));
1456-
self.r.visibilities.insert(def_id, vis);
1458+
self.r.feed_visibility(def_id, vis);
14571459

14581460
// If the variant is marked as non_exhaustive then lower the visibility to within the crate.
14591461
let ctor_vis =
@@ -1468,7 +1470,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
14681470
let ctor_def_id = self.r.local_def_id(ctor_node_id);
14691471
let ctor_res = self.res(ctor_def_id);
14701472
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
1471-
self.r.visibilities.insert(ctor_def_id, ctor_vis);
1473+
self.r.feed_visibility(ctor_def_id, ctor_vis);
14721474
}
14731475

14741476
// Record field names for error reporting.

compiler/rustc_resolve/src/effective_visibilities.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
186186
) -> Option<Option<Visibility>> {
187187
match parent_id {
188188
ParentId::Def(def_id) => (nominal_vis != self.current_private_vis
189-
&& self.r.visibilities[&def_id] != self.current_private_vis)
189+
&& self.r.tcx.local_visibility(def_id) != self.current_private_vis)
190190
.then_some(Some(self.current_private_vis)),
191191
ParentId::Import(_) => Some(None),
192192
}
@@ -222,7 +222,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
222222
}
223223

224224
fn update_field(&mut self, def_id: LocalDefId, parent_id: LocalDefId) {
225-
self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id));
225+
self.update_def(def_id, self.r.tcx.local_visibility(def_id), ParentId::Def(parent_id));
226226
}
227227
}
228228

compiler/rustc_resolve/src/late.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3112,6 +3112,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
31123112
| (DefKind::AssocFn, AssocItemKind::Fn(..))
31133113
| (DefKind::AssocConst, AssocItemKind::Const(..)) => {
31143114
self.r.record_partial_res(id, PartialRes::new(res));
3115+
let vis = self.r.tcx.visibility(id_in_trait).expect_local();
3116+
self.r.feed_visibility(self.r.local_def_id(id), vis);
31153117
return;
31163118
}
31173119
_ => {}

compiler/rustc_resolve/src/lib.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -1007,8 +1007,7 @@ pub struct Resolver<'a, 'tcx> {
10071007

10081008
/// Maps glob imports to the names of items actually imported.
10091009
glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
1010-
/// Visibilities in "lowered" form, for all entities that have them.
1011-
visibilities: FxHashMap<LocalDefId, ty::Visibility>,
1010+
visibilities_for_hashing: Vec<(LocalDefId, ty::Visibility)>,
10121011
used_imports: FxHashSet<NodeId>,
10131012
maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
10141013

@@ -1295,9 +1294,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12951294
&mut FxHashMap::default(),
12961295
);
12971296

1298-
let mut visibilities = FxHashMap::default();
1299-
visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public);
1300-
13011297
let mut def_id_to_node_id = IndexVec::default();
13021298
assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID);
13031299
let mut node_id_to_def_id = FxHashMap::default();
@@ -1363,7 +1359,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
13631359
ast_transform_scopes: FxHashMap::default(),
13641360

13651361
glob_map: Default::default(),
1366-
visibilities,
1362+
visibilities_for_hashing: Default::default(),
13671363
used_imports: FxHashSet::default(),
13681364
maybe_unused_trait_imports: Default::default(),
13691365

@@ -1450,6 +1446,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14501446

14511447
let root_parent_scope = ParentScope::module(graph_root, &resolver);
14521448
resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope);
1449+
resolver.feed_visibility(CRATE_DEF_ID, ty::Visibility::Public);
14531450

14541451
resolver
14551452
}
@@ -1497,10 +1494,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14971494
Default::default()
14981495
}
14991496

1497+
fn feed_visibility(&mut self, def_id: LocalDefId, vis: ty::Visibility) {
1498+
self.tcx.feed_local_def_id(def_id).visibility(vis.to_def_id());
1499+
self.visibilities_for_hashing.push((def_id, vis));
1500+
}
1501+
15001502
pub fn into_outputs(self) -> ResolverOutputs {
15011503
let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
15021504
let expn_that_defined = self.expn_that_defined;
1503-
let visibilities = self.visibilities;
15041505
let extern_crate_map = self.extern_crate_map;
15051506
let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
15061507
let glob_map = self.glob_map;
@@ -1517,7 +1518,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15171518

15181519
let global_ctxt = ResolverGlobalCtxt {
15191520
expn_that_defined,
1520-
visibilities,
1521+
visibilities_for_hashing: self.visibilities_for_hashing,
15211522
effective_visibilities,
15221523
extern_crate_map,
15231524
module_children: self.module_children,

0 commit comments

Comments
 (0)