Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
02b516a
core: Update the feature gate on `TryFrom<integer> for bool`
tgross35 Apr 1, 2026
8863db8
add broken test for multiple cfg arguments
scrabsha Mar 29, 2026
7199a0b
rustdoc: fix href of extern crates in search results
lolbinarycat Apr 1, 2026
3888a63
Add a regression test for rustdoc ICEing on negative `Deref`/`DerefMu…
jakubadamw Mar 26, 2026
23b1e78
rustdoc: When collecting `Deref` impls with their targets, skip the n…
jakubadamw Mar 26, 2026
02a73db
Address review feedback.
jakubadamw Mar 27, 2026
3bde2a7
allow attribute parser to generate suggestions themselves
scrabsha Mar 29, 2026
4e019ac
make `cfg` parser suggest `any` or `all` on `#[cfg(a, b)]`
scrabsha Mar 29, 2026
eb20cad
make sure the right target is passed to `#[cfg()]` when it is parsed
scrabsha Mar 30, 2026
8c44809
Correctly handle std "channels" in `rustdoc-js` tests
GuillaumeGomez Apr 2, 2026
edb9322
fix doc in rustc_attr_parsing::context
scrabsha Apr 2, 2026
e469da4
rustdoc: Improve internal function name
aDotInTheVoid Apr 2, 2026
b0c4b6e
fix(std): avoid AT_MINSIGSTKSZ on uclibc targets
xtqqczze Apr 2, 2026
e5e3c25
Rollup merge of #154444 - jakubadamw:issue-128801, r=fmease
jhpratt Apr 3, 2026
62a9658
Rollup merge of #154590 - scrabsha:push-xzmtpsntoxwm, r=jdonszelmann
jhpratt Apr 3, 2026
e1cd0ad
Rollup merge of #154691 - tgross35:bool-try-from-int, r=cuviper
jhpratt Apr 3, 2026
6f336f9
Rollup merge of #154697 - lolbinarycat:rustdoc-renamed-crate, r=Guill…
jhpratt Apr 3, 2026
325340e
Rollup merge of #154728 - aDotInTheVoid:doc-cfgz-nuts-gotem, r=Guilla…
jhpratt Apr 3, 2026
53af5ab
Rollup merge of #154732 - xtqqczze:GH154679, r=tgross35
jhpratt Apr 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions compiler/rustc_attr_parsing/src/attributes/autodiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {
ArgParser::NoArgs => return Some(AttributeKind::RustcAutodiff(None)),
ArgParser::List(list) => list,
ArgParser::NameValue(_) => {
cx.expected_list_or_no_args(cx.attr_span);
let attr_span = cx.attr_span;
cx.adcx().expected_list_or_no_args(attr_span);
return None;
}
};
Expand All @@ -45,23 +46,23 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {

// Parse name
let Some(mode) = items.next() else {
cx.expected_at_least_one_argument(list.span);
cx.adcx().expected_at_least_one_argument(list.span);
return None;
};
let Some(mode) = mode.meta_item() else {
cx.expected_identifier(mode.span());
cx.adcx().expected_identifier(mode.span());
return None;
};
let Ok(()) = mode.args().no_args() else {
cx.expected_identifier(mode.span());
cx.adcx().expected_identifier(mode.span());
return None;
};
let Some(mode) = mode.path().word() else {
cx.expected_identifier(mode.span());
cx.adcx().expected_identifier(mode.span());
return None;
};
let Ok(mode) = DiffMode::from_str(mode.as_str()) else {
cx.expected_specific_argument(mode.span, DiffMode::all_modes());
cx.adcx().expected_specific_argument(mode.span, DiffMode::all_modes());
return None;
};

Expand All @@ -81,26 +82,29 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {
let mut activities = ThinVec::new();
for activity in items {
let MetaItemOrLitParser::MetaItemParser(activity) = activity else {
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
cx.adcx()
.expected_specific_argument(activity.span(), DiffActivity::all_activities());
return None;
};
let Ok(()) = activity.args().no_args() else {
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
cx.adcx()
.expected_specific_argument(activity.span(), DiffActivity::all_activities());
return None;
};
let Some(activity) = activity.path().word() else {
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
cx.adcx()
.expected_specific_argument(activity.span(), DiffActivity::all_activities());
return None;
};
let Ok(activity) = DiffActivity::from_str(activity.as_str()) else {
cx.expected_specific_argument(activity.span, DiffActivity::all_activities());
cx.adcx().expected_specific_argument(activity.span, DiffActivity::all_activities());
return None;
};

activities.push(activity);
}
let Some(ret_activity) = activities.pop() else {
cx.expected_specific_argument(
cx.adcx().expected_specific_argument(
list.span.with_lo(list.span.hi()),
DiffActivity::all_activities(),
);
Expand Down
58 changes: 45 additions & 13 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,41 @@ pub fn parse_cfg<S: Stage>(
args: &ArgParser,
) -> Option<CfgEntry> {
let ArgParser::List(list) = args else {
cx.expected_list(cx.attr_span, args);
let attr_span = cx.attr_span;
cx.adcx().expected_list(attr_span, args);
return None;
};

let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
let target = cx.target;
let mut adcx = cx.adcx();
if list.is_empty() {
// `#[cfg()]`
let message = format!("if the {target} should be disabled, use `#[cfg(false)]`");
adcx.push_suggestion(message, list.span, "(false)".to_string());
} else {
// `#[cfg(foo, bar)]`
if let Ok(args) = adcx
.sess()
.source_map()
.span_to_source(list.span, |src, start, end| Ok(src[start..end].to_string()))
{
let all = format!("(all{args})");
let any = format!("(any{args})");

let all_msg = format!(
"if the {target} should be enabled when all these predicates are, wrap them in `all`"
);
let any_msg = format!(
"alternately, if the {target} should be enabled when any of these predicates are, wrap them in `any`"
);

adcx.push_suggestion(all_msg, list.span, all);
adcx.push_suggestion(any_msg, list.span, any);
}
}

adcx.expected_single_argument(list.span);
return None;
};
parse_cfg_entry(cx, single).ok()
Expand All @@ -63,7 +93,7 @@ pub fn parse_cfg_entry<S: Stage>(
ArgParser::List(list) => match meta.path().word_sym() {
Some(sym::not) => {
let Some(single) = list.single() else {
return Err(cx.expected_single_argument(list.span));
return Err(cx.adcx().expected_single_argument(list.span));
};
CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span)
}
Expand All @@ -87,14 +117,14 @@ pub fn parse_cfg_entry<S: Stage>(
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
let Some(name) = meta.path().word_sym().filter(|s| !s.is_path_segment_keyword())
else {
return Err(cx.expected_identifier(meta.path().span()));
return Err(cx.adcx().expected_identifier(meta.path().span()));
};
parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)?
}
},
MetaItemOrLitParser::Lit(lit) => match lit.kind {
LitKind::Bool(b) => CfgEntry::Bool(b, lit.span),
_ => return Err(cx.expected_identifier(lit.span)),
_ => return Err(cx.adcx().expected_identifier(lit.span)),
},
})
}
Expand Down Expand Up @@ -152,17 +182,17 @@ fn parse_cfg_entry_target<S: Stage>(
for sub_item in list.mixed() {
// First, validate that this is a NameValue item
let Some(sub_item) = sub_item.meta_item() else {
cx.expected_name_value(sub_item.span(), None);
cx.adcx().expected_name_value(sub_item.span(), None);
continue;
};
let Some(nv) = sub_item.args().name_value() else {
cx.expected_name_value(sub_item.span(), None);
cx.adcx().expected_name_value(sub_item.span(), None);
continue;
};

// Then, parse it as a name-value item
let Some(name) = sub_item.path().word_sym().filter(|s| !s.is_path_segment_keyword()) else {
return Err(cx.expected_identifier(sub_item.path().span()));
return Err(cx.adcx().expected_identifier(sub_item.path().span()));
};
let name = Symbol::intern(&format!("target_{name}"));
if let Ok(cfg) =
Expand All @@ -187,9 +217,9 @@ pub(crate) fn parse_name_value<S: Stage>(
None => None,
Some(value) => {
let Some(value_str) = value.value_as_str() else {
return Err(
cx.expected_string_literal(value.value_span, Some(value.value_as_lit()))
);
return Err(cx
.adcx()
.expected_string_literal(value.value_span, Some(value.value_as_lit())));
};
Some((value_str, value.value_span))
}
Expand Down Expand Up @@ -335,8 +365,10 @@ pub fn parse_cfg_attr(
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path, identity),
description: ParsedDescription::Attribute,
reason,
suggestions: CFG_ATTR_TEMPLATE
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr),
suggestions: session_diagnostics::AttributeParseErrorSuggestions::CreatedByTemplate(
CFG_ATTR_TEMPLATE
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr),
),
});
}
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ impl<S: Stage> SingleAttributeParser<S> for CfiEncodingParser {

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

let Some(value_str) = name_value.value_as_str() else {
cx.expected_string_literal(name_value.value_span, None);
cx.adcx().expected_string_literal(name_value.value_span, None);
return None;
};

if value_str.as_str().trim().is_empty() {
cx.expected_non_empty_string_literal(name_value.value_span);
cx.adcx().expected_non_empty_string_literal(name_value.value_span);
return None;
}

Expand Down
Loading
Loading