Skip to main content

rustc_attr_parsing/attributes/diagnostic/
opaque.rs

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