From d8d3b83e3ae6ade8498862d8c110c302abf859d9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 28 Aug 2022 00:10:06 +0300 Subject: [PATCH] rustc: Parameterize `ty::Visibility` over used ID It allows using `LocalDefId` instead of `DefId` when possible, and also encode cheaper `Visibility` into metadata. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 15 +++- .../src/rmeta/decoder/cstore_impl.rs | 6 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/src/metadata.rs | 3 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/assoc.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 6 ++ compiler/rustc_middle/src/ty/mod.rs | 61 +++++++++------ compiler/rustc_middle/src/ty/parameterized.rs | 4 +- compiler/rustc_privacy/src/lib.rs | 76 +++++++++---------- .../rustc_resolve/src/build_reduced_graph.rs | 46 ++++++----- compiler/rustc_resolve/src/ident.rs | 13 ++-- compiler/rustc_resolve/src/imports.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 16 ++-- compiler/rustc_span/src/def_id.rs | 6 ++ .../src/traits/error_reporting/mod.rs | 4 +- compiler/rustc_typeck/src/check/demand.rs | 2 +- compiler/rustc_typeck/src/check/expr.rs | 6 +- .../rustc_typeck/src/check/method/suggest.rs | 2 +- compiler/rustc_typeck/src/check/pat.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +- src/tools/clippy/clippy_lints/src/default.rs | 2 +- src/tools/clippy/clippy_lints/src/derive.rs | 4 +- 24 files changed, 170 insertions(+), 127 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 6f026678170..562246f4e8a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -911,8 +911,14 @@ fn get_generics(self, item_id: DefIndex, sess: &Session) -> ty::Generics { self.root.tables.generics_of.get(self, item_id).unwrap().decode((self, sess)) } - fn get_visibility(self, id: DefIndex) -> ty::Visibility { - self.root.tables.visibility.get(self, id).unwrap().decode(self) + fn get_visibility(self, id: DefIndex) -> ty::Visibility { + self.root + .tables + .visibility + .get(self, id) + .unwrap() + .decode(self) + .map_id(|index| self.local_def_id(index)) } fn get_trait_item_def_id(self, id: DefIndex) -> Option { @@ -1182,7 +1188,10 @@ fn get_struct_field_names( .map(move |index| respan(self.get_span(index, sess), self.item_name(index))) } - fn get_struct_field_visibilities(self, id: DefIndex) -> impl Iterator + 'a { + fn get_struct_field_visibilities( + self, + id: DefIndex, + ) -> impl Iterator> + 'a { self.root .tables .children diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 6b447ebd999..dede1b2122a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -210,7 +210,6 @@ fn into_args(self) -> (DefId, SimplifiedType) { lookup_const_stability => { table } lookup_default_body_stability => { table } lookup_deprecation_entry => { table } - visibility => { table } unused_generic_params => { table } opt_def_kind => { table_direct } impl_parent => { table } @@ -225,6 +224,7 @@ fn into_args(self) -> (DefId, SimplifiedType) { generator_kind => { table } trait_def => { table } + visibility => { cdata.get_visibility(def_id.index) } adt_def => { cdata.get_adt_def(def_id.index, tcx) } adt_destructor => { let _ = cdata; @@ -485,7 +485,7 @@ pub fn struct_field_names_untracked<'a>( pub fn struct_field_visibilities_untracked( &self, def: DefId, - ) -> impl Iterator + '_ { + ) -> impl Iterator> + '_ { self.get_crate_data(def.krate).get_struct_field_visibilities(def.index) } @@ -493,7 +493,7 @@ pub fn ctor_def_id_and_kind_untracked(&self, def: DefId) -> Option<(DefId, CtorK self.get_crate_data(def.krate).get_ctor_def_id_and_kind(def.index) } - pub fn visibility_untracked(&self, def: DefId) -> Visibility { + pub fn visibility_untracked(&self, def: DefId) -> Visibility { self.get_crate_data(def.krate).get_visibility(def.index) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 039486ba02c..b807663b10f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1138,7 +1138,9 @@ fn encode_def_ids(&mut self) { record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); } if should_encode_visibility(def_kind) { - record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id)); + let vis = + self.tcx.local_visibility(local_id).map_id(|def_id| def_id.local_def_index); + record!(self.tables.visibility[def_id] <- vis); } if should_encode_stability(def_kind) { self.encode_stability(def_id); @@ -1727,7 +1729,8 @@ fn encode_proc_macros(&mut self) -> Option { self.tables.opt_def_kind.set(LOCAL_CRATE.as_def_id().index, DefKind::Mod); record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); - record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- tcx.visibility(LOCAL_CRATE.as_def_id())); + let vis = tcx.local_visibility(CRATE_DEF_ID).map_id(|def_id| def_id.local_def_index); + record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); if let Some(stability) = stability { record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 6f849a58580..748b3afec37 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -338,7 +338,7 @@ fn encode(&self, buf: &mut FileEncoder) -> LazyTables { children: Table>, opt_def_kind: Table, - visibility: Table>, + visibility: Table>>, def_span: Table>, def_ident_span: Table>, lookup_stability: Table>, diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index c8e78747d8e..5ff014c7815 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -2,6 +2,7 @@ use rustc_hir::def::Res; use rustc_macros::HashStable; +use rustc_span::def_id::DefId; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -18,7 +19,7 @@ pub struct ModChild { /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter. pub res: Res, /// Visibility of the item. - pub vis: ty::Visibility, + pub vis: ty::Visibility, /// Span of the item. pub span: Span, /// A proper `macro_rules` item (not a reexport). diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 8e7bacca262..4478b45cf14 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1607,7 +1607,7 @@ desc { "looking up late bound vars" } } - query visibility(def_id: DefId) -> ty::Visibility { + query visibility(def_id: DefId) -> ty::Visibility { desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index c97156ac17f..55ee5bd2f81 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -42,7 +42,7 @@ pub fn defaultness(&self, tcx: TyCtxt<'_>) -> hir::Defaultness { } #[inline] - pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { + pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { tcx.visibility(self.def_id) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 262d59f8ff8..c2e5decfc78 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -22,6 +22,7 @@ FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, + Visibility, }; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; @@ -1728,6 +1729,11 @@ pub fn all_traits(self) -> impl Iterator + 'tcx { .chain(self.crates(()).iter().copied()) .flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied()) } + + #[inline] + pub fn local_visibility(self, def_id: LocalDefId) -> Visibility { + self.visibility(def_id.to_def_id()).expect_local() + } } /// A trait implemented for all `X<'a>` types that can be safely and diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a3f7880b9a5..e39a75400e7 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -259,11 +259,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } #[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)] -pub enum Visibility { +pub enum Visibility { /// Visible everywhere (including in other crates). Public, /// Visible only in the given crate-local module. - Restricted(DefId), + Restricted(Id), } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] @@ -354,28 +354,45 @@ fn opt_parent(self, id: DefId) -> Option { } } -impl Visibility { - /// Returns `true` if an item with this visibility is accessible from the given block. - pub fn is_accessible_from(self, module: DefId, tree: T) -> bool { - let restriction = match self { - // Public items are visible everywhere. - Visibility::Public => return true, - // Restricted items are visible in an arbitrary local module. - Visibility::Restricted(other) if other.krate != module.krate => return false, - Visibility::Restricted(module) => module, - }; +impl Visibility { + pub fn is_public(self) -> bool { + matches!(self, Visibility::Public) + } - tree.is_descendant_of(module, restriction) + pub fn map_id(self, f: impl FnOnce(Id) -> OutId) -> Visibility { + match self { + Visibility::Public => Visibility::Public, + Visibility::Restricted(id) => Visibility::Restricted(f(id)), + } + } +} + +impl> Visibility { + pub fn to_def_id(self) -> Visibility { + self.map_id(Into::into) + } + + /// Returns `true` if an item with this visibility is accessible from the given module. + pub fn is_accessible_from(self, module: impl Into, tree: impl DefIdTree) -> bool { + match self { + // Public items are visible everywhere. + Visibility::Public => true, + Visibility::Restricted(id) => tree.is_descendant_of(module.into(), id.into()), + } } /// Returns `true` if this visibility is at least as accessible as the given visibility - pub fn is_at_least(self, vis: Visibility, tree: T) -> bool { - let vis_restriction = match vis { - Visibility::Public => return self == Visibility::Public, - Visibility::Restricted(module) => module, - }; + pub fn is_at_least(self, vis: Visibility>, tree: impl DefIdTree) -> bool { + match vis { + Visibility::Public => self.is_public(), + Visibility::Restricted(id) => self.is_accessible_from(id, tree), + } + } +} - self.is_accessible_from(vis_restriction, tree) +impl Visibility { + pub fn expect_local(self) -> Visibility { + self.map_id(|id| id.expect_local()) } // Returns `true` if this item is visible anywhere in the local crate. @@ -385,10 +402,6 @@ pub fn is_visible_locally(self) -> bool { Visibility::Restricted(def_id) => def_id.is_local(), } } - - pub fn is_public(self) -> bool { - matches!(self, Visibility::Public) - } } /// The crate variances map is computed during typeck and contains the @@ -1790,7 +1803,7 @@ pub enum VariantDiscr { pub struct FieldDef { pub did: DefId, pub name: Symbol, - pub vis: Visibility, + pub vis: Visibility, } impl PartialEq for FieldDef { diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index ca24c0d1ce3..9c8dc30e2db 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -1,4 +1,4 @@ -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, DefIndex}; use rustc_index::vec::{Idx, IndexVec}; use crate::middle::exported_symbols::ExportedSymbol; @@ -60,7 +60,7 @@ impl $crate::ty::ParameterizedOverTcx for $ty { ty::ImplPolarity, ty::ReprOptions, ty::TraitDef, - ty::Visibility, + ty::Visibility, ty::adjustment::CoerceUnsizedInfo, ty::fast_reject::SimplifiedTypeGen, rustc_ast::Attribute, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index ba69bc23118..b2966f0d218 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,6 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(associated_type_defaults)] #![feature(control_flow_enum)] +#![feature(let_else)] #![feature(rustc_private)] #![feature(try_blocks)] #![recursion_limit = "256"] @@ -334,7 +335,9 @@ fn visit_def_id( _kind: &str, _descr: &dyn fmt::Display, ) -> ControlFlow { - self.min = VL::new_min(self, def_id); + if let Some(def_id) = def_id.as_local() { + self.min = VL::new_min(self, def_id); + } ControlFlow::CONTINUE } } @@ -342,7 +345,7 @@ fn visit_def_id( trait VisibilityLike: Sized { const MAX: Self; const SHALLOW: bool = false; - fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self; + fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self; // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to // associated types for which we can't determine visibility precisely. @@ -357,8 +360,8 @@ fn of_impl(def_id: LocalDefId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> } impl VisibilityLike for ty::Visibility { const MAX: Self = ty::Visibility::Public; - fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { - min(find.tcx.visibility(def_id), find.min, find.tcx) + fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { + min(find.tcx.local_visibility(def_id), find.min, find.tcx) } } impl VisibilityLike for Option { @@ -373,15 +376,8 @@ impl VisibilityLike for Option { // both "shallow" version of its self type and "shallow" version of its trait if it exists // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; - fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { - cmp::min( - if let Some(def_id) = def_id.as_local() { - find.access_levels.map.get(&def_id).copied() - } else { - Self::MAX - }, - find.min, - ) + fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { + cmp::min(find.access_levels.map.get(&def_id).copied(), find.min) } } @@ -511,15 +507,15 @@ fn update_macro_reachable_mod(&mut self, module_def_id: LocalDefId, defining_mod let module = self.tcx.hir().get_module(module_def_id).0; for item_id in module.item_ids { let def_kind = self.tcx.def_kind(item_id.def_id); - let vis = self.tcx.visibility(item_id.def_id); + let vis = self.tcx.local_visibility(item_id.def_id); self.update_macro_reachable_def(item_id.def_id, def_kind, vis, defining_mod); } if let Some(exports) = self.tcx.module_reexports(module_def_id) { for export in exports { - if export.vis.is_accessible_from(defining_mod.to_def_id(), self.tcx) { + if export.vis.is_accessible_from(defining_mod, self.tcx) { if let Res::Def(def_kind, def_id) = export.res { if let Some(def_id) = def_id.as_local() { - let vis = self.tcx.visibility(def_id.to_def_id()); + let vis = self.tcx.local_visibility(def_id); self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod); } } @@ -542,7 +538,7 @@ fn update_macro_reachable_def( match def_kind { // No type privacy, so can be directly marked as reachable. DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => { - if vis.is_accessible_from(module.to_def_id(), self.tcx) { + if vis.is_accessible_from(module, self.tcx) { self.update(def_id, level); } } @@ -554,7 +550,7 @@ fn update_macro_reachable_def( DefKind::Macro(_) => { let item = self.tcx.hir().expect_item(def_id); if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { - if vis.is_accessible_from(module.to_def_id(), self.tcx) { + if vis.is_accessible_from(module, self.tcx) { self.update(def_id, level); } } @@ -565,7 +561,7 @@ fn update_macro_reachable_def( // hygiene these don't need to be marked reachable. The contents of // the module, however may be reachable. DefKind::Mod => { - if vis.is_accessible_from(module.to_def_id(), self.tcx) { + if vis.is_accessible_from(module, self.tcx) { self.update_macro_reachable(def_id, module); } } @@ -579,8 +575,8 @@ fn update_macro_reachable_def( { for field in struct_def.fields() { let def_id = self.tcx.hir().local_def_id(field.hir_id); - let field_vis = self.tcx.visibility(def_id); - if field_vis.is_accessible_from(module.to_def_id(), self.tcx) { + let field_vis = self.tcx.local_visibility(def_id); + if field_vis.is_accessible_from(module, self.tcx) { self.reach(def_id, level).ty(); } } @@ -654,7 +650,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { hir::ItemKind::Impl(ref impl_) => { for impl_item_ref in impl_.items { if impl_.of_trait.is_some() - || self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public + || self.tcx.visibility(impl_item_ref.id.def_id).is_public() { self.update(impl_item_ref.id.def_id, item_level); } @@ -682,7 +678,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { } hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public { + if self.tcx.visibility(foreign_item.id.def_id).is_public() { self.update(foreign_item.id.def_id, item_level); } } @@ -1117,7 +1113,7 @@ fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> { } fn item_is_accessible(&self, did: DefId) -> bool { - self.tcx.visibility(did).is_accessible_from(self.current_item.to_def_id(), self.tcx) + self.tcx.visibility(did).is_accessible_from(self.current_item, self.tcx) } // Take node-id of an expression or pattern and check its type for privacy. @@ -1609,8 +1605,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { let mut found_pub_static = false; for impl_item_ref in impl_.items { if self.access_levels.is_reachable(impl_item_ref.id.def_id) - || self.tcx.visibility(impl_item_ref.id.def_id) - == ty::Visibility::Public + || self.tcx.visibility(impl_item_ref.id.def_id).is_public() { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item_ref.kind { @@ -1780,17 +1775,17 @@ fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) ); } - let hir_id = match def_id.as_local() { - Some(def_id) => self.tcx.hir().local_def_id_to_hir_id(def_id), - None => return false, + let Some(local_def_id) = def_id.as_local() else { + return false; }; - let vis = self.tcx.visibility(def_id); + let vis = self.tcx.local_visibility(local_def_id); if !vis.is_at_least(self.required_visibility, self.tcx) { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); let vis_descr = match vis { ty::Visibility::Public => "public", ty::Visibility::Restricted(vis_def_id) => { - if vis_def_id == self.tcx.parent_module(hir_id).to_def_id() { + if vis_def_id == self.tcx.parent_module(hir_id) { "private" } else if vis_def_id.is_top_level_module() { "crate-private" @@ -1906,7 +1901,7 @@ fn check_assoc_item( pub fn check_item(&mut self, id: ItemId) { let tcx = self.tcx; - let item_visibility = tcx.visibility(id.def_id); + let item_visibility = tcx.local_visibility(id.def_id); let def_kind = tcx.def_kind(id.def_id); match def_kind { @@ -1957,7 +1952,7 @@ pub fn check_item(&mut self, id: ItemId) { let item = tcx.hir().item(id); if let hir::ItemKind::ForeignMod { items, .. } = item.kind { for foreign_item in items { - let vis = tcx.visibility(foreign_item.id.def_id); + let vis = tcx.local_visibility(foreign_item.id.def_id); self.check(foreign_item.id.def_id, vis).generics().predicates().ty(); } } @@ -1972,7 +1967,7 @@ pub fn check_item(&mut self, id: ItemId) { for field in struct_def.fields() { let def_id = tcx.hir().local_def_id(field.hir_id); - let field_visibility = tcx.visibility(def_id); + let field_visibility = tcx.local_visibility(def_id); self.check(def_id, min(item_visibility, field_visibility, tcx)).ty(); } } @@ -1992,7 +1987,7 @@ pub fn check_item(&mut self, id: ItemId) { } for impl_item_ref in impl_.items { let impl_item_vis = if impl_.of_trait.is_none() { - min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx) + min(tcx.local_visibility(impl_item_ref.id.def_id), impl_vis, tcx) } else { impl_vis }; @@ -2019,8 +2014,11 @@ pub fn provide(providers: &mut Providers) { }; } -fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { - let def_id = def_id.expect_local(); +fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { + local_visibility(tcx, def_id.expect_local()).to_def_id() +} + +fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility { match tcx.resolutions(()).visibilities.get(&def_id) { Some(vis) => *vis, None => { @@ -2037,7 +2035,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { | Node::Item(hir::Item { kind: hir::ItemKind::Use(_, hir::UseKind::ListStem) | hir::ItemKind::OpaqueTy(..), .. - }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_def_id()), + }) => ty::Visibility::Restricted(tcx.parent_module(hir_id)), // Visibilities of trait impl items are inherited from their traits // and are not filled in resolve. Node::ImplItem(impl_item) => { @@ -2050,7 +2048,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { tcx.sess.delay_span_bug(tr.path.span, "trait without a def-id"); ty::Visibility::Public }, - |def_id| tcx.visibility(def_id), + |def_id| tcx.visibility(def_id).expect_local(), ), _ => span_bug!(impl_item.span, "the parent is not a trait impl"), } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 51e8c24b9c2..9cb735b3685 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -39,24 +39,26 @@ type Res = def::Res; -impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, LocalExpnId) { +impl<'a, Id: Into> ToNameBinding<'a> + for (Module<'a>, ty::Visibility, Span, LocalExpnId) +{ fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Module(self.0), ambiguity: None, - vis: self.1, + vis: self.1.to_def_id(), span: self.2, expansion: self.3, }) } } -impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) { +impl<'a, Id: Into> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Res(self.0, false), ambiguity: None, - vis: self.1, + vis: self.1.to_def_id(), span: self.2, expansion: self.3, }) @@ -70,7 +72,7 @@ fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Res(self.0, true), ambiguity: None, - vis: self.1, + vis: self.1.to_def_id(), span: self.2, expansion: self.3, }) @@ -260,7 +262,9 @@ fn try_resolve_visibility<'ast>( self.r.visibilities[&def_id.expect_local()] } // Otherwise, the visibility is restricted to the nearest parent `mod` item. - _ => ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()), + _ => ty::Visibility::Restricted( + self.parent_scope.module.nearest_parent_mod().expect_local(), + ), }) } ast::VisibilityKind::Restricted { ref path, id, .. } => { @@ -311,7 +315,7 @@ fn try_resolve_visibility<'ast>( } else { let vis = ty::Visibility::Restricted(res.def_id()); if self.r.is_accessible_from(vis, parent_scope.module) { - Ok(vis) + Ok(vis.expect_local()) } else { Err(VisResolutionError::AncestorOnly(path.span)) } @@ -649,7 +653,9 @@ fn build_reduced_graph_for_use_tree( true, // The whole `use` item item, - ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()), + ty::Visibility::Restricted( + self.parent_scope.module.nearest_parent_mod().expect_local(), + ), root_span, ); } @@ -765,10 +771,10 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) { if let Some(ctor_node_id) = vdata.ctor_id() { // If the structure is marked as non_exhaustive then lower the visibility // to within the crate. - let mut ctor_vis = if vis == ty::Visibility::Public + let mut ctor_vis = if vis.is_public() && self.r.session.contains_name(&item.attrs, sym::non_exhaustive) { - ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) + ty::Visibility::Restricted(CRATE_DEF_ID) } else { vis }; @@ -785,7 +791,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) { if ctor_vis.is_at_least(field_vis, &*self.r) { ctor_vis = field_vis; } - ret_fields.push(field_vis); + ret_fields.push(field_vis.to_def_id()); } let ctor_def_id = self.r.local_def_id(ctor_node_id); let ctor_res = Res::Def( @@ -795,7 +801,9 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) { self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); self.r.visibilities.insert(ctor_def_id, ctor_vis); - self.r.struct_constructors.insert(def_id, (ctor_res, ctor_vis, ret_fields)); + self.r + .struct_constructors + .insert(def_id, (ctor_res, ctor_vis.to_def_id(), ret_fields)); } } @@ -867,8 +875,8 @@ fn build_reduced_graph_for_extern_crate( } .map(|module| { let used = self.process_macro_use_imports(item, module); - let binding = - (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); + let vis = ty::Visibility::::Public; + let binding = (module, vis, sp, expansion).to_name_binding(self.r.arenas); (used, Some(ModuleOrUniformRoot::Module(module)), binding) }) .unwrap_or((true, None, self.r.dummy_binding)); @@ -1117,7 +1125,7 @@ fn process_macro_use_imports(&mut self, item: &Item, module: Module<'a>) -> bool root_span: span, span, module_path: Vec::new(), - vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()))), + vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID))), used: Cell::new(false), }) }; @@ -1263,7 +1271,7 @@ fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> { let vis = if is_macro_export { ty::Visibility::Public } else { - ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) + ty::Visibility::Restricted(CRATE_DEF_ID) }; let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas); self.r.set_binding_parent_module(binding, parent_scope.module); @@ -1294,7 +1302,7 @@ fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> { } _ => self.resolve_visibility(&item.vis), }; - if vis != ty::Visibility::Public { + if !vis.is_public() { self.insert_unused_macro(ident, def_id, item.id, &rule_spans); } self.r.define(module, ident, MacroNS, (res, vis, span, expansion)); @@ -1507,10 +1515,10 @@ fn visit_variant(&mut self, variant: &'b ast::Variant) { self.r.visibilities.insert(def_id, vis); // If the variant is marked as non_exhaustive then lower the visibility to within the crate. - let ctor_vis = if vis == ty::Visibility::Public + let ctor_vis = if vis.is_public() && self.r.session.contains_name(&variant.attrs, sym::non_exhaustive) { - ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) + ty::Visibility::Restricted(CRATE_DEF_ID) } else { vis }; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index b84a610833d..2287aa1eb25 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -6,6 +6,7 @@ use rustc_middle::ty; use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; use rustc_session::lint::BuiltinLintDiagnostics; +use rustc_span::def_id::LocalDefId; use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext}; use rustc_span::symbol::{kw, Ident}; @@ -26,6 +27,8 @@ use Namespace::*; use RibKind::*; +type Visibility = ty::Visibility; + impl<'a> Resolver<'a> { /// A generic scope visitor. /// Visits scopes in order to resolve some identifier in them or perform other actions. @@ -424,8 +427,7 @@ struct Flags: u8 { let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); let ok = |res, span, arenas| { Ok(( - (res, ty::Visibility::Public, span, LocalExpnId::ROOT) - .to_name_binding(arenas), + (res, Visibility::Public, span, LocalExpnId::ROOT).to_name_binding(arenas), Flags::empty(), )) }; @@ -438,7 +440,7 @@ struct Flags: u8 { { let binding = ( Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), - ty::Visibility::Public, + Visibility::Public, attr.span, expn_id, ) @@ -841,9 +843,8 @@ fn resolve_ident_in_module_unadjusted_ext( if ns == TypeNS { if ident.name == kw::Crate || ident.name == kw::DollarCrate { let module = self.resolve_crate_root(ident); - let binding = - (module, ty::Visibility::Public, module.span, LocalExpnId::ROOT) - .to_name_binding(self.arenas); + let binding = (module, Visibility::Public, module.span, LocalExpnId::ROOT) + .to_name_binding(self.arenas); return Ok(binding); } else if ident.name == kw::Super || ident.name == kw::SelfLower { // FIXME: Implement these with renaming requirements so that e.g. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 27745cee52d..c133c272bac 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -214,7 +214,7 @@ pub(crate) fn import( binding: &'a NameBinding<'a>, import: &'a Import<'a>, ) -> &'a NameBinding<'a> { - let import_vis = import.expect_vis(); + let import_vis = import.expect_vis().to_def_id(); let vis = if binding.vis.is_at_least(import_vis, self) || pub_use_of_private_extern_crate_hack(import, binding) { @@ -227,7 +227,7 @@ pub(crate) fn import( if vis == import_vis || max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self)) { - max_vis.set(Some(vis)) + max_vis.set(Some(vis.expect_local())) } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index aaa9ae6f325..f7b7313d104 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -648,7 +648,7 @@ pub struct NameBinding<'a> { ambiguity: Option<(&'a NameBinding<'a>, AmbiguityKind)>, expansion: LocalExpnId, span: Span, - vis: ty::Visibility, + vis: ty::Visibility, } pub trait ToNameBinding<'a> { @@ -1012,7 +1012,7 @@ pub struct Resolver<'a> { /// Table for mapping struct IDs into struct constructor IDs, /// it's not used during normal resolution, only for better error reporting. /// Also includes of list of each fields visibility - struct_constructors: DefIdMap<(Res, ty::Visibility, Vec)>, + struct_constructors: DefIdMap<(Res, ty::Visibility, Vec>)>, /// Features enabled for this crate. active_features: FxHashSet, @@ -1808,7 +1808,11 @@ fn record_pat_span(&mut self, node: NodeId, span: Span) { self.pat_span_map.insert(node, span); } - fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool { + fn is_accessible_from( + &self, + vis: ty::Visibility>, + module: Module<'a>, + ) -> bool { vis.is_accessible_from(module.nearest_parent_mod(), self) } @@ -1862,10 +1866,8 @@ fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<&'a Nam self.crate_loader.maybe_process_path_extern(ident.name)? }; let crate_root = self.expect_module(crate_id.as_def_id()); - Some( - (crate_root, ty::Visibility::Public, DUMMY_SP, LocalExpnId::ROOT) - .to_name_binding(self.arenas), - ) + let vis = ty::Visibility::::Public; + Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas)) } }) } diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index a1533fe46b3..ceb6b6c68b0 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -305,6 +305,12 @@ pub fn is_top_level_module(self) -> bool { } } +impl From for DefId { + fn from(local: LocalDefId) -> DefId { + local.to_def_id() + } +} + impl Encodable for DefId { default fn encode(&self, s: &mut E) { self.krate.encode(s); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 9b8bb9e3620..efdb1ace139 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1895,9 +1895,7 @@ fn report_similar_impl_candidates( // FIXME(compiler-errors): This could be generalized, both to // be more granular, and probably look past other `#[fundamental]` // types, too. - self.tcx - .visibility(def.did()) - .is_accessible_from(body_id.owner.to_def_id(), self.tcx) + self.tcx.visibility(def.did()).is_accessible_from(body_id.owner, self.tcx) } else { true } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index d078252ebd4..e1d55ff82cb 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -375,7 +375,7 @@ fn suggest_compatible_variants( let field_is_local = sole_field.did.is_local(); let field_is_accessible = - sole_field.vis.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx) + sole_field.vis.is_accessible_from(expr.hir_id.owner, self.tcx) // Skip suggestions for unstable public fields (for example `Pin::pointer`) && matches!(self.tcx.eval_stability(sole_field.did, None, expr.span, None), EvalResult::Allow | EvalResult::Unmarked); diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index e4141647d7d..0e6a8ef8265 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1729,9 +1729,7 @@ fn check_expr_struct_fields( let private_fields: Vec<&ty::FieldDef> = variant .fields .iter() - .filter(|field| { - !field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx) - }) + .filter(|field| !field.vis.is_accessible_from(tcx.parent_module(expr_id), tcx)) .collect(); if !private_fields.is_empty() { @@ -2343,7 +2341,7 @@ fn ban_nonexisting_field( if let ty::Adt(def, _) = output_ty.kind() && !def.is_enum() { def.non_enum_variant().fields.iter().any(|field| { field.ident(self.tcx) == ident - && field.vis.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx) + && field.vis.is_accessible_from(expr.hir_id.owner, self.tcx) }) } else if let ty::Tuple(tys) = output_ty.kind() && let Ok(idx) = ident.as_str().parse::() diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 124ac5c24fa..8065b848ad6 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1161,7 +1161,7 @@ fn suggest_field_call( _ => None, }); if let Some((field, field_ty)) = field_receiver { - let scope = tcx.parent_module(self.body_id).to_def_id(); + let scope = tcx.parent_module(self.body_id); let is_accessible = field.vis.is_accessible_from(scope, tcx); if is_accessible { diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 9096fc442d4..9fb915a056a 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1397,7 +1397,7 @@ fn check_struct_pat_fields( .iter() .copied() .filter(|(field, _)| { - field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx) + field.vis.is_accessible_from(tcx.parent_module(pat.hir_id), tcx) && !matches!( tcx.eval_stability(field.did, None, DUMMY_SP, None), EvalResult::Deny { .. } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index be2227f47af..944c44f017a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1777,7 +1777,7 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } } -pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility { +pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility { match vis { ty::Visibility::Public => Visibility::Public, ty::Visibility::Restricted(module) => Visibility::Restricted(module), @@ -2111,8 +2111,8 @@ fn clean_use_statement<'tcx>( // `pub(super)` or higher. If the current module is the top level // module, there isn't really a parent module, which makes the results // meaningless. In this case, we make sure the answer is `false`. - let is_visible_from_parent_mod = visibility.is_accessible_from(parent_mod.to_def_id(), cx.tcx) - && !current_mod.is_top_level_module(); + let is_visible_from_parent_mod = + visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module(); if pub_underscore { if let Some(ref inline) = inline_attr { diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index 74f7df61177..4e68d6810e2 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -142,7 +142,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) { if adt.is_struct(); let variant = adt.non_enum_variant(); if adt.did().is_local() || !variant.is_field_list_non_exhaustive(); - let module_did = cx.tcx.parent_module(stmt.hir_id).to_def_id(); + let module_did = cx.tcx.parent_module(stmt.hir_id); if variant .fields .iter() diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 9ca443b7dff..23c86482b46 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -15,7 +15,7 @@ use rustc_middle::traits::Reveal; use rustc_middle::ty::{ self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef, - Ty, TyCtxt, Visibility, + Ty, TyCtxt, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; @@ -464,7 +464,7 @@ fn nested_visit_map(&mut self) -> Self::Map { fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { if_chain! { if let ty::Adt(adt, substs) = ty.kind(); - if cx.tcx.visibility(adt.did()) == Visibility::Public; + if cx.tcx.visibility(adt.did()).is_public(); if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq); if let Some(def_id) = trait_ref.trait_def_id(); if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id);