From 2ff14448863ac1a1dd9533461708e29aae170c2d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:06:31 +0200 Subject: Adding debian version 1.65.0+dfsg1-2. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/middle/stability.rs | 77 ++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 8 deletions(-) (limited to 'compiler/rustc_middle/src/middle/stability.rs') diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 414912dd0..d182929c4 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -5,7 +5,7 @@ pub use self::StabilityLevel::*; use crate::ty::{self, DefIdTree, TyCtxt}; use rustc_ast::NodeId; -use rustc_attr::{self as attr, ConstStability, Deprecation, Stability}; +use rustc_attr::{self as attr, ConstStability, DefaultBodyStability, Deprecation, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, Diagnostic}; use rustc_feature::GateIssue; @@ -61,6 +61,7 @@ pub struct Index { /// are filled by the annotator. pub stab_map: FxHashMap, pub const_stab_map: FxHashMap, + pub default_body_stab_map: FxHashMap, pub depr_map: FxHashMap, /// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]` /// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute @@ -86,6 +87,10 @@ impl Index { self.const_stab_map.get(&def_id).copied() } + pub fn local_default_body_stability(&self, def_id: LocalDefId) -> Option { + self.default_body_stab_map.get(&def_id).copied() + } + pub fn local_deprecation_entry(&self, def_id: LocalDefId) -> Option { self.depr_map.get(&def_id).cloned() } @@ -288,7 +293,7 @@ fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // These are not visible outside crate; therefore // stability markers are irrelevant, if even present. - ty::Visibility::Restricted(..) | ty::Visibility::Invisible => true, + ty::Visibility::Restricted(..) => true, } } @@ -416,6 +421,12 @@ impl<'tcx> TyCtxt<'tcx> { return EvalResult::Allow; } + // Only the cross-crate scenario matters when checking unstable APIs + let cross_crate = !def_id.is_local(); + if !cross_crate { + return EvalResult::Allow; + } + let stability = self.lookup_stability(def_id); debug!( "stability: \ @@ -423,12 +434,6 @@ impl<'tcx> TyCtxt<'tcx> { def_id, span, stability ); - // Only the cross-crate scenario matters when checking unstable APIs - let cross_crate = !def_id.is_local(); - if !cross_crate { - return EvalResult::Allow; - } - // Issue #38412: private items lack stability markers. if skip_stability_check_due_to_privacy(self, def_id) { return EvalResult::Allow; @@ -492,6 +497,62 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Evaluates the default-impl stability of an item. + /// + /// Returns `EvalResult::Allow` if the item's default implementation is stable, or unstable but the corresponding + /// `#![feature]` has been provided. Returns `EvalResult::Deny` which describes the offending + /// unstable feature otherwise. + pub fn eval_default_body_stability(self, def_id: DefId, span: Span) -> EvalResult { + let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some(); + if !is_staged_api { + return EvalResult::Allow; + } + + // Only the cross-crate scenario matters when checking unstable APIs + let cross_crate = !def_id.is_local(); + if !cross_crate { + return EvalResult::Allow; + } + + let stability = self.lookup_default_body_stability(def_id); + debug!( + "body stability: inspecting def_id={def_id:?} span={span:?} of stability={stability:?}" + ); + + // Issue #38412: private items lack stability markers. + if skip_stability_check_due_to_privacy(self, def_id) { + return EvalResult::Allow; + } + + match stability { + Some(DefaultBodyStability { + level: attr::Unstable { reason, issue, is_soft, .. }, + feature, + }) => { + if span.allows_unstable(feature) { + debug!("body stability: skipping span={:?} since it is internal", span); + return EvalResult::Allow; + } + if self.features().active(feature) { + return EvalResult::Allow; + } + + EvalResult::Deny { + feature, + reason: reason.to_opt_reason(), + issue, + suggestion: None, + is_soft, + } + } + Some(_) => { + // Stable APIs are always ok to call + EvalResult::Allow + } + None => EvalResult::Unmarked, + } + } + /// Checks if an item is stable or error out. /// /// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not -- cgit v1.2.3