Skip to content

Commit 62a9658

Browse files
authored
Rollup merge of #154590 - scrabsha:push-xzmtpsntoxwm, r=jdonszelmann
Make #[cfg] suggest any or all on #[cfg(a, b)]
2 parents e5e3c25 + edb9322 commit 62a9658

36 files changed

+946
-486
lines changed

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: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,41 @@ 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
};
51+
5052
let Some(single) = list.single() else {
51-
cx.expected_single_argument(list.span);
53+
let target = cx.target;
54+
let mut adcx = cx.adcx();
55+
if list.is_empty() {
56+
// `#[cfg()]`
57+
let message = format!("if the {target} should be disabled, use `#[cfg(false)]`");
58+
adcx.push_suggestion(message, list.span, "(false)".to_string());
59+
} else {
60+
// `#[cfg(foo, bar)]`
61+
if let Ok(args) = adcx
62+
.sess()
63+
.source_map()
64+
.span_to_source(list.span, |src, start, end| Ok(src[start..end].to_string()))
65+
{
66+
let all = format!("(all{args})");
67+
let any = format!("(any{args})");
68+
69+
let all_msg = format!(
70+
"if the {target} should be enabled when all these predicates are, wrap them in `all`"
71+
);
72+
let any_msg = format!(
73+
"alternately, if the {target} should be enabled when any of these predicates are, wrap them in `any`"
74+
);
75+
76+
adcx.push_suggestion(all_msg, list.span, all);
77+
adcx.push_suggestion(any_msg, list.span, any);
78+
}
79+
}
80+
81+
adcx.expected_single_argument(list.span);
5282
return None;
5383
};
5484
parse_cfg_entry(cx, single).ok()
@@ -63,7 +93,7 @@ pub fn parse_cfg_entry<S: Stage>(
6393
ArgParser::List(list) => match meta.path().word_sym() {
6494
Some(sym::not) => {
6595
let Some(single) = list.single() else {
66-
return Err(cx.expected_single_argument(list.span));
96+
return Err(cx.adcx().expected_single_argument(list.span));
6797
};
6898
CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span)
6999
}
@@ -87,14 +117,14 @@ pub fn parse_cfg_entry<S: Stage>(
87117
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
88118
let Some(name) = meta.path().word_sym().filter(|s| !s.is_path_segment_keyword())
89119
else {
90-
return Err(cx.expected_identifier(meta.path().span()));
120+
return Err(cx.adcx().expected_identifier(meta.path().span()));
91121
};
92122
parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)?
93123
}
94124
},
95125
MetaItemOrLitParser::Lit(lit) => match lit.kind {
96126
LitKind::Bool(b) => CfgEntry::Bool(b, lit.span),
97-
_ => return Err(cx.expected_identifier(lit.span)),
127+
_ => return Err(cx.adcx().expected_identifier(lit.span)),
98128
},
99129
})
100130
}
@@ -152,17 +182,17 @@ fn parse_cfg_entry_target<S: Stage>(
152182
for sub_item in list.mixed() {
153183
// First, validate that this is a NameValue item
154184
let Some(sub_item) = sub_item.meta_item() else {
155-
cx.expected_name_value(sub_item.span(), None);
185+
cx.adcx().expected_name_value(sub_item.span(), None);
156186
continue;
157187
};
158188
let Some(nv) = sub_item.args().name_value() else {
159-
cx.expected_name_value(sub_item.span(), None);
189+
cx.adcx().expected_name_value(sub_item.span(), None);
160190
continue;
161191
};
162192

163193
// Then, parse it as a name-value item
164194
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()));
195+
return Err(cx.adcx().expected_identifier(sub_item.path().span()));
166196
};
167197
let name = Symbol::intern(&format!("target_{name}"));
168198
if let Ok(cfg) =
@@ -187,9 +217,9 @@ pub(crate) fn parse_name_value<S: Stage>(
187217
None => None,
188218
Some(value) => {
189219
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-
);
220+
return Err(cx
221+
.adcx()
222+
.expected_string_literal(value.value_span, Some(value.value_as_lit())));
193223
};
194224
Some((value_str, value.value_span))
195225
}
@@ -335,8 +365,10 @@ pub fn parse_cfg_attr(
335365
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path, identity),
336366
description: ParsedDescription::Attribute,
337367
reason,
338-
suggestions: CFG_ATTR_TEMPLATE
339-
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr),
368+
suggestions: session_diagnostics::AttributeParseErrorSuggestions::CreatedByTemplate(
369+
CFG_ATTR_TEMPLATE
370+
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr),
371+
),
340372
});
341373
}
342374
}

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)