rustc_attr_parsing/attributes/
test_attrs.rs

1use super::prelude::*;
2
3pub(crate) struct IgnoreParser;
4
5impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
6    const PATH: &[Symbol] = &[sym::ignore];
7    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
8    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
9    const ALLOWED_TARGETS: AllowedTargets =
10        AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]);
11    const TEMPLATE: AttributeTemplate = template!(
12        Word, NameValueStr: "reason",
13        "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute"
14    );
15
16    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
17        Some(AttributeKind::Ignore {
18            span: cx.attr_span,
19            reason: match args {
20                ArgParser::NoArgs => None,
21                ArgParser::NameValue(name_value) => {
22                    let Some(str_value) = name_value.value_as_str() else {
23                        let suggestions = cx.suggestions();
24                        let span = cx.attr_span;
25                        cx.emit_lint(
26                            AttributeLintKind::IllFormedAttributeInput { suggestions },
27                            span,
28                        );
29                        return None;
30                    };
31                    Some(str_value)
32                }
33                ArgParser::List(_) => {
34                    let suggestions = cx.suggestions();
35                    let span = cx.attr_span;
36                    cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
37                    return None;
38                }
39            },
40        })
41    }
42}
43
44pub(crate) struct ShouldPanicParser;
45
46impl<S: Stage> SingleAttributeParser<S> for ShouldPanicParser {
47    const PATH: &[Symbol] = &[sym::should_panic];
48    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
49    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
50    const ALLOWED_TARGETS: AllowedTargets =
51        AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]);
52    const TEMPLATE: AttributeTemplate = template!(
53        Word, List: &[r#"expected = "reason""#], NameValueStr: "reason",
54        "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute"
55    );
56
57    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
58        Some(AttributeKind::ShouldPanic {
59            span: cx.attr_span,
60            reason: match args {
61                ArgParser::NoArgs => None,
62                ArgParser::NameValue(name_value) => {
63                    let Some(str_value) = name_value.value_as_str() else {
64                        cx.expected_string_literal(
65                            name_value.value_span,
66                            Some(name_value.value_as_lit()),
67                        );
68                        return None;
69                    };
70                    Some(str_value)
71                }
72                ArgParser::List(list) => {
73                    let Some(single) = list.single() else {
74                        cx.expected_single_argument(list.span);
75                        return None;
76                    };
77                    let Some(single) = single.meta_item() else {
78                        cx.expected_name_value(single.span(), Some(sym::expected));
79                        return None;
80                    };
81                    if !single.path().word_is(sym::expected) {
82                        cx.expected_specific_argument_strings(list.span, &[sym::expected]);
83                        return None;
84                    }
85                    let Some(nv) = single.args().name_value() else {
86                        cx.expected_name_value(single.span(), Some(sym::expected));
87                        return None;
88                    };
89                    let Some(expected) = nv.value_as_str() else {
90                        cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
91                        return None;
92                    };
93                    Some(expected)
94                }
95            },
96        })
97    }
98}