Skip to main content

rustc_attr_parsing/attributes/diagnostic/
on_const.rs

1use 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 OnConstParser {
    #[inline]
    fn default() -> OnConstParser {
        OnConstParser {
            span: ::core::default::Default::default(),
            directive: ::core::default::Default::default(),
        }
    }
}Default)]
9pub(crate) struct OnConstParser {
10    span: Option<Span>,
11    directive: Option<(Span, Directive)>,
12}
13
14impl<S: Stage> AttributeParser<S> for OnConstParser {
15    const ATTRIBUTES: AcceptMapping<Self, S> = &[(
16        &[sym::diagnostic, sym::on_const],
17        ::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 = "...""#]),
18        |this, cx, args| {
19            if !cx.features().diagnostic_on_const() {
20                return;
21            }
22
23            let span = cx.attr_span;
24            this.span = Some(span);
25
26            let items = match args {
27                ArgParser::List(items) if items.len() != 0 => items,
28                ArgParser::NoArgs | ArgParser::List(_) => {
29                    cx.emit_lint(
30                        MALFORMED_DIAGNOSTIC_ATTRIBUTES,
31                        AttributeLintKind::MissingOptionsForOnConst,
32                        span,
33                    );
34                    return;
35                }
36                ArgParser::NameValue(_) => {
37                    cx.emit_lint(
38                        MALFORMED_DIAGNOSTIC_ATTRIBUTES,
39                        AttributeLintKind::MalformedOnConstAttr { span },
40                        span,
41                    );
42                    return;
43                }
44            };
45
46            let Some(directive) =
47                parse_directive_items(cx, Mode::DiagnosticOnConst, items.mixed(), true)
48            else {
49                return;
50            };
51            merge_directives(cx, &mut this.directive, (span, directive));
52        },
53    )];
54
55    //FIXME Still checked in `check_attr.rs`
56    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
57
58    fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
59        if let Some(span) = self.span {
60            Some(AttributeKind::OnConst { span, directive: self.directive.map(|d| Box::new(d.1)) })
61        } else {
62            None
63        }
64    }
65}