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