rustc_attr_parsing/attributes/diagnostic/
on_unimplemented.rs1use rustc_hir::attrs::diagnostic::Directive;
2use rustc_hir::lints::AttributeLintKind;
3use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
4
5use crate::attributes::diagnostic::*;
6use crate::attributes::prelude::*;
7
8#[derive(#[automatically_derived]
impl ::core::default::Default for OnUnimplementedParser {
#[inline]
fn default() -> OnUnimplementedParser {
OnUnimplementedParser {
span: ::core::default::Default::default(),
directive: ::core::default::Default::default(),
}
}
}Default)]
9pub(crate) struct OnUnimplementedParser {
10 span: Option<Span>,
11 directive: Option<(Span, Directive)>,
12}
13
14impl OnUnimplementedParser {
15 fn parse<'sess, S: Stage>(
16 &mut self,
17 cx: &mut AcceptContext<'_, 'sess, S>,
18 args: &ArgParser,
19 mode: Mode,
20 ) {
21 let span = cx.attr_span;
22 self.span = Some(span);
23
24 if !#[allow(non_exhaustive_omitted_patterns)] match cx.target {
Target::Trait => true,
_ => false,
}matches!(cx.target, Target::Trait) {
28 return;
30 }
31
32 let items = match args {
33 ArgParser::List(items) if items.len() != 0 => items,
34 ArgParser::NoArgs | ArgParser::List(_) => {
35 cx.emit_lint(
36 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
37 AttributeLintKind::MissingOptionsForOnUnimplemented,
38 span,
39 );
40 return;
41 }
42 ArgParser::NameValue(_) => {
43 cx.emit_lint(
44 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
45 AttributeLintKind::MalformedOnUnimplementedAttr { span },
46 span,
47 );
48 return;
49 }
50 };
51
52 if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
53 merge_directives(cx, &mut self.directive, (span, directive));
54 };
55 }
56}
57
58impl<S: Stage> AttributeParser<S> for OnUnimplementedParser {
59 const ATTRIBUTES: AcceptMapping<Self, S> = &[
60 (
61 &[sym::diagnostic, sym::on_unimplemented],
62 ::rustc_feature::AttributeTemplate {
word: false,
list: Some(&[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
one_of: &[],
name_value_str: None,
docs: None,
}template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
63 |this, cx, args| {
64 this.parse(cx, args, Mode::DiagnosticOnUnimplemented);
65 },
66 ),
67 (
68 &[sym::rustc_on_unimplemented],
69 ::rustc_feature::AttributeTemplate {
word: false,
list: Some(&[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
one_of: &[],
name_value_str: None,
docs: None,
}template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
70 |this, cx, args| {
71 this.parse(cx, args, Mode::RustcOnUnimplemented);
72 },
73 ),
74 ];
75 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
77
78 fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
79 if let Some(span) = self.span {
80 Some(AttributeKind::OnUnimplemented {
81 span,
82 directive: self.directive.map(|d| Box::new(d.1)),
83 })
84 } else {
85 None
86 }
87 }
88}