Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
806b443
add check for typo in let chains
Kivooeo Oct 21, 2025
caf1d89
extend some comments and clarify some names around enum tag type comp…
RalfJung Sep 24, 2025
d0349fd
FCW for repr(C) enums whose discriminant values do not fit into a c_int
RalfJung Sep 25, 2025
13a3ac7
do not complain about enums where all discriminants fit into a c_uint
RalfJung Oct 2, 2025
b92ed4e
reflect that type and const parameter can be intermixed
tshepang Oct 29, 2025
73515c7
fix: Only special case single line item attribute suggestions
Muscraft Oct 22, 2025
d472d91
address review
Kivooeo Oct 31, 2025
516a273
Suggest making binding `mut` on `&mut` reborrow
estebank Sep 29, 2025
93fef45
Fix `wasm_import_module` attribute cross-crate
alexcrichton Nov 1, 2025
ba2600e
Suggest appropriate type instead of `Self` in E0401
estebank Nov 3, 2025
4af32ca
Add test
estebank Nov 3, 2025
48dde00
Use more accurate span in `resolve_ident_in_lexical_scope`
estebank Nov 3, 2025
14646ec
Add note to E0401
estebank Nov 3, 2025
001be2f
Make `parse_cfg_entry` output `ErrorGuaranteed` on failure
JonathanBrouwer Oct 21, 2025
b78800f
Port `cfg!()` macro to the new attribute parsing system
JonathanBrouwer Oct 21, 2025
a628e71
Add `ParsedDescription` to the attribute parsers
JonathanBrouwer Oct 29, 2025
4b72a93
Rollup merge of #147017 - RalfJung:repr-c-big-discriminant, r=davidtwco
GuillaumeGomez Nov 3, 2025
4a8c1ab
Rollup merge of #147141 - estebank:issue-81059, r=jackh726
GuillaumeGomez Nov 3, 2025
27fe67f
Rollup merge of #147945 - JonathanBrouwer:cfg_macro, r=jdonszelmann
GuillaumeGomez Nov 3, 2025
62e1dbf
Rollup merge of #147951 - Kivooeo:plus-equal-let-chains, r=davidtwco
GuillaumeGomez Nov 3, 2025
b261cb1
Rollup merge of #148004 - Muscraft:only-single-line-item-attributes, …
GuillaumeGomez Nov 3, 2025
4dcc84e
Rollup merge of #148264 - tshepang:patch-4, r=jackh726
GuillaumeGomez Nov 3, 2025
d907ac9
Rollup merge of #148363 - alexcrichton:fix-wasm-link-name, r=jackh726
GuillaumeGomez Nov 3, 2025
3cd6aa4
Rollup merge of #148447 - estebank:outer-param-2, r=jackh726
GuillaumeGomez Nov 3, 2025
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
2 changes: 1 addition & 1 deletion compiler/rustc_abi/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
let (max, min) = largest_niche
// We might have no inhabited variants, so pretend there's at least one.
.unwrap_or((0, 0));
let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::repr_discr(tcx, ty, &repr, min, max);
let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::discr_range_of_repr(tcx, ty, &repr, min, max);

let mut align = dl.aggregate_align;
let mut max_repr_align = repr.align;
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ impl ReprOptions {

/// Returns the discriminant type, given these `repr` options.
/// This must only be called on enums!
///
/// This is the "typeck type" of the discriminant, which is effectively the maximum size:
/// discriminant values will be wrapped to fit (with a lint). Layout can later decide to use a
/// smaller type for the tag that stores the discriminant at runtime and that will work just
/// fine, it just induces casts when getting/setting the discriminant.
pub fn discr_type(&self) -> IntegerType {
self.int.unwrap_or(IntegerType::Pointer(true))
}
Expand Down
73 changes: 37 additions & 36 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ use rustc_session::config::ExpectedValues;
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
use rustc_session::parse::{ParseSess, feature_err};
use rustc_span::{Span, Symbol, sym};
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
use thin_vec::ThinVec;

use crate::context::{AcceptContext, ShouldEmit, Stage};
use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser};
use crate::session_diagnostics::{
AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
ParsedDescription,
};
use crate::{
AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics,
Expand Down Expand Up @@ -47,20 +48,19 @@ pub fn parse_cfg<'c, S: Stage>(
cx.expected_single_argument(list.span);
return None;
};
parse_cfg_entry(cx, single)
parse_cfg_entry(cx, single).ok()
}

pub(crate) fn parse_cfg_entry<S: Stage>(
pub fn parse_cfg_entry<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
item: &MetaItemOrLitParser<'_>,
) -> Option<CfgEntry> {
Some(match item {
) -> Result<CfgEntry, ErrorGuaranteed> {
Ok(match item {
MetaItemOrLitParser::MetaItemParser(meta) => match meta.args() {
ArgParser::List(list) => match meta.path().word_sym() {
Some(sym::not) => {
let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
return None;
return Err(cx.expected_single_argument(list.span));
};
CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span)
}
Expand All @@ -75,49 +75,47 @@ pub(crate) fn parse_cfg_entry<S: Stage>(
Some(sym::target) => parse_cfg_entry_target(cx, list, meta.span())?,
Some(sym::version) => parse_cfg_entry_version(cx, list, meta.span())?,
_ => {
cx.emit_err(session_diagnostics::InvalidPredicate {
return Err(cx.emit_err(session_diagnostics::InvalidPredicate {
span: meta.span(),
predicate: meta.path().to_string(),
});
return None;
}));
}
},
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
let Some(name) = meta.path().word_sym() else {
cx.expected_identifier(meta.path().span());
return None;
return Err(cx.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),
_ => {
cx.expected_identifier(lit.span);
return None;
}
_ => return Err(cx.expected_identifier(lit.span)),
},
MetaItemOrLitParser::Err(_, _) => return None,
MetaItemOrLitParser::Err(_, err) => return Err(*err),
})
}

fn parse_cfg_entry_version<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
list: &MetaItemListParser<'_>,
meta_span: Span,
) -> Option<CfgEntry> {
) -> Result<CfgEntry, ErrorGuaranteed> {
try_gate_cfg(sym::version, meta_span, cx.sess(), cx.features_option());
let Some(version) = list.single() else {
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span });
return None;
return Err(
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span })
);
};
let Some(version_lit) = version.lit() else {
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() });
return None;
return Err(
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() })
);
};
let Some(version_str) = version_lit.value_str() else {
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span });
return None;
return Err(
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span })
);
};

let min_version = parse_version(version_str).or_else(|| {
Expand All @@ -127,14 +125,14 @@ fn parse_cfg_entry_version<S: Stage>(
None
});

Some(CfgEntry::Version(min_version, list.span))
Ok(CfgEntry::Version(min_version, list.span))
}

fn parse_cfg_entry_target<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
list: &MetaItemListParser<'_>,
meta_span: Span,
) -> Option<CfgEntry> {
) -> Result<CfgEntry, ErrorGuaranteed> {
if let Some(features) = cx.features_option()
&& !features.cfg_target_compact()
{
Expand All @@ -161,17 +159,16 @@ fn parse_cfg_entry_target<S: Stage>(

// Then, parse it as a name-value item
let Some(name) = sub_item.path().word_sym() else {
cx.expected_identifier(sub_item.path().span());
return None;
return Err(cx.expected_identifier(sub_item.path().span()));
};
let name = Symbol::intern(&format!("target_{name}"));
if let Some(cfg) =
if let Ok(cfg) =
parse_name_value(name, sub_item.path().span(), Some(nv), sub_item.span(), cx)
{
result.push(cfg);
}
}
Some(CfgEntry::All(result, list.span))
Ok(CfgEntry::All(result, list.span))
}

fn parse_name_value<S: Stage>(
Expand All @@ -180,21 +177,22 @@ fn parse_name_value<S: Stage>(
value: Option<&NameValueParser>,
span: Span,
cx: &mut AcceptContext<'_, '_, S>,
) -> Option<CfgEntry> {
) -> Result<CfgEntry, ErrorGuaranteed> {
try_gate_cfg(name, span, cx.sess(), cx.features_option());

let value = match value {
None => None,
Some(value) => {
let Some(value_str) = value.value_as_str() else {
cx.expected_string_literal(value.value_span, Some(value.value_as_lit()));
return None;
return Err(
cx.expected_string_literal(value.value_span, Some(value.value_as_lit()))
);
};
Some((value_str, value.value_span))
}
};

Some(CfgEntry::NameValue { name, name_span, value, span })
Ok(CfgEntry::NameValue { name, name_span, value, span })
}

pub fn eval_config_entry(
Expand Down Expand Up @@ -355,7 +353,8 @@ pub fn parse_cfg_attr(
span,
attr_span: cfg_attr.span,
template: CFG_ATTR_TEMPLATE,
attribute: AttrPath::from_ast(&cfg_attr.get_normal_item().path),
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path),
description: ParsedDescription::Attribute,
reason,
suggestions: CFG_ATTR_TEMPLATE.suggestions(Some(cfg_attr.style), sym::cfg_attr),
});
Expand Down Expand Up @@ -398,6 +397,7 @@ fn parse_cfg_attr_internal<'a>(
.into_boxed_slice(),
span: attribute.span,
},
ParsedDescription::Attribute,
pred_span,
CRATE_NODE_ID,
features,
Expand All @@ -406,7 +406,8 @@ fn parse_cfg_attr_internal<'a>(
parse_cfg_entry,
&CFG_ATTR_TEMPLATE,
)
.ok_or_else(|| {
.map_err(|_err: ErrorGuaranteed| {
// We have an `ErrorGuaranteed` so this delayed bug cannot fail, but we need a `Diag` for the `PResult` so we make one anyways
let mut diag = sess.dcx().struct_err(
"cfg_entry parsing failing with `ShouldEmit::ErrorsAndLints` should emit a error.",
);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ impl LinkParser {
)
.emit();
}
*cfg = parse_cfg_entry(cx, link_cfg);
*cfg = parse_cfg_entry(cx, link_cfg).ok();
true
}

Expand Down
47 changes: 33 additions & 14 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ use crate::attributes::traits::{
use crate::attributes::transparency::TransparencyParser;
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
use crate::parser::{ArgParser, PathParser};
use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};
use crate::session_diagnostics::{
AttributeParseError, AttributeParseErrorReason, ParsedDescription, UnknownMetaItem,
};
use crate::target_checking::AllowedTargets;

type GroupType<S> = LazyLock<GroupTypeInner<S>>;
Expand Down Expand Up @@ -353,6 +355,10 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
/// Whether it is an inner or outer attribute
pub(crate) attr_style: AttrStyle,

/// A description of the thing we are parsing using this attribute parser
/// We are not only using these parsers for attributes, but also for macros such as the `cfg!()` macro.
pub(crate) parsed_description: ParsedDescription,

/// The expected structure of the attribute.
///
/// Used in reporting errors to give a hint to users what the attribute *should* look like.
Expand Down Expand Up @@ -431,7 +437,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedStringLiteral {
byte_string: actual_literal.and_then(|i| {
i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))
Expand All @@ -446,7 +453,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedIntegerLiteral,
suggestions: self.suggestions(),
})
Expand All @@ -457,7 +465,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedList,
suggestions: self.suggestions(),
})
Expand All @@ -468,7 +477,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span: args_span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedNoArgs,
suggestions: self.suggestions(),
})
Expand All @@ -480,7 +490,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedIdentifier,
suggestions: self.suggestions(),
})
Expand All @@ -493,7 +504,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedNameValue(name),
suggestions: self.suggestions(),
})
Expand All @@ -505,7 +517,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::DuplicateKey(key),
suggestions: self.suggestions(),
})
Expand All @@ -518,7 +531,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::UnexpectedLiteral,
suggestions: self.suggestions(),
})
Expand All @@ -529,7 +543,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedSingleArgument,
suggestions: self.suggestions(),
})
Expand All @@ -540,7 +555,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument,
suggestions: self.suggestions(),
})
Expand All @@ -556,7 +572,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
possibilities,
strings: false,
Expand All @@ -577,7 +594,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
possibilities,
strings: false,
Expand All @@ -597,7 +615,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
span,
attr_span: self.attr_span,
template: self.template.clone(),
attribute: self.attr_path.clone(),
path: self.attr_path.clone(),
description: self.parsed_description,
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
possibilities,
strings: true,
Expand Down
Loading
Loading