From 20431706a863f92cb37dc512fef6e48d192aaf2c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/middle/limits.rs | 2 +- compiler/rustc_middle/src/middle/privacy.rs | 214 ++++++++++++++++++--- .../rustc_middle/src/middle/resolve_lifetime.rs | 15 +- compiler/rustc_middle/src/middle/stability.rs | 11 +- 4 files changed, 194 insertions(+), 48 deletions(-) (limited to 'compiler/rustc_middle/src/middle') diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 53c4d9267..12aef66bc 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -38,7 +38,7 @@ pub fn provide(providers: &mut ty::query::Providers) { tcx.hir().krate_attrs(), tcx.sess, sym::const_eval_limit, - 1_000_000, + 2_000_000, ), } } diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 751c7f464..9c68c7504 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -1,64 +1,218 @@ //! 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::{DefIdTree, Visibility}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; -use rustc_span::def_id::LocalDefId; +use rustc_span::def_id::{DefId, LocalDefId}; use std::hash::Hash; -/// Represents the levels of accessibility an item can have. +/// Represents the levels of effective visibility an item can have. /// -/// The variants are sorted in ascending order of accessibility. +/// The variants are sorted in ascending order of directness. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, HashStable)] -pub enum AccessLevel { - /// Superset of `AccessLevel::Reachable` used to mark impl Trait items. - ReachableFromImplTrait, - /// Exported items + items participating in various kinds of public interfaces, - /// but not directly nameable. For example, if function `fn f() -> T {...}` is - /// public, then type `T` is reachable. Its values can be obtained by other crates - /// even if the type itself is not nameable. +pub enum Level { + /// Superset of `Reachable` including items leaked through return position `impl Trait`. + ReachableThroughImplTrait, + /// Item is either reexported, or leaked through any kind of interface. + /// For example, if function `fn f() -> T {...}` is directly public, then type `T` is publicly + /// reachable and its values can be obtained by other crates even if the type itself is not + /// nameable. Reachable, - /// Public items + items accessible to other crates with the help of `pub use` re-exports. - Exported, - /// Items accessible to other crates directly, without the help of re-exports. - Public, + /// Item is accessible either directly, or with help of `use` reexports. + Reexported, + /// Item is directly accessible, without help of reexports. + Direct, +} + +impl Level { + pub fn all_levels() -> [Level; 4] { + [Level::Direct, Level::Reexported, Level::Reachable, Level::ReachableThroughImplTrait] + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)] +pub struct EffectiveVisibility { + direct: Visibility, + reexported: Visibility, + reachable: Visibility, + reachable_through_impl_trait: Visibility, +} + +impl EffectiveVisibility { + pub fn at_level(&self, level: Level) -> &Visibility { + match level { + Level::Direct => &self.direct, + Level::Reexported => &self.reexported, + Level::Reachable => &self.reachable, + Level::ReachableThroughImplTrait => &self.reachable_through_impl_trait, + } + } + + fn at_level_mut(&mut self, level: Level) -> &mut Visibility { + match level { + Level::Direct => &mut self.direct, + Level::Reexported => &mut self.reexported, + Level::Reachable => &mut self.reachable, + Level::ReachableThroughImplTrait => &mut self.reachable_through_impl_trait, + } + } + + pub fn is_public_at_level(&self, level: Level) -> bool { + self.at_level(level).is_public() + } + + pub fn from_vis(vis: Visibility) -> EffectiveVisibility { + EffectiveVisibility { + direct: vis, + reexported: vis, + reachable: vis, + reachable_through_impl_trait: vis, + } + } } -/// Holds a map of accessibility levels for reachable HIR nodes. +/// Holds a map of effective visibilities for reachable HIR nodes. #[derive(Debug, Clone)] -pub struct AccessLevels { - pub map: FxHashMap, +pub struct EffectiveVisibilities { + map: FxHashMap, } -impl AccessLevels { - /// See `AccessLevel::Reachable`. +impl EffectiveVisibilities { + pub fn is_public_at_level(&self, id: Id, level: Level) -> bool { + self.effective_vis(id) + .map_or(false, |effective_vis| effective_vis.is_public_at_level(level)) + } + + /// See `Level::Reachable`. pub fn is_reachable(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Reachable) + self.is_public_at_level(id, Level::Reachable) } - /// See `AccessLevel::Exported`. + /// See `Level::Reexported`. pub fn is_exported(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Exported) + self.is_public_at_level(id, Level::Reexported) + } + + /// See `Level::Direct`. + pub fn is_directly_public(&self, id: Id) -> bool { + self.is_public_at_level(id, Level::Direct) + } + + pub fn public_at_level(&self, id: Id) -> Option { + self.effective_vis(id).and_then(|effective_vis| { + for level in Level::all_levels() { + if effective_vis.is_public_at_level(level) { + return Some(level); + } + } + None + }) + } + + pub fn effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> { + self.map.get(&id) } - /// See `AccessLevel::Public`. - pub fn is_public(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Public) + pub fn iter(&self) -> impl Iterator { + self.map.iter() + } + + pub fn map_id( + &self, + f: impl Fn(Id) -> OutId, + ) -> EffectiveVisibilities { + EffectiveVisibilities { map: self.map.iter().map(|(k, v)| (f(*k), *v)).collect() } + } + + pub fn set_public_at_level( + &mut self, + id: Id, + default_vis: impl FnOnce() -> Visibility, + level: Level, + ) { + let mut effective_vis = self + .effective_vis(id) + .copied() + .unwrap_or_else(|| EffectiveVisibility::from_vis(default_vis())); + for l in Level::all_levels() { + if l <= level { + *effective_vis.at_level_mut(l) = Visibility::Public; + } + } + self.map.insert(id, effective_vis); + } +} + +impl> EffectiveVisibilities { + // `parent_id` is not necessarily a parent in source code tree, + // it is the node from which the maximum effective visibility is inherited. + pub fn update( + &mut self, + id: Id, + nominal_vis: Visibility, + default_vis: impl FnOnce() -> Visibility, + parent_id: Id, + level: Level, + tree: impl DefIdTree, + ) -> bool { + let mut changed = false; + let mut current_effective_vis = self.effective_vis(id).copied().unwrap_or_else(|| { + if id.into().is_crate_root() { + EffectiveVisibility::from_vis(Visibility::Public) + } else { + EffectiveVisibility::from_vis(default_vis()) + } + }); + if let Some(inherited_effective_vis) = self.effective_vis(parent_id) { + let mut inherited_effective_vis_at_prev_level = + *inherited_effective_vis.at_level(level); + let mut calculated_effective_vis = inherited_effective_vis_at_prev_level; + for l in Level::all_levels() { + if level >= l { + let inherited_effective_vis_at_level = *inherited_effective_vis.at_level(l); + let current_effective_vis_at_level = current_effective_vis.at_level_mut(l); + // effective visibility for id shouldn't be recalculated if + // inherited from parent_id effective visibility isn't changed at next level + if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level + && level != l) + { + calculated_effective_vis = + if nominal_vis.is_at_least(inherited_effective_vis_at_level, tree) { + inherited_effective_vis_at_level + } else { + nominal_vis + }; + } + // effective visibility can't be decreased at next update call for the + // same id + if *current_effective_vis_at_level != calculated_effective_vis + && calculated_effective_vis + .is_at_least(*current_effective_vis_at_level, tree) + { + changed = true; + *current_effective_vis_at_level = calculated_effective_vis; + } + inherited_effective_vis_at_prev_level = inherited_effective_vis_at_level; + } + } + } + self.map.insert(id, current_effective_vis); + changed } } -impl Default for AccessLevels { +impl Default for EffectiveVisibilities { fn default() -> Self { - AccessLevels { map: Default::default() } + EffectiveVisibilities { map: Default::default() } } } -impl<'a> HashStable> for AccessLevels { +impl<'a> HashStable> for EffectiveVisibilities { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let AccessLevels { ref map } = *self; + let EffectiveVisibilities { ref map } = *self; map.hash_stable(hcx, hasher); } } diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index a171f5711..c3bf1c717 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -2,9 +2,9 @@ use crate::ty; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::ItemLocalId; +use rustc_data_structures::fx::FxHashMap; +use rustc_hir::def_id::DefId; +use rustc_hir::{ItemLocalId, OwnerId}; use rustc_macros::HashStable; #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)] @@ -49,12 +49,7 @@ pub enum ObjectLifetimeDefault { pub struct ResolveLifetimes { /// Maps from every use of a named (not anonymous) lifetime to a /// `Region` describing how that region is bound - pub defs: FxHashMap>, + pub defs: FxHashMap>, - /// Set of lifetime def ids that are late-bound; a region can - /// be late-bound if (a) it does NOT appear in a where-clause and - /// (b) it DOES appear in the arguments. - pub late_bound: FxHashMap>, - - pub late_bound_vars: FxHashMap>>, + pub late_bound_vars: FxHashMap>>, } diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index d182929c4..61bc089e4 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -253,13 +253,12 @@ fn late_report_deprecation( return; } let method_span = method_span.unwrap_or(span); - tcx.struct_span_lint_hir(lint, hir_id, method_span, |lint| { - let mut diag = lint.build(message); + tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| { if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { let kind = tcx.def_kind(def_id).descr(def_id); - deprecation_suggestion(&mut diag, kind, suggestion, method_span); + deprecation_suggestion(diag, kind, suggestion, method_span); } - diag.emit(); + diag }); } @@ -621,9 +620,7 @@ impl<'tcx> TyCtxt<'tcx> { unmarked: impl FnOnce(Span, DefId), ) -> bool { let soft_handler = |lint, span, msg: &_| { - self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { - lint.build(msg).emit(); - }) + self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |lint| lint) }; let eval_result = self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); -- cgit v1.2.3