Skip to content

Commit 321b656

Browse files
committed
Auto merge of rust-lang#118657 - petrochenkov:feedvis, r=cjgillot
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. I suspect that in general this approach should work for queries that are 1) executed for most keys and 2) have results that are cheap to hash (do not have spans, in particular). Visibility query matches that description.
2 parents 43dcc9b + be321aa commit 321b656

File tree

8 files changed

+49
-82
lines changed

8 files changed

+49
-82
lines changed

Diff for: 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();

Diff for: 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

Diff for: 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,

Diff for: 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 {

Diff for: 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.

Diff for: 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

Diff for: 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
_ => {}

Diff for: 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)