diff options
| author | bors <bors@rust-lang.org> | 2022-09-17 22:04:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-09-17 22:04:28 +0000 |
| commit | 5253b0a0a1f366fad0ebed57597fcf2703b9e893 (patch) | |
| tree | 8111bda03a6a21e62ba5c5ae16ac54619f21cbd1 /compiler | |
| parent | 98ad6a5519651af36e246c0335c964dd52c554ba (diff) | |
| parent | 5ba52ca002bd1ee2d7f9fe1969c21e8faaf9edac (diff) | |
| download | rust-5253b0a0a1f366fad0ebed57597fcf2703b9e893.tar.gz rust-5253b0a0a1f366fad0ebed57597fcf2703b9e893.zip | |
Auto merge of #101949 - matthiaskrgr:rollup-xu5cqnd, r=matthiaskrgr
Rollup of 7 pull requests
Successful merges:
- #101093 (Initial version of 1.64 release notes)
- #101713 (change AccessLevels representation)
- #101821 (Bump Unicode to version 15.0.0, regenerate tables)
- #101826 (Enforce "joined()" and "joined_with_noop()" test)
- #101835 (Allow using vendoring when running bootstrap from outside the source root)
- #101942 (Revert "Copy stage0 binaries into stage0-sysroot")
- #101943 (rustdoc: remove unused CSS `.non-exhaustive { margin-bottom }`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_error_messages/locales/en-US/privacy.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/builtin_attrs.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/privacy.rs | 93 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/reachable.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_privacy/src/errors.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_privacy/src/lib.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/access_levels.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 2 |
9 files changed, 139 insertions, 34 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_error_messages/locales/en-US/privacy.ftl index da987152ff6..a26d1b2b381 100644 --- a/compiler/rustc_error_messages/locales/en-US/privacy.ftl +++ b/compiler/rustc_error_messages/locales/en-US/privacy.ftl @@ -11,7 +11,7 @@ privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interfac .label = can't leak {$vis_descr} {$kind} .visibility_label = `{$descr}` declared as {$vis_descr} -privacy_report_access_level = {$descr} +privacy_report_effective_visibility = {$descr} privacy_from_private_dep_in_public_interface = {$kind} `{$descr}` from private dependency '{$krate}' in public interface diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index b50c972e6f6..0f6d7ed9edc 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -762,7 +762,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Internal attributes, Testing: // ========================================================================== - rustc_attr!(TEST, rustc_access_level, Normal, template!(Word), WarnFollowing), + rustc_attr!(TEST, rustc_effective_visibility, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_outlives, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing), diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 751c7f46482..c595fbec0dd 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 rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; @@ -27,26 +27,107 @@ pub enum AccessLevel { Public, } +#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Default)] +pub struct EffectiveVisibility { + public: Option<Visibility>, + exported: Option<Visibility>, + reachable: Option<Visibility>, + reachable_from_impl_trait: Option<Visibility>, +} + +impl EffectiveVisibility { + pub fn get(&self, tag: AccessLevel) -> Option<&Visibility> { + match tag { + AccessLevel::Public => &self.public, + AccessLevel::Exported => &self.exported, + AccessLevel::Reachable => &self.reachable, + AccessLevel::ReachableFromImplTrait => &self.reachable_from_impl_trait, + } + .as_ref() + } + + fn get_mut(&mut self, tag: AccessLevel) -> &mut Option<Visibility> { + match tag { + AccessLevel::Public => &mut self.public, + AccessLevel::Exported => &mut self.exported, + AccessLevel::Reachable => &mut self.reachable, + AccessLevel::ReachableFromImplTrait => &mut self.reachable_from_impl_trait, + } + } + + pub fn is_public_at_level(&self, tag: AccessLevel) -> bool { + self.get(tag).map_or(false, |vis| vis.is_public()) + } +} + /// Holds a map of accessibility levels for reachable HIR nodes. #[derive(Debug, Clone)] pub struct AccessLevels<Id = LocalDefId> { - pub map: FxHashMap<Id, AccessLevel>, + map: FxHashMap<Id, EffectiveVisibility>, } -impl<Id: Hash + Eq> AccessLevels<Id> { +impl<Id: Hash + Eq + Copy> AccessLevels<Id> { + pub fn is_public_at_level(&self, id: Id, tag: AccessLevel) -> bool { + self.get_effective_vis(id) + .map_or(false, |effective_vis| effective_vis.is_public_at_level(tag)) + } + /// See `AccessLevel::Reachable`. pub fn is_reachable(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Reachable) + self.is_public_at_level(id, AccessLevel::Reachable) } /// See `AccessLevel::Exported`. pub fn is_exported(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Exported) + self.is_public_at_level(id, AccessLevel::Exported) } /// See `AccessLevel::Public`. pub fn is_public(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Public) + self.is_public_at_level(id, AccessLevel::Public) + } + + pub fn get_access_level(&self, id: Id) -> Option<AccessLevel> { + self.get_effective_vis(id).and_then(|effective_vis| { + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + if effective_vis.is_public_at_level(level) { + return Some(level); + } + } + None + }) + } + + pub fn set_access_level(&mut self, id: Id, tag: AccessLevel) { + let mut effective_vis = self.get_effective_vis(id).copied().unwrap_or_default(); + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + if level <= tag { + *effective_vis.get_mut(level) = Some(Visibility::Public); + } + } + self.map.insert(id, effective_vis); + } + + pub fn get_effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> { + self.map.get(&id) + } + + pub fn iter(&self) -> impl Iterator<Item = (&Id, &EffectiveVisibility)> { + self.map.iter() + } + + pub fn map_id<OutId: Hash + Eq + Copy>(&self, f: impl Fn(Id) -> OutId) -> AccessLevels<OutId> { + AccessLevels { map: self.map.iter().map(|(k, v)| (f(*k), *v)).collect() } } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index f141d7beeb9..57f7c379d04 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Node, PatKind, TyKind}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::middle::privacy; +use rustc_middle::middle::privacy::AccessLevel; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::lint; @@ -619,13 +619,10 @@ fn create_and_seed_worklist<'tcx>( // see `MarkSymbolVisitor::struct_constructors` let mut struct_constructors = Default::default(); let mut worklist = access_levels - .map .iter() - .filter_map( - |(&id, &level)| { - if level >= privacy::AccessLevel::Reachable { Some(id) } else { None } - }, - ) + .filter_map(|(&id, effective_vis)| { + effective_vis.is_public_at_level(AccessLevel::Reachable).then_some(id) + }) // Seed entry point .chain(tcx.entry_fn(()).and_then(|(def_id, _)| def_id.as_local())) .collect::<Vec<_>>(); diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index f7e3fac6b2e..75244124e20 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; -use rustc_middle::middle::privacy; +use rustc_middle::middle::privacy::{self, AccessLevel}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::config::CrateType; @@ -373,7 +373,13 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> { // If other crates link to us, they're going to expect to be able to // use the lang items, so we need to be sure to mark them as // exported. - reachable_context.worklist.extend(access_levels.map.keys()); + reachable_context.worklist = access_levels + .iter() + .filter_map(|(&id, effective_vis)| { + effective_vis.is_public_at_level(AccessLevel::ReachableFromImplTrait).then_some(id) + }) + .collect::<Vec<_>>(); + for item in tcx.lang_items().items().iter() { if let Some(def_id) = *item { if let Some(def_id) = def_id.as_local() { diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 63f83f8965e..705ad567aa7 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -76,8 +76,8 @@ pub struct InPublicInterface<'a> { } #[derive(SessionDiagnostic)] -#[diag(privacy::report_access_level)] -pub struct ReportAccessLevel { +#[diag(privacy::report_effective_visibility)] +pub struct ReportEffectiveVisibility { #[primary_span] pub span: Span, pub descr: String, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 48ab31ab92d..8f5ee51e6cf 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -42,7 +42,7 @@ use std::{cmp, fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, - InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportAccessLevel, + InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportEffectiveVisibility, UnnamedItemIsPrivate, }; @@ -376,7 +376,7 @@ impl VisibilityLike for Option<AccessLevel> { // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { - cmp::min(find.access_levels.map.get(&def_id).copied(), find.min) + cmp::min(find.access_levels.get_access_level(def_id), find.min) } } @@ -416,7 +416,7 @@ struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> { impl<'tcx> EmbargoVisitor<'tcx> { fn get(&self, def_id: LocalDefId) -> Option<AccessLevel> { - self.access_levels.map.get(&def_id).copied() + self.access_levels.get_access_level(def_id) } fn update_with_hir_id( @@ -433,7 +433,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { let old_level = self.get(def_id); // Accessibility levels can only grow. if level > old_level { - self.access_levels.map.insert(def_id, level.unwrap()); + self.access_levels.set_access_level(def_id, level.unwrap()); self.changed = true; level } else { @@ -914,10 +914,31 @@ pub struct TestReachabilityVisitor<'tcx, 'a> { impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { fn access_level_diagnostic(&mut self, def_id: LocalDefId) { - if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_access_level) { - let access_level = format!("{:?}", self.access_levels.map.get(&def_id)); - let span = self.tcx.def_span(def_id.to_def_id()); - self.tcx.sess.emit_err(ReportAccessLevel { span, descr: access_level }); + let span = self.tcx.def_span(def_id.to_def_id()); + if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) { + let mut error_msg = String::new(); + + let effective_vis = + self.access_levels.get_effective_vis(def_id).copied().unwrap_or_default(); + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + let vis_str = match effective_vis.get(level) { + Some(ty::Visibility::Restricted(restricted_id)) => { + format!("pub({})", self.tcx.item_name(restricted_id.to_def_id())) + } + Some(ty::Visibility::Public) => "pub".to_string(), + None => "pub(self)".to_string(), + }; + if level != AccessLevel::Public { + error_msg.push_str(", "); + } + error_msg.push_str(&format!("{:?}: {}", level, vis_str)); + } + self.tcx.sess.emit_err(ReportEffectiveVisibility { span, descr: error_msg }); } } } diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index 0a3add2e0f5..9b1111c02c7 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -46,7 +46,7 @@ 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.map.get(&module_id).copied(); + let module_level = self.r.access_levels.get_access_level(module_id); if !module_level.is_some() { return; } @@ -103,9 +103,9 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { def_id: LocalDefId, access_level: Option<AccessLevel>, ) -> Option<AccessLevel> { - let old_level = self.r.access_levels.map.get(&def_id).copied(); + let old_level = self.r.access_levels.get_access_level(def_id); if old_level < access_level { - self.r.access_levels.map.insert(def_id, access_level.unwrap()); + self.r.access_levels.set_access_level(def_id, access_level.unwrap()); self.changed = true; access_level } else { @@ -131,7 +131,7 @@ 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.map.get(&self.r.local_parent(def_id)).copied(); + self.r.access_levels.get_access_level(self.r.local_parent(def_id)); self.set_access_level(item.id, parent_level); } @@ -151,7 +151,7 @@ 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.map.get(&variant_def_id).copied(); + 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); } @@ -159,7 +159,7 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> { } ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { - let inherited_level = self.r.access_levels.map.get(&def_id).copied(); + 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); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ae4d1a4635b..562360130e9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1214,7 +1214,6 @@ symbols! { rust_eh_unregister_frames, rust_oom, rustc, - rustc_access_level, rustc_allocator, rustc_allocator_nounwind, rustc_allocator_zeroed, @@ -1242,6 +1241,7 @@ symbols! { rustc_dump_program_clauses, rustc_dump_user_substs, rustc_dump_vtable, + rustc_effective_visibility, rustc_error, rustc_evaluate_where_clauses, rustc_expected_cgu_reuse, |
