Skip to main content

rustc_attr_parsing/attributes/diagnostic/
opaque.rs

1use rustc_feature::AttributeStability;
2use rustc_hir::Target;
3use rustc_hir::attrs::AttributeKind;
4use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
5use rustc_span::{Span, sym};
6
7use crate::attributes::{AcceptMapping, AttributeParser};
8use crate::context::{AcceptContext, FinalizeContext};
9use crate::diagnostics::OpaqueDoesNotExpectArgs;
10use crate::parser::ArgParser;
11use crate::target_checking::AllowedTargets;
12use crate::target_checking::Policy::Allow;
13use crate::{template, unstable};
14
15#[derive(#[automatically_derived]
impl ::core::default::Default for OpaqueParser {
    #[inline]
    fn default() -> OpaqueParser {
        OpaqueParser { attr_span: ::core::default::Default::default() }
    }
}Default)]
16pub(crate) struct OpaqueParser {
17    attr_span: Option<Span>,
18}
19
20impl AttributeParser for OpaqueParser {
21    const ATTRIBUTES: AcceptMapping<Self> = &[
22        (
23            &[sym::diagnostic, sym::opaque],
24            crate::AttributeTemplate {
    word: true,
    list: None,
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word),
25            AttributeStability::Stable, // Unstable, stability checked manually in the parser
26            |this, cx, args| {
27                if !cx.features().diagnostic_opaque() {
28                    return;
29                }
30                this.parse(cx, args);
31            },
32        ),
33        (
34            // For use on exported macros, where using tool attributes is an error.
35            &[sym::rustc_diagnostic_opaque],
36            crate::AttributeTemplate {
    word: true,
    list: None,
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word),
37            AttributeStability::Unstable {
    gate_name: rustc_span::sym::rustc_attrs,
    gate_check: rustc_feature::Features::rustc_attrs,
    notes: &["see `#[diagnostic::opaque]` for the nightly equivalent of this attribute"],
}unstable!(
38                rustc_attrs,
39                "see `#[diagnostic::opaque]` for the nightly equivalent of this attribute"
40            ),
41            OpaqueParser::parse,
42        ),
43    ];
44    const ALLOWED_TARGETS: AllowedTargets<'_> =
45        AllowedTargets::AllowListWarnRest(&[Allow(Target::MacroDef)]);
46
47    fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
48        if let Some(_) = self.attr_span { Some(AttributeKind::Opaque) } else { None }
49    }
50}
51
52impl OpaqueParser {
53    fn parse<'sess>(&mut self, cx: &mut AcceptContext<'_, 'sess>, args: &ArgParser) {
54        let attr_span = cx.attr_span;
55        if let Some(earlier_span) = self.attr_span {
56            cx.warn_unused_duplicate(earlier_span, attr_span);
57        }
58        self.attr_span = Some(attr_span);
59
60        if !#[allow(non_exhaustive_omitted_patterns)] match args {
    ArgParser::NoArgs => true,
    _ => false,
}matches!(args, ArgParser::NoArgs) {
61            cx.emit_lint(MALFORMED_DIAGNOSTIC_ATTRIBUTES, OpaqueDoesNotExpectArgs, attr_span);
62        }
63    }
64}