summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/middle
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:11:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:13:23 +0000
commit20431706a863f92cb37dc512fef6e48d192aaf2c (patch)
tree2867f13f5fd5437ba628c67d7f87309ccadcd286 /compiler/rustc_middle/src/middle
parentReleasing progress-linux version 1.65.0+dfsg1-2~progress7.99u1. (diff)
downloadrustc-20431706a863f92cb37dc512fef6e48d192aaf2c.tar.xz
rustc-20431706a863f92cb37dc512fef6e48d192aaf2c.zip
Merging upstream version 1.66.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_middle/src/middle')
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs2
-rw-r--r--compiler/rustc_middle/src/middle/privacy.rs214
-rw-r--r--compiler/rustc_middle/src/middle/resolve_lifetime.rs15
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs11
4 files changed, 194 insertions, 48 deletions
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<Id = LocalDefId> {
- pub map: FxHashMap<Id, AccessLevel>,
+pub struct EffectiveVisibilities<Id = LocalDefId> {
+ map: FxHashMap<Id, EffectiveVisibility>,
}
-impl<Id: Hash + Eq> AccessLevels<Id> {
- /// See `AccessLevel::Reachable`.
+impl<Id: Hash + Eq + Copy> EffectiveVisibilities<Id> {
+ 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<Level> {
+ 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<Item = (&Id, &EffectiveVisibility)> {
+ self.map.iter()
+ }
+
+ pub fn map_id<OutId: Hash + Eq + Copy>(
+ &self,
+ f: impl Fn(Id) -> OutId,
+ ) -> EffectiveVisibilities<OutId> {
+ 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<Id: Hash + Eq + Copy + Into<DefId>> EffectiveVisibilities<Id> {
+ // `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<Id> Default for AccessLevels<Id> {
+impl<Id> Default for EffectiveVisibilities<Id> {
fn default() -> Self {
- AccessLevels { map: Default::default() }
+ EffectiveVisibilities { map: Default::default() }
}
}
-impl<'a> HashStable<StableHashingContext<'a>> for AccessLevels {
+impl<'a> HashStable<StableHashingContext<'a>> 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<LocalDefId, FxHashMap<ItemLocalId, Region>>,
+ pub defs: FxHashMap<OwnerId, FxHashMap<ItemLocalId, Region>>,
- /// 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<LocalDefId, FxHashSet<LocalDefId>>,
-
- pub late_bound_vars: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
+ pub late_bound_vars: FxHashMap<OwnerId, FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
}
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);