rustc_attr_parsing/attributes/
test_attrs.rs1use 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}