rustc_attr_parsing/attributes/diagnostic/
opaque.rs1use 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, |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 &[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}