diff options
Diffstat (limited to 'compiler/rustc_passes/src/stability.rs')
| -rw-r--r-- | compiler/rustc_passes/src/stability.rs | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index d92edf959af..8a4bdf3875c 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -6,8 +6,8 @@ use std::num::NonZero; use rustc_ast_lowering::stability::extern_abi_stability; use rustc_attr_parsing::{ - self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince, - UnstableReason, VERSION_PLACEHOLDER, + self as attr, AttributeKind, ConstStability, DeprecatedSince, PartialConstStability, Stability, + StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER, find_attr, }; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet}; @@ -121,7 +121,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs); - let depr = attr::find_deprecation(self.tcx.sess, self.tcx.features(), attrs); + let depr = attr::find_attr!(attrs, AttributeKind::Deprecation{deprecation, span} => (*deprecation, *span)); + let const_stability_indirect = find_attr!(attrs, AttributeKind::ConstStabilityIndirect); + let mut is_deprecated = false; if let Some((depr, span)) = &depr { is_deprecated = true; @@ -154,9 +156,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if inherit_deprecation.yes() && stab.is_unstable() { self.index.stab_map.insert(def_id, stab); if fn_sig.is_some_and(|s| s.header.is_const()) { - let const_stab = - attr::unmarked_crate_const_stab(self.tcx.sess, attrs, stab); - self.index.const_stab_map.insert(def_id, const_stab); + self.index.const_stab_map.insert( + def_id, + ConstStability::unmarked(const_stability_indirect, stab), + ); } } } @@ -171,9 +174,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } // # Regular and body stability - - let stab = attr::find_stability(self.tcx.sess, attrs, item_sp); - let body_stab = attr::find_body_stability(self.tcx.sess, attrs); + let stab = attr::find_attr!(attrs, AttributeKind::Stability { stability, span } => (*stability, *span)); + let body_stab = + attr::find_attr!(attrs, AttributeKind::BodyStability { stability, .. } => *stability); if let Some((depr, span)) = &depr && depr.is_since_rustc_version() @@ -182,7 +185,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { self.tcx.dcx().emit_err(errors::DeprecatedAttribute { span: *span }); } - if let Some((body_stab, _span)) = body_stab { + if let Some(body_stab) = body_stab { // FIXME: check that this item can have body stability self.index.default_body_stab_map.insert(def_id, body_stab); @@ -260,10 +263,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // # Const stability - let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item_sp); + let const_stab = attr::find_attr!(attrs, AttributeKind::ConstStability { stability, span } => (*stability, *span)); // If the current node is a function with const stability attributes (directly given or - // implied), check if the function/method is const. + // implied), check if the function/method is const or the parent impl block is const. if let Some(fn_sig) = fn_sig && !fn_sig.header.is_const() && const_stab.is_some() @@ -285,7 +288,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // Stable *language* features shouldn't be used as unstable library features. // (Not doing this for stable library features is checked by tidy.) if let Some(( - ConstStability { level: StabilityLevel::Unstable { .. }, feature, .. }, + PartialConstStability { level: StabilityLevel::Unstable { .. }, feature, .. }, const_span, )) = const_stab { @@ -297,9 +300,17 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } } + if let Some((stab, span)) = &const_stab + && stab.is_const_stable() + && const_stability_indirect + { + self.tcx.dcx().emit_err(errors::RustcConstStableIndirectPairing { span: *span }); + } + // After checking the immediate attributes, get rid of the span and compute implied // const stability: inherit feature gate from regular stability. - let mut const_stab = const_stab.map(|(stab, _span)| stab); + let mut const_stab = const_stab + .map(|(stab, _span)| ConstStability::from_partial(stab, const_stability_indirect)); // If this is a const fn but not annotated with stability markers, see if we can inherit regular stability. if fn_sig.is_some_and(|s| s.header.is_const()) && const_stab.is_none() && @@ -785,8 +796,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { let features = self.tcx.features(); if features.staged_api() { let attrs = self.tcx.hir().attrs(item.hir_id()); - let stab = attr::find_stability(self.tcx.sess, attrs, item.span); - let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item.span); + let stab = attr::find_attr!(attrs, AttributeKind::Stability{stability, span} => (*stability, *span)); + + // FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem + let const_stab = attr::find_attr!(attrs, AttributeKind::ConstStability{stability, ..} => *stability); // If this impl block has an #[unstable] attribute, give an // error if all involved types and traits are stable, because @@ -817,7 +830,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // needs to have an error emitted. if features.const_trait_impl() && self.tcx.is_const_trait_impl(item.owner_id.to_def_id()) - && const_stab.is_some_and(|(stab, _)| stab.is_const_stable()) + && const_stab.is_some_and(|stab| stab.is_const_stable()) { self.tcx.dcx().emit_err(errors::TraitImplConstStable { span: item.span }); } |
