about summary refs log tree commit diff
path: root/compiler/rustc_middle
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-08 23:39:00 +0000
committerbors <bors@rust-lang.org>2024-09-08 23:39:00 +0000
commit085744b7ad8b227239bcee0a44cd78dcd0310ab9 (patch)
treed8aaf9848ccd82688d09a137d9df19fe8c034bb1 /compiler/rustc_middle
parentadf8d168af9334a8bf940824fcf4207d01e05ae5 (diff)
parent7c9e818f028a899cf4597f80c67bfe64b7e1a4ed (diff)
downloadrust-085744b7ad8b227239bcee0a44cd78dcd0310ab9.tar.gz
rust-085744b7ad8b227239bcee0a44cd78dcd0310ab9.zip
Auto merge of #130036 - weiznich:diagnostic_unstable_tracking, r=compiler-errors
Correctly handle stability of `#[diagnostic]` attributes

This commit changes the way we treat the stability of attributes in the
`#[diagnostic]` namespace. Instead of relaying on ad-hoc checks to
ensure at call side that a certain attribute is really usable at that
location it centralises the logic to one place. For diagnostic
attributes comming from other crates it just skips serializing
attributes that are not stable and that do not have the corresponding
feature enabled. For attributes from the current crate we can just use
the feature information provided by `TyCtx`.

r​? `@compiler-errors`
Diffstat (limited to 'compiler/rustc_middle')
-rw-r--r--compiler/rustc_middle/src/ty/context.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs32
2 files changed, 32 insertions, 3 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 2a3008897c6..5334e767766 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -3183,8 +3183,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
     pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
-        matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true })
-            && self.impl_trait_header(def_id).is_some_and(|header| header.do_not_recommend)
+        self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index ee70a6346d9..e637ced7139 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -263,7 +263,6 @@ pub struct ImplTraitHeader<'tcx> {
     pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>,
     pub polarity: ImplPolarity,
     pub safety: hir::Safety,
-    pub do_not_recommend: bool,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
@@ -1797,6 +1796,37 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
+    /// Get an attribute from the diagnostic attribute namespace
+    ///
+    /// This function requests an attribute with the following structure:
+    ///
+    /// `#[diagnostic::$attr]`
+    ///
+    /// This function performs feature checking, so if an attribute is returned
+    /// it can be used by the consumer
+    pub fn get_diagnostic_attr(
+        self,
+        did: impl Into<DefId>,
+        attr: Symbol,
+    ) -> Option<&'tcx ast::Attribute> {
+        let did: DefId = did.into();
+        if did.as_local().is_some() {
+            // it's a crate local item, we need to check feature flags
+            if rustc_feature::is_stable_diagnostic_attribute(attr, self.features()) {
+                self.get_attrs_by_path(did, &[sym::diagnostic, sym::do_not_recommend]).next()
+            } else {
+                None
+            }
+        } else {
+            // we filter out unstable diagnostic attributes before
+            // encoding attributes
+            debug_assert!(rustc_feature::encode_cross_crate(attr));
+            self.item_attrs(did)
+                .iter()
+                .find(|a| matches!(a.path().as_ref(), [sym::diagnostic, a] if *a == attr))
+        }
+    }
+
     pub fn get_attrs_by_path<'attr>(
         self,
         did: DefId,