Skip to content

Commit c8f151a

Browse files
committed
allow attribute parser to generate suggestions themselves
1 parent 61ad5a7 commit c8f151a

30 files changed

Lines changed: 673 additions & 464 deletions

compiler/rustc_attr_parsing/src/attributes/autodiff.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {
3636
ArgParser::NoArgs => return Some(AttributeKind::RustcAutodiff(None)),
3737
ArgParser::List(list) => list,
3838
ArgParser::NameValue(_) => {
39-
cx.expected_list_or_no_args(cx.attr_span);
39+
let attr_span = cx.attr_span;
40+
cx.adcx().expected_list_or_no_args(attr_span);
4041
return None;
4142
}
4243
};
@@ -45,23 +46,23 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {
4546

4647
// Parse name
4748
let Some(mode) = items.next() else {
48-
cx.expected_at_least_one_argument(list.span);
49+
cx.adcx().expected_at_least_one_argument(list.span);
4950
return None;
5051
};
5152
let Some(mode) = mode.meta_item() else {
52-
cx.expected_identifier(mode.span());
53+
cx.adcx().expected_identifier(mode.span());
5354
return None;
5455
};
5556
let Ok(()) = mode.args().no_args() else {
56-
cx.expected_identifier(mode.span());
57+
cx.adcx().expected_identifier(mode.span());
5758
return None;
5859
};
5960
let Some(mode) = mode.path().word() else {
60-
cx.expected_identifier(mode.span());
61+
cx.adcx().expected_identifier(mode.span());
6162
return None;
6263
};
6364
let Ok(mode) = DiffMode::from_str(mode.as_str()) else {
64-
cx.expected_specific_argument(mode.span, DiffMode::all_modes());
65+
cx.adcx().expected_specific_argument(mode.span, DiffMode::all_modes());
6566
return None;
6667
};
6768

@@ -81,26 +82,29 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {
8182
let mut activities = ThinVec::new();
8283
for activity in items {
8384
let MetaItemOrLitParser::MetaItemParser(activity) = activity else {
84-
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
85+
cx.adcx()
86+
.expected_specific_argument(activity.span(), DiffActivity::all_activities());
8587
return None;
8688
};
8789
let Ok(()) = activity.args().no_args() else {
88-
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
90+
cx.adcx()
91+
.expected_specific_argument(activity.span(), DiffActivity::all_activities());
8992
return None;
9093
};
9194
let Some(activity) = activity.path().word() else {
92-
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
95+
cx.adcx()
96+
.expected_specific_argument(activity.span(), DiffActivity::all_activities());
9397
return None;
9498
};
9599
let Ok(activity) = DiffActivity::from_str(activity.as_str()) else {
96-
cx.expected_specific_argument(activity.span, DiffActivity::all_activities());
100+
cx.adcx().expected_specific_argument(activity.span, DiffActivity::all_activities());
97101
return None;
98102
};
99103

100104
activities.push(activity);
101105
}
102106
let Some(ret_activity) = activities.pop() else {
103-
cx.expected_specific_argument(
107+
cx.adcx().expected_specific_argument(
104108
list.span.with_lo(list.span.hi()),
105109
DiffActivity::all_activities(),
106110
);

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ pub fn parse_cfg<S: Stage>(
4444
args: &ArgParser,
4545
) -> Option<CfgEntry> {
4646
let ArgParser::List(list) = args else {
47-
cx.expected_list(cx.attr_span, args);
47+
let attr_span = cx.attr_span;
48+
cx.adcx().expected_list(attr_span, args);
4849
return None;
4950
};
5051
let Some(single) = list.single() else {
51-
cx.expected_single_argument(list.span);
52+
cx.adcx().expected_single_argument(list.span);
5253
return None;
5354
};
5455
parse_cfg_entry(cx, single).ok()
@@ -63,7 +64,7 @@ pub fn parse_cfg_entry<S: Stage>(
6364
ArgParser::List(list) => match meta.path().word_sym() {
6465
Some(sym::not) => {
6566
let Some(single) = list.single() else {
66-
return Err(cx.expected_single_argument(list.span));
67+
return Err(cx.adcx().expected_single_argument(list.span));
6768
};
6869
CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span)
6970
}
@@ -87,14 +88,14 @@ pub fn parse_cfg_entry<S: Stage>(
8788
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
8889
let Some(name) = meta.path().word_sym().filter(|s| !s.is_path_segment_keyword())
8990
else {
90-
return Err(cx.expected_identifier(meta.path().span()));
91+
return Err(cx.adcx().expected_identifier(meta.path().span()));
9192
};
9293
parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)?
9394
}
9495
},
9596
MetaItemOrLitParser::Lit(lit) => match lit.kind {
9697
LitKind::Bool(b) => CfgEntry::Bool(b, lit.span),
97-
_ => return Err(cx.expected_identifier(lit.span)),
98+
_ => return Err(cx.adcx().expected_identifier(lit.span)),
9899
},
99100
})
100101
}
@@ -152,17 +153,17 @@ fn parse_cfg_entry_target<S: Stage>(
152153
for sub_item in list.mixed() {
153154
// First, validate that this is a NameValue item
154155
let Some(sub_item) = sub_item.meta_item() else {
155-
cx.expected_name_value(sub_item.span(), None);
156+
cx.adcx().expected_name_value(sub_item.span(), None);
156157
continue;
157158
};
158159
let Some(nv) = sub_item.args().name_value() else {
159-
cx.expected_name_value(sub_item.span(), None);
160+
cx.adcx().expected_name_value(sub_item.span(), None);
160161
continue;
161162
};
162163

163164
// Then, parse it as a name-value item
164165
let Some(name) = sub_item.path().word_sym().filter(|s| !s.is_path_segment_keyword()) else {
165-
return Err(cx.expected_identifier(sub_item.path().span()));
166+
return Err(cx.adcx().expected_identifier(sub_item.path().span()));
166167
};
167168
let name = Symbol::intern(&format!("target_{name}"));
168169
if let Ok(cfg) =
@@ -187,9 +188,9 @@ pub(crate) fn parse_name_value<S: Stage>(
187188
None => None,
188189
Some(value) => {
189190
let Some(value_str) = value.value_as_str() else {
190-
return Err(
191-
cx.expected_string_literal(value.value_span, Some(value.value_as_lit()))
192-
);
191+
return Err(cx
192+
.adcx()
193+
.expected_string_literal(value.value_span, Some(value.value_as_lit())));
193194
};
194195
Some((value_str, value.value_span))
195196
}
@@ -335,8 +336,10 @@ pub fn parse_cfg_attr(
335336
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path, identity),
336337
description: ParsedDescription::Attribute,
337338
reason,
338-
suggestions: CFG_ATTR_TEMPLATE
339-
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr),
339+
suggestions: session_diagnostics::AttributeParseErrorSuggestions::CreatedByTemplate(
340+
CFG_ATTR_TEMPLATE
341+
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr),
342+
),
340343
});
341344
}
342345
}

compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ impl<S: Stage> SingleAttributeParser<S> for CfiEncodingParser {
1313

1414
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
1515
let Some(name_value) = args.name_value() else {
16-
cx.expected_name_value(cx.attr_span, Some(sym::cfi_encoding));
16+
let attr_span = cx.attr_span;
17+
cx.adcx().expected_name_value(attr_span, Some(sym::cfi_encoding));
1718
return None;
1819
};
1920

2021
let Some(value_str) = name_value.value_as_str() else {
21-
cx.expected_string_literal(name_value.value_span, None);
22+
cx.adcx().expected_string_literal(name_value.value_span, None);
2223
return None;
2324
};
2425

2526
if value_str.as_str().trim().is_empty() {
26-
cx.expected_non_empty_string_literal(name_value.value_span);
27+
cx.adcx().expected_non_empty_string_literal(name_value.value_span);
2728
return None;
2829
}
2930

0 commit comments

Comments
 (0)