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