rustc_attr_parsing/attributes/diagnostic/
opaque.rs1use 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, |this, cx, args| {
27 if !cx.features().diagnostic_opaque() {
28 return;
29 }
30 this.parse(cx, args);
31 },
32 ),
33 (
34 &[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}