From 18d2bd2256b39cd250b35f0865b64180d06f8f43 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 5 Dec 2023 23:16:08 +0300 Subject: [PATCH] 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. --- compiler/rustc_ast_lowering/src/lib.rs | 10 ++-- compiler/rustc_middle/src/hir/map/mod.rs | 4 -- compiler/rustc_middle/src/ty/mod.rs | 1 - compiler/rustc_privacy/src/lib.rs | 55 ++++--------------- .../rustc_resolve/src/build_reduced_graph.rs | 28 +++++----- .../src/effective_visibilities.rs | 4 +- compiler/rustc_resolve/src/late.rs | 2 + compiler/rustc_resolve/src/lib.rs | 13 ++--- 8 files changed, 40 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d435082e12190..8c494646339ba 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -60,10 +60,8 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::{Idx, IndexSlice, IndexVec}; -use rustc_middle::{ - span_bug, - ty::{ResolverAstLowering, TyCtxt}, -}; +use rustc_middle::span_bug; +use rustc_middle::ty::{ResolverAstLowering, TyCtxt, Visibility}; use rustc_session::parse::{add_feature_diagnostics, feature_err}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{DesugaringKind, Span, DUMMY_SP}; @@ -1624,6 +1622,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); debug!(?opaque_ty_def_id); + // Meaningless, but provided so that all items have visibilities. + let parent_mod = self.tcx.parent_module_from_def_id(opaque_ty_def_id).to_def_id(); + self.tcx.feed_local_def_id(opaque_ty_def_id).visibility(Visibility::Restricted(parent_mod)); + // Map from captured (old) lifetime to synthetic (new) lifetime. // Used to resolve lifetimes in the bounds of the opaque. let mut captured_to_synthesized_mapping = FxHashMap::default(); diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index f407d30ac82a3..6d7e0365896da 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1077,8 +1077,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let upstream_crates = upstream_crates(tcx); - let resolutions = tcx.resolutions(()); - // We hash the final, remapped names of all local source files so we // don't have to include the path prefix remapping commandline args. // If we included the full mapping in the SVH, we could only have @@ -1133,8 +1131,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { } tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher); tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher); - // Hash visibility information since it does not appear in HIR. - resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher); stable_hasher.finish() }); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9feda4d205e9c..9dc21c366e5fa 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -158,7 +158,6 @@ pub struct ResolverOutputs { #[derive(Debug)] pub struct ResolverGlobalCtxt { - pub visibilities: FxHashMap, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. pub expn_that_defined: FxHashMap, pub effective_visibilities: EffectiveVisibilities, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e7ec4749efe67..e9ed6068545c9 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1797,52 +1797,17 @@ pub fn provide(providers: &mut Providers) { } fn visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility { - local_visibility(tcx, def_id).to_def_id() -} - -fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility { - match tcx.resolutions(()).visibilities.get(&def_id) { - Some(vis) => *vis, - None => { - let hir_id = tcx.local_def_id_to_hir_id(def_id); - match tcx.hir().get(hir_id) { - // Unique types created for closures participate in type privacy checking. - // They have visibilities inherited from the module they are defined in. - Node::Expr(hir::Expr { kind: hir::ExprKind::Closure{..}, .. }) - // - AST lowering creates dummy `use` items which don't - // get their entries in the resolver's visibility table. - // - AST lowering also creates opaque type items with inherited visibilities. - // Visibility on them should have no effect, but to avoid the visibility - // query failing on some items, we provide it for opaque types as well. - | Node::Item(hir::Item { - kind: hir::ItemKind::Use(_, hir::UseKind::ListStem) - | hir::ItemKind::OpaqueTy(..), - .. - }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_local_def_id()), - // Visibilities of trait impl items are inherited from their traits - // and are not filled in resolve. - Node::ImplItem(impl_item) => { - match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(hir_id).def_id) { - Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }), - .. - }) => tr.path.res.opt_def_id().map_or_else( - || { - tcx.sess.span_delayed_bug(tr.path.span, "trait without a def-id"); - ty::Visibility::Public - }, - |def_id| tcx.visibility(def_id).expect_local(), - ), - _ => span_bug!(impl_item.span, "the parent is not a trait impl"), - } - } - _ => span_bug!( - tcx.def_span(def_id), - "visibility table unexpectedly missing a def-id: {:?}", - def_id, - ), - } + match tcx.hir().get_by_def_id(def_id) { + // Unique types created for closures participate in type privacy checking. + // They have visibilities inherited from the module they are defined in. + Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { + ty::Visibility::Restricted(tcx.parent_module_from_def_id(def_id).to_def_id()) } + _ => span_bug!( + tcx.def_span(def_id), + "visibility query unexpectedly called on a def-id: {:?}", + def_id, + ), } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 65901eedb2148..cc553d916806c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -231,7 +231,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { // (i.e. variants, fields, and trait items) inherits from the visibility // of the enum or trait. ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => { - self.r.visibilities[&def_id.expect_local()] + self.r.tcx.visibility(def_id).expect_local() } // Otherwise, the visibility is restricted to the nearest parent `mod` item. _ => ty::Visibility::Restricted( @@ -399,6 +399,10 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { parent_prefix, use_tree, nested ); + if nested { + self.r.feed_visibility(self.r.local_def_id(id), vis); + } + let mut prefix_iter = parent_prefix .iter() .cloned() @@ -437,8 +441,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let mut source = module_path.pop().unwrap(); let mut type_ns_only = false; - self.r.visibilities.insert(self.r.local_def_id(id), vis); - if nested { // Correctly handle `self` if source.ident.name == kw::SelfLower { @@ -552,7 +554,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { max_vis: Cell::new(None), id, }; - self.r.visibilities.insert(self.r.local_def_id(id), vis); + self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis); } ast::UseTreeKind::Nested(ref items) => { @@ -629,7 +631,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let local_def_id = self.r.local_def_id(item.id); let def_id = local_def_id.to_def_id(); - self.r.visibilities.insert(local_def_id, vis); + self.r.feed_visibility(local_def_id, vis); match item.kind { ItemKind::Use(ref use_tree) => { @@ -753,7 +755,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id()); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); - self.r.visibilities.insert(ctor_def_id, ctor_vis); + self.r.feed_visibility(ctor_def_id, ctor_vis); // We need the field visibility spans also for the constructor for E0603. self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata); @@ -899,7 +901,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let vis = self.resolve_visibility(&item.vis); let res = Res::Def(def_kind, def_id); self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion)); - self.r.visibilities.insert(local_def_id, vis); + self.r.feed_visibility(local_def_id, vis); } fn build_reduced_graph_for_block(&mut self, block: &Block) { @@ -1233,7 +1235,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { self.r.check_reserved_macro_name(ident, res); self.insert_unused_macro(ident, def_id, item.id); } - self.r.visibilities.insert(def_id, vis); + self.r.feed_visibility(def_id, vis); let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding( self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding { parent_macro_rules_scope: parent_scope.macro_rules, @@ -1257,7 +1259,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { self.insert_unused_macro(ident, def_id, item.id); } self.r.define(module, ident, MacroNS, (res, vis, span, expansion)); - self.r.visibilities.insert(def_id, vis); + self.r.feed_visibility(def_id, vis); self.parent_scope.macro_rules } } @@ -1359,7 +1361,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { // Trait impl item visibility is inherited from its trait when not specified // explicitly. In that case we cannot determine it here in early resolve, // so we leave a hole in the visibility table to be filled later. - self.r.visibilities.insert(local_def_id, vis); + self.r.feed_visibility(local_def_id, vis); } if ctxt == AssocCtxt::Trait { @@ -1438,7 +1440,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { self.visit_invoc(sf.id); } else { let vis = self.resolve_visibility(&sf.vis); - self.r.visibilities.insert(self.r.local_def_id(sf.id), vis); + self.r.feed_visibility(self.r.local_def_id(sf.id), vis); visit::walk_field_def(self, sf); } } @@ -1460,7 +1462,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { let res = Res::Def(DefKind::Variant, def_id.to_def_id()); let vis = self.resolve_visibility(&variant.vis); self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id)); - self.r.visibilities.insert(def_id, vis); + self.r.feed_visibility(def_id, vis); // If the variant is marked as non_exhaustive then lower the visibility to within the crate. let ctor_vis = @@ -1476,7 +1478,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id()); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); - self.r.visibilities.insert(ctor_def_id, ctor_vis); + self.r.feed_visibility(ctor_def_id, ctor_vis); } // Record field names for error reporting. diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index a71c50dd82fdd..50352169221d7 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -186,7 +186,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { ) -> Option> { match parent_id { ParentId::Def(def_id) => (nominal_vis != self.current_private_vis - && self.r.visibilities[&def_id] != self.current_private_vis) + && self.r.tcx.local_visibility(def_id) != self.current_private_vis) .then_some(Some(self.current_private_vis)), ParentId::Import(_) => Some(None), } @@ -222,7 +222,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { } fn update_field(&mut self, def_id: LocalDefId, parent_id: LocalDefId) { - self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id)); + self.update_def(def_id, self.r.tcx.local_visibility(def_id), ParentId::Def(parent_id)); } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ad14f5e5225f6..cb813ff90102d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3108,6 +3108,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { | (DefKind::AssocFn, AssocItemKind::Fn(..)) | (DefKind::AssocConst, AssocItemKind::Const(..)) => { self.r.record_partial_res(id, PartialRes::new(res)); + let vis = self.r.tcx.visibility(id_in_trait).expect_local(); + self.r.feed_visibility(self.r.local_def_id(id), vis); return; } _ => {} diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 70e0eb12c01da..9b627141263e1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1007,8 +1007,6 @@ pub struct Resolver<'a, 'tcx> { /// Maps glob imports to the names of items actually imported. glob_map: FxHashMap>, - /// Visibilities in "lowered" form, for all entities that have them. - visibilities: FxHashMap, used_imports: FxHashSet, maybe_unused_trait_imports: FxIndexSet, @@ -1295,9 +1293,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &mut FxHashMap::default(), ); - let mut visibilities = FxHashMap::default(); - visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public); - let mut def_id_to_node_id = IndexVec::default(); assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID); let mut node_id_to_def_id = FxHashMap::default(); @@ -1363,7 +1358,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ast_transform_scopes: FxHashMap::default(), glob_map: Default::default(), - visibilities, used_imports: FxHashSet::default(), maybe_unused_trait_imports: Default::default(), @@ -1450,6 +1444,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let root_parent_scope = ParentScope::module(graph_root, &resolver); resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope); + resolver.feed_visibility(CRATE_DEF_ID, ty::Visibility::Public); resolver } @@ -1497,10 +1492,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Default::default() } + fn feed_visibility(&self, def_id: LocalDefId, vis: ty::Visibility) { + self.tcx.feed_local_def_id(def_id).visibility(vis.to_def_id()); + } + pub fn into_outputs(self) -> ResolverOutputs { let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let expn_that_defined = self.expn_that_defined; - let visibilities = self.visibilities; let extern_crate_map = self.extern_crate_map; let maybe_unused_trait_imports = self.maybe_unused_trait_imports; let glob_map = self.glob_map; @@ -1517,7 +1515,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let global_ctxt = ResolverGlobalCtxt { expn_that_defined, - visibilities, effective_visibilities, extern_crate_map, module_children: self.module_children,