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`.
This commit is contained in:
@@ -1797,6 +1797,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,
|
||||
|
||||
Reference in New Issue
Block a user