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