Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b32b841
lint against repeated repr attributes
ettolrach Aug 24, 2026
a2f1460
Fix broken link to lang_items.rs in unstable book
Wilfred Aug 24, 2026
dcf82c1
Add test demonstrating a wasm32-unknown-unknown target feature/cfg bug
nnethercote Aug 25, 2026
e45b83a
Do more in `parse_cfg`/`parse_check_cfg`
nnethercote Aug 25, 2026
45c4d9c
Simplify `add_configuration`
nnethercote Aug 25, 2026
62578df
Fix the wasm32-unknown-unknown target feature/cfg bug
nnethercote Aug 25, 2026
ad2aa1c
Remove `RawDefPathHash`
nnethercote Aug 25, 2026
57bb4d1
explicitly state that allocations cannot grow to the left
RalfJung Aug 25, 2026
4339216
panic_unwind: Use global_asm! for IMGREL relocations
Darksonn Jul 29, 2026
1b2470e
bring back warns for repeated reprs, update tests
ettolrach Aug 24, 2026
6423eed
finish rewording lint messages
ettolrach Aug 24, 2026
deb8160
add another test
ettolrach Aug 24, 2026
4f5002d
also warn on repeated int reprs
ettolrach Aug 24, 2026
819099b
use sort/chunk_by to find repeated reprs
ettolrach Aug 24, 2026
e99f23f
add to unused group
ettolrach Aug 24, 2026
8de399a
Remove dead parse error recovery (underscores in expressions)
fmease Aug 26, 2026
0230abe
Rollup merge of #157036 - ettolrach:disallow-repeated-reprs, r=jdonsz…
JonathanBrouwer Aug 26, 2026
c00735c
Rollup merge of #160183 - Darksonn:seh-imgrel, r=Mark-Simulacrum
JonathanBrouwer Aug 26, 2026
abfd8e5
Rollup merge of #161718 - nnethercote:parse_cfg-stuff, r=Urgau
JonathanBrouwer Aug 26, 2026
aec7c2a
Rollup merge of #161673 - Wilfred:patch-4, r=ShoyuVanilla
JonathanBrouwer Aug 26, 2026
2e33de1
Rollup merge of #161744 - nnethercote:rm-RawDefPathHash, r=fee1-dead
JonathanBrouwer Aug 26, 2026
3657478
Rollup merge of #161747 - RalfJung:alloc-growth, r=saethlin
JonathanBrouwer Aug 26, 2026
0ae3fd9
Rollup merge of #161796 - fmease:rm-dead-underscore-recovery, r=mu001999
JonathanBrouwer Aug 26, 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
16 changes: 14 additions & 2 deletions compiler/rustc_attr_ir/src/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,19 @@ impl OptimizeAttr {
}
}

#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, StableHash, PrintAttribute)]
#[derive(
PartialEq,
Eq,
Debug,
PartialOrd,
Ord,
Encodable,
Decodable,
Copy,
Clone,
StableHash,
PrintAttribute
)]
pub enum ReprAttr {
ReprInt(IntType),
ReprRust,
Expand All @@ -188,7 +200,7 @@ pub enum TransparencyError {
MultipleTransparencyAttrs(Span, Span),
}

#[derive(Eq, PartialEq, Debug, Copy, Clone)]
#[derive(Eq, PartialEq, Debug, Copy, Clone, PartialOrd, Ord)]
#[derive(Encodable, Decodable, StableHash, PrintAttribute)]
pub enum IntType {
SignedInt(ast::IntTy),
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_data_structures/src/stable_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use rustc_index::{Idx, IndexSlice, IndexVec};
use smallvec::SmallVec;
use thin_vec::ThinVec;

use crate::fingerprint::Fingerprint;

#[cfg(test)]
mod tests;

Expand All @@ -24,8 +26,8 @@ pub trait StableHashCtxt {
/// The main event: stable hashing of a span.
fn stable_hash_span(&mut self, span: RawSpan, hasher: &mut StableHasher);

/// Compute a `DefPathHash`.
fn def_path_hash(&self, def_id: RawDefId) -> RawDefPathHash;
/// Compute a `Fingerprint`, which can be trivially turned into a `DefPathHash`.
fn def_path_hash(&self, def_id: RawDefId) -> Fingerprint;

/// Get the stable hash controls.
fn stable_hash_controls(&self) -> StableHashControls;
Expand All @@ -43,10 +45,6 @@ pub struct RawSpan(pub u32, pub u16, pub u16);
// `DefId`.
pub struct RawDefId(pub u32, pub u32);

// A type used to work around `DefPathHash` not being visible in this crate. It is the same size as
// `DefPathHash`.
pub struct RawDefPathHash(pub [u8; 16]);

/// Something that implements `StableHash` can be hashed in a way that is
/// stable across multiple compilation sessions.
///
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/stable_hash/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl StableHashCtxt for () {
fn stable_hash_span(&mut self, _: RawSpan, _: &mut StableHasher) {
panic!();
}
fn def_path_hash(&self, _: RawDefId) -> RawDefPathHash {
fn def_path_hash(&self, _: RawDefId) -> Fingerprint {
panic!();
}
fn stable_hash_controls(&self) -> StableHashControls {
Expand Down
46 changes: 32 additions & 14 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ pub struct Compiler {
}

/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {
cfgs.into_iter()
pub(crate) fn parse_cfg(sess: &Session, cfgs: Vec<String>) -> Cfg {
let cfg = cfgs
.into_iter()
.map(|s| {
let psess = ParseSess::emitter_with_note(format!(
"this occurred on the command line: `--cfg={s}`"
Expand All @@ -54,7 +55,7 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {

macro_rules! error {
($reason: expr) => {
dcx.fatal(format!("invalid `--cfg` argument: `{s}` ({})", $reason));
sess.dcx().fatal(format!("invalid `--cfg` argument: `{s}` ({})", $reason));
};
}

Expand Down Expand Up @@ -106,11 +107,13 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {
error!(r#"expected `key` or `key="value"`"#);
}
})
.collect::<Cfg>()
.collect::<Cfg>();

config::build_configuration(sess, cfg)
}

/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> CheckCfg {
pub(crate) fn parse_check_cfg(sess: &Session, specs: Vec<String>) -> CheckCfg {
// If any --check-cfg is passed then exhaustive_values and exhaustive_names
// are enabled by default.
let exhaustive_names = !specs.is_empty();
Expand All @@ -128,13 +131,15 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch

macro_rules! error {
($reason:expr) => {{
let mut diag = dcx.struct_fatal(format!("invalid `--check-cfg` argument: `{s}`"));
let mut diag =
sess.dcx().struct_fatal(format!("invalid `--check-cfg` argument: `{s}`"));
diag.note($reason);
diag.note(VISIT);
diag.emit()
}};
(in $arg:expr, $reason:expr) => {{
let mut diag = dcx.struct_fatal(format!("invalid `--check-cfg` argument: `{s}`"));
let mut diag =
sess.dcx().struct_fatal(format!("invalid `--check-cfg` argument: `{s}`"));

let pparg = rustc_ast_pretty::pprust::meta_list_item_to_string($arg);
if let Some(lit) = $arg.lit() {
Expand Down Expand Up @@ -304,6 +309,8 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch
}
}

check_cfg.fill_well_known(&sess.target);

check_cfg
}

Expand Down Expand Up @@ -443,14 +450,25 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
sess.fallback_intrinsics = FxHashSet::from_iter(codegen_backend.fallback_intrinsics());
sess.thin_lto_supported = codegen_backend.thin_lto_supported();

let cfg = parse_cfg(sess.dcx(), config.crate_cfg);
let mut cfg = config::build_configuration(&sess, cfg);
util::add_configuration(&mut cfg, &mut sess, &*codegen_backend);
sess.config = cfg;
let target_config = codegen_backend.target_config(&sess);

// Store all of the target features in the session.
// Needs to be done before `parse_cfg` because it checks this list.
sess.internal_target_features
.extend(target_config.internal_target_features.to_sorted_stable_ord());

sess.config = parse_cfg(&sess, config.crate_cfg);
let is_nightly_build = sess.is_nightly_build();
let is_crt_static = sess.crt_static(None);
util::add_configuration(
&mut sess.config,
&target_config,
&sess.target,
is_nightly_build,
is_crt_static,
);

let mut check_cfg = parse_check_cfg(sess.dcx(), config.crate_check_cfg);
check_cfg.fill_well_known(&sess.target);
sess.check_config = check_cfg;
sess.check_config = parse_check_cfg(&sess, config.crate_check_cfg);

if let Some(psess_created) = config.psess_created {
psess_created(&mut sess.psess);
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_session::config::{
LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, Offload, Options,
OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry,
Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion,
WasiExecModel, build_configuration, build_session_options, rustc_optgroups,
WasiExecModel, build_session_options, rustc_optgroups,
};
use rustc_session::search_paths::SearchPath;
use rustc_session::utils::{CanonicalizedPath, NativeLib};
Expand Down Expand Up @@ -75,8 +75,7 @@ where
None,
&USING_INTERNAL_FEATURES,
);
let cfg = parse_cfg(sess.dcx(), matches.opt_strs("cfg"));
let cfg = build_configuration(&sess, cfg);
let cfg = parse_cfg(&sess, matches.opt_strs("cfg"));
f(sess, cfg)
});
}
Expand Down
33 changes: 14 additions & 19 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,52 +42,47 @@ type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
/// specific features (SSE, NEON etc.).
///
/// This is performed by checking whether a set of permitted features
/// is available on the target machine, by querying the codegen backend.
/// is available on the target machine, by querying the `TargetConfig` from the codegen backend.
pub(crate) fn add_configuration(
cfg: &mut Cfg,
sess: &mut Session,
codegen_backend: &dyn CodegenBackend,
target_config: &TargetConfig,
target: &Target,
is_nightly_build: bool,
is_crt_static: bool,
) {
let tf = sym::target_feature;
let tf_cfg = codegen_backend.target_config(sess);

// Add some of the target features to `cfg`.
cfg.extend(
sess.target
target
.rust_target_features()
.iter()
.filter_map(|(feature, gate, _)| {
if gate.in_cfg()
&& (sess.is_nightly_build()
|| gate.requires_nightly(/* in_cfg */ true).is_none())
&& (is_nightly_build || gate.requires_nightly(/* in_cfg */ true).is_none())
{
Some(Symbol::intern(feature))
} else {
None
}
})
.filter(|feature| tf_cfg.internal_target_features.contains(&feature))
.filter(|feature| target_config.internal_target_features.contains(&feature))
.map(|feature| (sym::target_feature, Some(feature))),
);

// Store all of them in the session.
sess.internal_target_features.extend(tf_cfg.internal_target_features.into_sorted_stable_ord());

if tf_cfg.has_reliable_f16 {
if target_config.has_reliable_f16 {
cfg.insert((sym::target_has_reliable_f16, None));
}
if tf_cfg.has_reliable_f16_math {
if target_config.has_reliable_f16_math {
cfg.insert((sym::target_has_reliable_f16_math, None));
}
if tf_cfg.has_reliable_f128 {
if target_config.has_reliable_f128 {
cfg.insert((sym::target_has_reliable_f128, None));
}
if tf_cfg.has_reliable_f128_math {
if target_config.has_reliable_f128_math {
cfg.insert((sym::target_has_reliable_f128_math, None));
}

if sess.crt_static(None) {
cfg.insert((tf, Some(sym::crt_dash_static)));
if is_crt_static {
cfg.insert((sym::target_feature, Some(sym::crt_dash_static)));
}
}

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,8 @@ fn register_builtins(store: &mut LintStore) {
UNUSED_PARENS,
UNUSED_BRACES,
REDUNDANT_SEMICOLONS,
MAP_UNIT_FN
MAP_UNIT_FN,
REPEATED_REPRS
);

add_lint_group!("let_underscore", LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK);
Expand Down
25 changes: 25 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pub mod hardwired {
REFINING_IMPL_TRAIT_INTERNAL,
REFINING_IMPL_TRAIT_REACHABLE,
RENAMED_AND_REMOVED_LINTS,
REPEATED_REPRS,
REPR_C_ENUMS_LARGER_THAN_INT,
RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS,
RTSAN_NONBLOCKING_ASYNC,
Expand Down Expand Up @@ -276,6 +277,30 @@ declare_lint! {
};
}

declare_lint! {
/// The `repeated_reprs` lint detects when the same representation is
/// specified more than once in a `#[repr(..)]` attribute.
///
/// ### Example
///
/// ```rust
/// #[repr(C)]
/// #[repr(C)]
/// enum Foo { A }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// While some representations may be specified more than once, the compiler
/// will reject repeated uses of some others. For consistency, prefer to
/// only specify the representation once.
pub REPEATED_REPRS,
Warn,
"detects repeated representations in `#[repr(..)]` attributes",
}

declare_lint! {
/// The `meta_variable_misuse` lint detects possible meta-variable misuse
/// in macro definitions.
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_middle/src/ich.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::hash::Hash;

use rustc_crate_store::Untracked;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hash::{
RawDefId, RawDefPathHash, RawSpan, StableHash, StableHashControls, StableHashCtxt, StableHasher,
RawDefId, RawSpan, StableHash, StableHashControls, StableHashCtxt, StableHasher,
};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_session::Session;
Expand Down Expand Up @@ -159,14 +160,14 @@ impl<'a> StableHashCtxt for StableHashState<'a> {
}

#[inline]
fn def_path_hash(&self, raw_def_id: RawDefId) -> RawDefPathHash {
fn def_path_hash(&self, raw_def_id: RawDefId) -> Fingerprint {
let def_id = DefId::from_raw_def_id(raw_def_id);
if let Some(def_id) = def_id.as_local() {
self.untracked.definitions.read().def_path_hash(def_id)
} else {
self.untracked.cstore.read().def_path_hash(def_id)
}
.to_raw_def_path_hash()
.0
}

/// Assert that the provided `StableHashCtxt` is configured with the default
Expand Down
25 changes: 2 additions & 23 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,30 +85,9 @@ impl<'a> Parser<'a> {
self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value })
}

fn parse_expr_catch_underscore(
&mut self,
restrictions: Restrictions,
) -> PResult<'a, Box<Expr>> {
match self.parse_expr_res(restrictions) {
Ok(expr) => Ok(expr),
Err(err) => match self.token.ident() {
Some((Ident { name: kw::Underscore, .. }, IdentIsRaw::No))
if self.may_recover() && self.look_ahead(1, |t| t == &token::Comma) =>
{
// Special-case handling of `foo(_, _, _)`
let guar = err.emit();
self.bump();
Ok(self.mk_expr(self.prev_token.span, ExprKind::Err(guar)))
}
_ => Err(err),
},
}
}

/// Parses a sequence of expressions delimited by parentheses.
fn parse_expr_paren_seq(&mut self) -> PResult<'a, ThinVec<Box<Expr>>> {
self.parse_paren_comma_seq(|p| p.parse_expr_catch_underscore(Restrictions::empty()))
.map(|(r, _)| r)
self.parse_paren_comma_seq(Self::parse_expr).map(|(r, _)| r)
}

/// Parses an expression, subject to the given restrictions.
Expand Down Expand Up @@ -1644,7 +1623,7 @@ impl<'a> Parser<'a> {
let (es, trailing_comma) = match self.parse_seq_to_end(
exp!(CloseParen),
SeqSep::trailing_allowed(exp!(Comma)),
|p| p.parse_expr_catch_underscore(restrictions.intersection(Restrictions::ALLOW_LET)),
|p| p.parse_expr_res(restrictions.intersection(Restrictions::ALLOW_LET)),
) {
Ok(x) => x,
Err(err) => {
Expand Down
Loading
Loading