From 9e50375645b4df58506eab1827887140ea5bf758 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 15:20:02 +0300 Subject: [PATCH 1/8] initial commit for effective vis table impl in rustc_resolve --- compiler/rustc_middle/src/middle/privacy.rs | 35 +++++++++++- compiler/rustc_resolve/src/access_levels.rs | 59 ++++++++++++++++++--- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index c595fbec0dd5c..cfcef810daaea 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -1,7 +1,7 @@ //! A pass that checks to make sure private fields and methods aren't used //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. -use crate::ty::Visibility; +use crate::ty::{Visibility, DefIdTree}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; @@ -58,6 +58,35 @@ impl EffectiveVisibility { pub fn is_public_at_level(&self, tag: AccessLevel) -> bool { self.get(tag).map_or(false, |vis| vis.is_public()) } + + pub fn nearest_available(&self, tag: AccessLevel) -> Option { + for level in [AccessLevel::ReachableFromImplTrait, AccessLevel::Reachable, AccessLevel::Exported, AccessLevel::Public] { + if (level <= tag) && self.get(tag).is_some() { + return self.get(tag).cloned(); + } + } + None + } + + pub fn update(&mut self, vis: Visibility, tag: AccessLevel, tree: T) { + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + if level <= tag { + let current_effective_vis = self.get_mut(level); + if let Some(current_effective_vis) = current_effective_vis { + if vis.is_at_least(*current_effective_vis, tree) { + *current_effective_vis = vis; + } + } else { + *current_effective_vis = Some(vis); + } + } + } + } } /// Holds a map of accessibility levels for reachable HIR nodes. @@ -122,6 +151,10 @@ impl AccessLevels { self.map.get(&id) } + pub fn set_effective_vis(&mut self, id: Id, effective_vis: EffectiveVisibility) { + self.map.insert(id, effective_vis); + } + pub fn iter(&self) -> impl Iterator { self.map.iter() } diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index 9b1111c02c73f..30da1ec7ee54a 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -11,7 +11,7 @@ use rustc_ast::NodeId; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::CRATE_DEF_ID; use rustc_middle::middle::privacy::AccessLevel; -use rustc_middle::ty::DefIdTree; +use rustc_middle::ty::{DefIdTree, Visibility}; use rustc_span::sym; pub struct AccessLevelsVisitor<'r, 'a> { @@ -26,6 +26,11 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) { let mut visitor = AccessLevelsVisitor { r, changed: false }; + /* + let crate_effective_vis = EffectiveVisibility::default(); + crate_effective_vis.update(Visibility::Public, AccessLevel::Public, visitor.r); + visitor.r.access_levels.set_effective_vis(CRATE_DEF_ID, crate_effective_vis); + */ visitor.set_access_level_def_id(CRATE_DEF_ID, Some(AccessLevel::Public)); visitor.set_bindings_access_level(CRATE_DEF_ID); @@ -47,9 +52,6 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { fn set_bindings_access_level(&mut self, module_id: LocalDefId) { assert!(self.r.module_map.contains_key(&&module_id.to_def_id())); let module_level = self.r.access_levels.get_access_level(module_id); - if !module_level.is_some() { - return; - } // Set the given binding access level to `AccessLevel::Public` and // sets the rest of the `use` chain to `AccessLevel::Exported` until // we hit the actual exported item. @@ -72,8 +74,8 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { let module = self.r.get_module(module_id.to_def_id()).unwrap(); let resolutions = self.r.resolutions(module); - for (.., name_resolution) in resolutions.borrow().iter() { - if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() { + for (key, name_resolution) in resolutions.borrow().iter() { + if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() && module_level.is_some() { let access_level = match binding.is_import() { true => { set_import_binding_access_level(self, binding, module_level); @@ -85,6 +87,51 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { self.set_access_level_def_id(def_id, access_level); } } + + if let Some(binding) = name_resolution.borrow().binding() { + println!("ident: {}", key.ident.as_str()); + if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { + let tag = match binding.is_import() { + true => AccessLevel::Exported, + false => AccessLevel::Public, + }; + let vis = match binding.vis { + Visibility::Public => Visibility::Public, + Visibility::Restricted(id) => Visibility::Restricted(id.expect_local()) + }; + self.update_effective_vis(def_id, vis, module_id, tag); + }; + } + } + } + + // fn init_crate_effective_vis(&mut self) { + + // } + + fn update_effective_vis( + &mut self, + current_id: LocalDefId, + current_vis: Visibility, + module_id: LocalDefId, + tag: AccessLevel, + ) { + if let Some(inherited_effective_vis) = self.r.access_levels.get_effective_vis(module_id) { + println!("tag: {:?}", tag); + println!("inherited effective vis: {:?}", inherited_effective_vis); + let mut current_effective_vis = self.r.access_levels.get_effective_vis(current_id).copied().unwrap_or_default(); + let nearest_available_vis = inherited_effective_vis.nearest_available(tag).unwrap(); + println!("nearest available vis: {:?}", nearest_available_vis); + let calculated_effective_vis = match current_vis { + Visibility::Public => nearest_available_vis, + Visibility::Restricted(_) => { + if current_vis.is_at_least(nearest_available_vis, &*self.r) {nearest_available_vis} else {current_vis} + } + }; + println!("calculated effective vis: {:?}", calculated_effective_vis); + current_effective_vis.update(calculated_effective_vis, tag, &*self.r); + println!("updated effective vis: {:?}", current_effective_vis); + self.r.access_levels.set_effective_vis(current_id, current_effective_vis); } } From 0ec13c69e923242ca928780f6182d54d9734f9c7 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 15:39:37 +0300 Subject: [PATCH 2/8] cleaunup --- compiler/rustc_resolve/src/access_levels.rs | 41 +++++---------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index 30da1ec7ee54a..6f478150d68bf 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -26,11 +26,6 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) { let mut visitor = AccessLevelsVisitor { r, changed: false }; - /* - let crate_effective_vis = EffectiveVisibility::default(); - crate_effective_vis.update(Visibility::Public, AccessLevel::Public, visitor.r); - visitor.r.access_levels.set_effective_vis(CRATE_DEF_ID, crate_effective_vis); - */ visitor.set_access_level_def_id(CRATE_DEF_ID, Some(AccessLevel::Public)); visitor.set_bindings_access_level(CRATE_DEF_ID); @@ -74,41 +69,30 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { let module = self.r.get_module(module_id.to_def_id()).unwrap(); let resolutions = self.r.resolutions(module); - for (key, name_resolution) in resolutions.borrow().iter() { - if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() && module_level.is_some() { - let access_level = match binding.is_import() { + for (.., name_resolution) in resolutions.borrow().iter() { + + if let Some(binding) = name_resolution.borrow().binding() { + let tag = match binding.is_import() { true => { - set_import_binding_access_level(self, binding, module_level); - Some(AccessLevel::Exported) + if binding.vis.is_public() && !binding.is_ambiguity() && module_level.is_some() { + set_import_binding_access_level(self, binding, module_level); + } + AccessLevel::Exported }, - false => module_level, + false => AccessLevel::Public }; - if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { - self.set_access_level_def_id(def_id, access_level); - } - } - if let Some(binding) = name_resolution.borrow().binding() { - println!("ident: {}", key.ident.as_str()); if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { - let tag = match binding.is_import() { - true => AccessLevel::Exported, - false => AccessLevel::Public, - }; let vis = match binding.vis { Visibility::Public => Visibility::Public, Visibility::Restricted(id) => Visibility::Restricted(id.expect_local()) }; self.update_effective_vis(def_id, vis, module_id, tag); - }; + } } } } - // fn init_crate_effective_vis(&mut self) { - - // } - fn update_effective_vis( &mut self, current_id: LocalDefId, @@ -117,20 +101,15 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { tag: AccessLevel, ) { if let Some(inherited_effective_vis) = self.r.access_levels.get_effective_vis(module_id) { - println!("tag: {:?}", tag); - println!("inherited effective vis: {:?}", inherited_effective_vis); let mut current_effective_vis = self.r.access_levels.get_effective_vis(current_id).copied().unwrap_or_default(); let nearest_available_vis = inherited_effective_vis.nearest_available(tag).unwrap(); - println!("nearest available vis: {:?}", nearest_available_vis); let calculated_effective_vis = match current_vis { Visibility::Public => nearest_available_vis, Visibility::Restricted(_) => { if current_vis.is_at_least(nearest_available_vis, &*self.r) {nearest_available_vis} else {current_vis} } }; - println!("calculated effective vis: {:?}", calculated_effective_vis); current_effective_vis.update(calculated_effective_vis, tag, &*self.r); - println!("updated effective vis: {:?}", current_effective_vis); self.r.access_levels.set_effective_vis(current_id, current_effective_vis); } } From 35c33ca772eb7e5b692b693184819beac91e54ce Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 15:57:48 +0300 Subject: [PATCH 3/8] access_levels -> effective vis in access_levels.rs::visit_item --- compiler/rustc_resolve/src/access_levels.rs | 29 ++++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index 6f478150d68bf..a7629b988fe0e 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -12,7 +12,6 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::CRATE_DEF_ID; use rustc_middle::middle::privacy::AccessLevel; use rustc_middle::ty::{DefIdTree, Visibility}; -use rustc_span::sym; pub struct AccessLevelsVisitor<'r, 'a> { r: &'r mut Resolver<'a>, @@ -156,16 +155,15 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> { // Foreign modules inherit level from parents. ast::ItemKind::ForeignMod(..) => { - let parent_level = - self.r.access_levels.get_access_level(self.r.local_parent(def_id)); - self.set_access_level(item.id, parent_level); + let parent_id = self.r.local_parent(def_id); + self.update_effective_vis(def_id, Visibility::Public, parent_id, AccessLevel::Public); } // Only exported `macro_rules!` items are public, but they always are ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => { - if item.attrs.iter().any(|attr| attr.has_name(sym::macro_export)) { - self.set_access_level(item.id, Some(AccessLevel::Public)); - } + let parent_id = self.r.local_parent(def_id); + let vis = self.r.visibilities.get(&def_id).unwrap().clone(); + self.update_effective_vis(def_id, vis, parent_id, AccessLevel::Public); } ast::ItemKind::Mod(..) => { @@ -177,19 +175,24 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> { self.set_bindings_access_level(def_id); for variant in variants { let variant_def_id = self.r.local_def_id(variant.id); - let variant_level = self.r.access_levels.get_access_level(variant_def_id); for field in variant.data.fields() { - self.set_access_level(field.id, variant_level); + let field_def_id = self.r.local_def_id(field.id); + let vis = self.r.visibilities.get(&field_def_id).unwrap().clone(); + self.update_effective_vis( + field_def_id, + vis, + variant_def_id, + AccessLevel::Public, + ); } } } ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { - let inherited_level = self.r.access_levels.get_access_level(def_id); for field in def.fields() { - if field.vis.kind.is_pub() { - self.set_access_level(field.id, inherited_level); - } + let field_def_id = self.r.local_def_id(field.id); + let vis = self.r.visibilities.get(&field_def_id).unwrap(); + self.update_effective_vis(field_def_id, *vis, def_id, AccessLevel::Public); } } From 2f81511751e114c7f40faad4c9a63bd797d1db84 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 16:04:02 +0300 Subject: [PATCH 4/8] start tracking changed flag --- compiler/rustc_resolve/src/access_levels.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index a7629b988fe0e..c6ef08f176b1f 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -108,8 +108,13 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { if current_vis.is_at_least(nearest_available_vis, &*self.r) {nearest_available_vis} else {current_vis} } }; + let current_effective_vis_copy = current_effective_vis.clone(); current_effective_vis.update(calculated_effective_vis, tag, &*self.r); - self.r.access_levels.set_effective_vis(current_id, current_effective_vis); + + if current_effective_vis_copy != current_effective_vis { + self.changed = true; + self.r.access_levels.set_effective_vis(current_id, current_effective_vis); + } } } From 5fe5036667e8ad8a93b6e153fddc4b266cd50c63 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 16:31:11 +0300 Subject: [PATCH 5/8] fix update func --- compiler/rustc_resolve/src/access_levels.rs | 27 +++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index c6ef08f176b1f..63128f2c30620 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -69,7 +69,6 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { let resolutions = self.r.resolutions(module); for (.., name_resolution) in resolutions.borrow().iter() { - if let Some(binding) = name_resolution.borrow().binding() { let tag = match binding.is_import() { true => { @@ -101,16 +100,24 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { ) { if let Some(inherited_effective_vis) = self.r.access_levels.get_effective_vis(module_id) { let mut current_effective_vis = self.r.access_levels.get_effective_vis(current_id).copied().unwrap_or_default(); - let nearest_available_vis = inherited_effective_vis.nearest_available(tag).unwrap(); - let calculated_effective_vis = match current_vis { - Visibility::Public => nearest_available_vis, - Visibility::Restricted(_) => { - if current_vis.is_at_least(nearest_available_vis, &*self.r) {nearest_available_vis} else {current_vis} - } - }; let current_effective_vis_copy = current_effective_vis.clone(); - current_effective_vis.update(calculated_effective_vis, tag, &*self.r); - + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + if level <= tag { + let nearest_available_vis = inherited_effective_vis.nearest_available(level).unwrap(); + let calculated_effective_vis = match current_vis { + Visibility::Public => nearest_available_vis, + Visibility::Restricted(_) => { + if current_vis.is_at_least(nearest_available_vis, &*self.r) {nearest_available_vis} else {current_vis} + } + }; + current_effective_vis.update(calculated_effective_vis, level, &*self.r); + } + } if current_effective_vis_copy != current_effective_vis { self.changed = true; self.r.access_levels.set_effective_vis(current_id, current_effective_vis); From b0551a4be2d4837d651e2214237802a9fbb73547 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 17:05:57 +0300 Subject: [PATCH 6/8] fix glob-shadowing.rs fail --- compiler/rustc_resolve/src/access_levels.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index 63128f2c30620..5124fb5c4c632 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -80,7 +80,7 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { false => AccessLevel::Public }; - if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { + if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) && !binding.is_ambiguity(){ let vis = match binding.vis { Visibility::Public => Visibility::Public, Visibility::Restricted(id) => Visibility::Restricted(id.expect_local()) From a9e21a3c7827f2a49b9bd2179b0f4a3b4d0ed4c8 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 19:48:09 +0300 Subject: [PATCH 7/8] update tests --- compiler/rustc_resolve/src/access_levels.rs | 47 +++++++++++---------- src/test/ui/privacy/access_levels.rs | 34 +++++++-------- src/test/ui/privacy/access_levels.stderr | 32 +++++++------- 3 files changed, 57 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index 5124fb5c4c632..de90c7a5e809a 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -7,7 +7,6 @@ use rustc_ast::visit; use rustc_ast::visit::Visitor; use rustc_ast::Crate; use rustc_ast::EnumDef; -use rustc_ast::NodeId; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::CRATE_DEF_ID; use rustc_middle::middle::privacy::AccessLevel; @@ -45,35 +44,47 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { /// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level). fn set_bindings_access_level(&mut self, module_id: LocalDefId) { assert!(self.r.module_map.contains_key(&&module_id.to_def_id())); - let module_level = self.r.access_levels.get_access_level(module_id); + // Set the given binding access level to `AccessLevel::Public` and // sets the rest of the `use` chain to `AccessLevel::Exported` until // we hit the actual exported item. let set_import_binding_access_level = - |this: &mut Self, mut binding: &NameBinding<'a>, mut access_level| { + |this: &mut Self, mut binding: &NameBinding<'a>, mut parent_id| { while let NameBindingKind::Import { binding: nested_binding, import, .. } = binding.kind { - this.set_access_level(import.id, access_level); - if let ImportKind::Single { additional_ids, .. } = import.kind { - this.set_access_level(additional_ids.0, access_level); - this.set_access_level(additional_ids.1, access_level); - } + if this.r.opt_local_def_id(import.id).is_some() { + let vis = match binding.vis { + Visibility::Public => Visibility::Public, + Visibility::Restricted(id) => Visibility::Restricted(id.expect_local()) + }; + this.update_effective_vis(this.r.local_def_id(import.id), vis, parent_id, AccessLevel::Exported); + if let ImportKind::Single { additional_ids, .. } = import.kind { + + if let Some(id) = this.r.opt_local_def_id(additional_ids.0) { + this.update_effective_vis(id, vis, parent_id, AccessLevel::Exported); + } + + if let Some(id) = this.r.opt_local_def_id(additional_ids.1) { + this.update_effective_vis(id, vis, parent_id, AccessLevel::Exported); + } + } - access_level = Some(AccessLevel::Exported); + parent_id = this.r.local_def_id(import.id); + } binding = nested_binding; } }; - let module = self.r.get_module(module_id.to_def_id()).unwrap(); - let resolutions = self.r.resolutions(module); + let module = self.r.get_module(module_id.to_def_id()).unwrap(); + let resolutions = self.r.resolutions(module); for (.., name_resolution) in resolutions.borrow().iter() { if let Some(binding) = name_resolution.borrow().binding() { let tag = match binding.is_import() { true => { - if binding.vis.is_public() && !binding.is_ambiguity() && module_level.is_some() { - set_import_binding_access_level(self, binding, module_level); + if !binding.is_ambiguity() { + set_import_binding_access_level(self, binding, module_id); } AccessLevel::Exported }, @@ -125,16 +136,6 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { } } - /// Sets the access level of the `LocalDefId` corresponding to the given `NodeId`. - /// This function will panic if the `NodeId` does not have a `LocalDefId` - fn set_access_level( - &mut self, - node_id: NodeId, - access_level: Option, - ) -> Option { - self.set_access_level_def_id(self.r.local_def_id(node_id), access_level) - } - fn set_access_level_def_id( &mut self, def_id: LocalDefId, diff --git a/src/test/ui/privacy/access_levels.rs b/src/test/ui/privacy/access_levels.rs index aa718ab9254df..b9ed923380890 100644 --- a/src/test/ui/privacy/access_levels.rs +++ b/src/test/ui/privacy/access_levels.rs @@ -1,57 +1,57 @@ #![feature(rustc_attrs)] #[rustc_effective_visibility] -mod outer { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) +mod outer { //~ ERROR Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub(access_levels), ReachableFromImplTrait: pub(access_levels) #[rustc_effective_visibility] - pub mod inner1 { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + pub mod inner1 { //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - extern "C" {} //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + extern "C" {} //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - pub trait PubTrait { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + pub trait PubTrait { //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - const A: i32; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + const A: i32; //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - type B; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + type B; //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub } #[rustc_effective_visibility] - struct PrivStruct; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + struct PrivStruct; //~ ERROR Public: pub(inner1), Exported: pub(inner1), Reachable: pub(inner1), ReachableFromImplTrait: pub(inner1) #[rustc_effective_visibility] - pub union PubUnion { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + pub union PubUnion { //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + a: u8, //~ ERROR Public: pub(inner1), Exported: pub(inner1), Reachable: pub(inner1), ReachableFromImplTrait: pub(inner1) #[rustc_effective_visibility] - pub b: u8, //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + pub b: u8, //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub } #[rustc_effective_visibility] - pub enum Enum { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + pub enum Enum { //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - A( //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + A( //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - PubUnion, //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + PubUnion, //~ ERROR Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub ), } } #[rustc_effective_visibility] - macro_rules! none_macro { //~ Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + macro_rules! none_macro { //~ Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub(access_levels), ReachableFromImplTrait: pub(access_levels) () => {}; } #[macro_export] #[rustc_effective_visibility] - macro_rules! public_macro { //~ Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + macro_rules! public_macro { //~ Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub () => {}; } #[rustc_effective_visibility] - pub struct ReachableStruct { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub + pub struct ReachableStruct { //~ ERROR Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub, ReachableFromImplTrait: pub #[rustc_effective_visibility] - pub a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub + pub a: u8, //~ ERROR Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub, ReachableFromImplTrait: pub } } diff --git a/src/test/ui/privacy/access_levels.stderr b/src/test/ui/privacy/access_levels.stderr index 2ed6c330a2f97..fae7d55ae1c00 100644 --- a/src/test/ui/privacy/access_levels.stderr +++ b/src/test/ui/privacy/access_levels.stderr @@ -1,70 +1,70 @@ -error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) +error: Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub(access_levels), ReachableFromImplTrait: pub(access_levels) --> $DIR/access_levels.rs:4:1 | LL | mod outer { | ^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:6:5 | LL | pub mod inner1 { | ^^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:9:9 | LL | extern "C" {} | ^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:12:9 | LL | pub trait PubTrait { | ^^^^^^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) +error: Public: pub(inner1), Exported: pub(inner1), Reachable: pub(inner1), ReachableFromImplTrait: pub(inner1) --> $DIR/access_levels.rs:20:9 | LL | struct PrivStruct; | ^^^^^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:23:9 | LL | pub union PubUnion { | ^^^^^^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) +error: Public: pub(inner1), Exported: pub(inner1), Reachable: pub(inner1), ReachableFromImplTrait: pub(inner1) --> $DIR/access_levels.rs:25:13 | LL | a: u8, | ^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:27:13 | LL | pub b: u8, | ^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:31:9 | LL | pub enum Enum { | ^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:33:13 | LL | A( | ^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:35:17 | LL | PubUnion, | ^^^^^^^^ -error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) +error: Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub(access_levels), ReachableFromImplTrait: pub(access_levels) --> $DIR/access_levels.rs:41:5 | LL | macro_rules! none_macro { @@ -76,25 +76,25 @@ error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub LL | macro_rules! public_macro { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:52:5 | LL | pub struct ReachableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub(access_levels), Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:54:9 | LL | pub a: u8, | ^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:14:13 | LL | const A: i32; | ^^^^^^^^^^^^ -error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub +error: Public: pub(access_levels), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:16:13 | LL | type B; From 0d2e73a824385f87926ea1669d958831da3bf685 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 19 Sep 2022 19:48:34 +0300 Subject: [PATCH 8/8] fmt --- compiler/rustc_middle/src/middle/privacy.rs | 9 +++- compiler/rustc_resolve/src/access_levels.rs | 51 +++++++++++++++------ 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index cfcef810daaea..44cbc20970e1c 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -1,7 +1,7 @@ //! A pass that checks to make sure private fields and methods aren't used //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. -use crate::ty::{Visibility, DefIdTree}; +use crate::ty::{DefIdTree, Visibility}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; @@ -60,7 +60,12 @@ impl EffectiveVisibility { } pub fn nearest_available(&self, tag: AccessLevel) -> Option { - for level in [AccessLevel::ReachableFromImplTrait, AccessLevel::Reachable, AccessLevel::Exported, AccessLevel::Public] { + for level in [ + AccessLevel::ReachableFromImplTrait, + AccessLevel::Reachable, + AccessLevel::Exported, + AccessLevel::Public, + ] { if (level <= tag) && self.get(tag).is_some() { return self.get(tag).cloned(); } diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index de90c7a5e809a..43e115b5c5285 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -56,17 +56,31 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { if this.r.opt_local_def_id(import.id).is_some() { let vis = match binding.vis { Visibility::Public => Visibility::Public, - Visibility::Restricted(id) => Visibility::Restricted(id.expect_local()) + Visibility::Restricted(id) => Visibility::Restricted(id.expect_local()), }; - this.update_effective_vis(this.r.local_def_id(import.id), vis, parent_id, AccessLevel::Exported); + this.update_effective_vis( + this.r.local_def_id(import.id), + vis, + parent_id, + AccessLevel::Exported, + ); if let ImportKind::Single { additional_ids, .. } = import.kind { - if let Some(id) = this.r.opt_local_def_id(additional_ids.0) { - this.update_effective_vis(id, vis, parent_id, AccessLevel::Exported); + this.update_effective_vis( + id, + vis, + parent_id, + AccessLevel::Exported, + ); } if let Some(id) = this.r.opt_local_def_id(additional_ids.1) { - this.update_effective_vis(id, vis, parent_id, AccessLevel::Exported); + this.update_effective_vis( + id, + vis, + parent_id, + AccessLevel::Exported, + ); } } @@ -76,8 +90,8 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { } }; - let module = self.r.get_module(module_id.to_def_id()).unwrap(); - let resolutions = self.r.resolutions(module); + let module = self.r.get_module(module_id.to_def_id()).unwrap(); + let resolutions = self.r.resolutions(module); for (.., name_resolution) in resolutions.borrow().iter() { if let Some(binding) = name_resolution.borrow().binding() { @@ -87,8 +101,8 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { set_import_binding_access_level(self, binding, module_id); } AccessLevel::Exported - }, - false => AccessLevel::Public + } + false => AccessLevel::Public, }; if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) && !binding.is_ambiguity(){ @@ -110,7 +124,8 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { tag: AccessLevel, ) { if let Some(inherited_effective_vis) = self.r.access_levels.get_effective_vis(module_id) { - let mut current_effective_vis = self.r.access_levels.get_effective_vis(current_id).copied().unwrap_or_default(); + let mut current_effective_vis = + self.r.access_levels.get_effective_vis(current_id).copied().unwrap_or_default(); let current_effective_vis_copy = current_effective_vis.clone(); for level in [ AccessLevel::Public, @@ -119,11 +134,16 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { AccessLevel::ReachableFromImplTrait, ] { if level <= tag { - let nearest_available_vis = inherited_effective_vis.nearest_available(level).unwrap(); + let nearest_available_vis = + inherited_effective_vis.nearest_available(level).unwrap(); let calculated_effective_vis = match current_vis { Visibility::Public => nearest_available_vis, Visibility::Restricted(_) => { - if current_vis.is_at_least(nearest_available_vis, &*self.r) {nearest_available_vis} else {current_vis} + if current_vis.is_at_least(nearest_available_vis, &*self.r) { + nearest_available_vis + } else { + current_vis + } } }; current_effective_vis.update(calculated_effective_vis, level, &*self.r); @@ -169,7 +189,12 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> { // Foreign modules inherit level from parents. ast::ItemKind::ForeignMod(..) => { let parent_id = self.r.local_parent(def_id); - self.update_effective_vis(def_id, Visibility::Public, parent_id, AccessLevel::Public); + self.update_effective_vis( + def_id, + Visibility::Public, + parent_id, + AccessLevel::Public, + ); } // Only exported `macro_rules!` items are public, but they always are