Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f943606
Fix unused_assignments false positives from macros
chenyukang Nov 20, 2025
5009847
std: don't call `current_os_id` from signal handler
joboet Sep 17, 2025
9549166
add test
lcnr Dec 1, 2025
02d84c8
generic normalization errors to `TooGeneric`
lcnr Dec 1, 2025
3f1aa0b
Additional test for uN::{gather,scatter}_bits
quaternic Dec 1, 2025
7922479
Regression tests for system register `ttbr0_el2`
Jamesbarford Dec 2, 2025
85b6c38
remember the main thread ID before performing platform initialisation
joboet Dec 1, 2025
f4729f2
build-manifest: generate MSI and MINGW arrays from rustc
mati865 Dec 2, 2025
f8ca417
reword error for invalid range patterns
fee1-dead Dec 2, 2025
f49eaec
reorganize test contents and adjust generated inputs to reduce iterat…
quaternic Dec 3, 2025
fc017dd
c-variadic: bpf and spirv do not support c-variadic definitions
folkertdev Dec 3, 2025
b3bf315
Disable native-lib for x check miri
bjorn3 Dec 2, 2025
46d8ade
Use TypingEnv::fully_monomorphized for evaluating const without gener…
tiif Nov 21, 2025
af66b68
refactor: make the match exhaustive
tiif Nov 21, 2025
1864bf6
ICE when applying test to crate root
jdonszelmann Oct 18, 2025
9dd3cae
only discard items with `#[test]` on it when target is valid
jdonszelmann Oct 18, 2025
97d4d21
fixup name in diagnostics
jdonszelmann Oct 18, 2025
8f82478
address review comments
jdonszelmann Dec 3, 2025
876c1c9
Unify my name in the mailmap
blyxyas Dec 2, 2025
5019bda
Rollup merge of #147841 - jdonszelmann:test-macro-ice, r=wafflelapkin
matthiaskrgr Dec 4, 2025
82a17b3
Rollup merge of #149147 - chenyukang:yukang-fix-unused_assignments-ma…
matthiaskrgr Dec 4, 2025
bea2f89
Rollup merge of #149183 - tiif:typing_env_fix, r=BoxyUwU
matthiaskrgr Dec 4, 2025
08a5519
Rollup merge of #149456 - joboet:async-safe-tid, r=Mark-Simulacrum
matthiaskrgr Dec 4, 2025
40c97a9
Rollup merge of #149501 - lcnr:no-hard-error-on-norm-failure, r=lqd,o…
matthiaskrgr Dec 4, 2025
420ef95
Rollup merge of #149528 - fee1-dead-contrib:rangeboundreword, r=jieyouxu
matthiaskrgr Dec 4, 2025
8fe1225
Rollup merge of #149539 - quaternic:gather-scatter-bits, r=Mark-Simul…
matthiaskrgr Dec 4, 2025
05b2958
Rollup merge of #149549 - Jamesbarford:chore/regression-test-ttbr0_el…
matthiaskrgr Dec 4, 2025
5105c4f
Rollup merge of #149550 - bjorn3:faster_compile_time_deps, r=RalfJung
matthiaskrgr Dec 4, 2025
b63ef74
Rollup merge of #149554 - mati865:build-manifest-more-gen, r=Mark-Sim…
matthiaskrgr Dec 4, 2025
62a42e8
Rollup merge of #149557 - folkertdev:c-variadic-not-supported, r=work…
matthiaskrgr Dec 4, 2025
eeff7ad
Rollup merge of #149569 - blyxyas:mailmap, r=Mark-Simulacrum
matthiaskrgr Dec 4, 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
5 changes: 4 additions & 1 deletion .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Andre Bogus <bogusandre@gmail.com>
Andre Bogus <bogusandre@gmail.com> <andre.bogus@aleph-alpha.de>
Andre Bogus <bogusandre@gmail.com> <andre.bogus@ankordata.de>
Andrea Ciliberti <meziu210@icloud.com>

Andreas Gal <gal@mozilla.com> <andreas.gal@gmail.com>
Andreas Jonson <andjo403@users.noreply.github.com>
Andrew Gauger <andygauge@gmail.com>
Expand Down Expand Up @@ -87,7 +88,9 @@ bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3@users.noreply.github.c
bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3_gh@protonmail.com>
Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de>
blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc>
blyxyas <blyxyas@gmail.com> Alejandra González <blyxyas@gmail.com>
Alejandra González <blyxyas@goose.love> blyxyas <blyxyas@gmail.com>
Alejandra González <blyxyas@goose.love> blyxyas <blyxyas@goose.love>
Alejandra González <blyxyas@goose.love> Alejandra González <blyxyas@gmail.com>
boolean_coercion <booleancoercion@gmail.com>
Boris Egorov <jightuse@gmail.com> <egorov@linux.com>
bors <bors@rust-lang.org> bors[bot] <26634292+bors[bot]@users.noreply.github.com>
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_ast_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ ast_passes_c_variadic_must_be_unsafe =
ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
ast_passes_c_variadic_not_supported = the `{$target}` target does not support c-variadic functions
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
.const = `const` because of this
.variadic = C-variadic because of this
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,14 @@ impl<'a> AstValidator<'a> {
match fn_ctxt {
FnCtxt::Foreign => return,
FnCtxt::Free | FnCtxt::Assoc(_) => {
if !self.sess.target.arch.supports_c_variadic_definitions() {
self.dcx().emit_err(errors::CVariadicNotSupported {
variadic_span: variadic_param.span,
target: &*self.sess.target.llvm_target,
});
return;
}

match sig.header.ext {
Extern::Implicit(_) => {
if !matches!(sig.header.safety, Safety::Unsafe(_)) {
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,14 @@ pub(crate) struct CoroutineAndCVariadic {
pub variadic_span: Span,
}

#[derive(Diagnostic)]
#[diag(ast_passes_c_variadic_not_supported)]
pub(crate) struct CVariadicNotSupported<'a> {
#[primary_span]
pub variadic_span: Span,
pub target: &'a str,
}

#[derive(Diagnostic)]
#[diag(ast_passes_pattern_in_foreign, code = E0130)]
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
Expand Down
39 changes: 22 additions & 17 deletions compiler/rustc_builtin_macros/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ pub(crate) fn expand_test_case(
check_builtin_macro_attribute(ecx, meta_item, sym::test_case);
warn_on_duplicate_attribute(ecx, &anno_item, sym::test_case);

if !ecx.ecfg.should_test {
return vec![];
}

let sp = ecx.with_def_site_ctxt(attr_sp);
let (mut item, is_stmt) = match anno_item {
Annotatable::Item(item) => (item, false),
Expand All @@ -54,6 +50,10 @@ pub(crate) fn expand_test_case(
}
};

if !ecx.ecfg.should_test {
return vec![];
}

// `#[test_case]` is valid on functions, consts, and statics. Only modify
// the item in those cases.
match &mut item.kind {
Expand Down Expand Up @@ -113,29 +113,29 @@ pub(crate) fn expand_test_or_bench(
item: Annotatable,
is_bench: bool,
) -> Vec<Annotatable> {
// If we're not in test configuration, remove the annotated item
if !cx.ecfg.should_test {
return vec![];
}

let (item, is_stmt) = match item {
Annotatable::Item(i) => (i, false),
Annotatable::Stmt(box ast::Stmt { kind: ast::StmtKind::Item(i), .. }) => (i, true),
other => {
not_testable_error(cx, attr_sp, None);
not_testable_error(cx, is_bench, attr_sp, None);
return vec![other];
}
};

let ast::ItemKind::Fn(fn_) = &item.kind else {
not_testable_error(cx, attr_sp, Some(&item));
not_testable_error(cx, is_bench, attr_sp, Some(&item));
return if is_stmt {
vec![Annotatable::Stmt(Box::new(cx.stmt_item(item.span, item)))]
} else {
vec![Annotatable::Item(item)]
};
};

// If we're not in test configuration, remove the annotated item
if !cx.ecfg.should_test {
return vec![];
}

if let Some(attr) = attr::find_by_name(&item.attrs, sym::naked) {
cx.dcx().emit_err(errors::NakedFunctionTestingAttribute {
testing_span: attr_sp,
Expand Down Expand Up @@ -405,9 +405,10 @@ pub(crate) fn expand_test_or_bench(
}
}

fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) {
fn not_testable_error(cx: &ExtCtxt<'_>, is_bench: bool, attr_sp: Span, item: Option<&ast::Item>) {
let dcx = cx.dcx();
let msg = "the `#[test]` attribute may only be used on a non-associated function";
let name = if is_bench { "bench" } else { "test" };
let msg = format!("the `#[{name}]` attribute may only be used on a free function");
let level = match item.map(|i| &i.kind) {
// These were a warning before #92959 and need to continue being that to avoid breaking
// stable user code (#94508).
Expand All @@ -426,12 +427,16 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
),
);
}
err.with_span_label(attr_sp, "the `#[test]` macro causes a function to be run as a test and has no effect on non-functions")
.with_span_suggestion(attr_sp,
err.span_label(attr_sp, format!("the `#[{name}]` macro causes a function to be run as a test and has no effect on non-functions"));

if !is_bench {
err.with_span_suggestion(attr_sp,
"replace with conditional compilation to make the item only exist when tests are being run",
"#[cfg(test)]",
Applicability::MaybeIncorrect)
.emit();
Applicability::MaybeIncorrect).emit();
} else {
err.emit();
}
}

fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, usize, usize) {
Expand Down
29 changes: 26 additions & 3 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf,
LayoutOfHelpers, TyAndLayout,
};
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance};
use rustc_middle::ty::{
self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingEnv, Variance,
};
use rustc_middle::{mir, span_bug};
use rustc_span::Span;
use rustc_target::callconv::FnAbi;
Expand Down Expand Up @@ -84,10 +86,31 @@ impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> {
#[inline]
fn handle_layout_err(
&self,
err: LayoutError<'tcx>,
mut err: LayoutError<'tcx>,
_: Span,
_: Ty<'tcx>,
) -> InterpErrorKind<'tcx> {
// FIXME(#149283): This is really hacky and is only used to hide type
// system bugs. We use it as a temporary fix for #149081.
//
// While it's expected that we sometimes get ambiguity errors when
// entering another generic environment while the current environment
// itself is still generic, we should never fail to entirely prove
// something.
match err {
LayoutError::NormalizationFailure(ty, _) => {
if ty.has_non_region_param() {
err = LayoutError::TooGeneric(ty);
}
}

LayoutError::Unknown(_)
| LayoutError::SizeOverflow(_)
| LayoutError::InvalidSimd { .. }
| LayoutError::TooGeneric(_)
| LayoutError::ReferencesError(_)
| LayoutError::Cycle(_) => {}
}
err_inval!(Layout(err))
}
}
Expand All @@ -112,7 +135,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span.
/// See [LayoutOf::layout_of] for the original documentation.
#[inline(always)]
pub fn layout_of(&self, ty: Ty<'tcx>) -> <Self as LayoutOfHelpers<'tcx>>::LayoutOfResult {
pub fn layout_of(&self, ty: Ty<'tcx>) -> Result<TyAndLayout<'tcx>, InterpErrorKind<'tcx>> {
let _trace = enter_trace_span!(M, layouting::layout_of, ty = ?ty.kind());
LayoutOf::layout_of(self, ty)
}
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,11 @@ mir_build_loop_match_unsupported_type =
.note = only integers, floats, bool, char, and enums without fields are supported
mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper =
lower range bound must be less than or equal to upper
lower bound for range pattern must be less than or equal to upper bound
.label = lower bound larger than upper bound
.teach_note = When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range.
mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper
mir_build_lower_range_bound_must_be_less_than_upper = lower bound for range pattern must be less than upper bound
mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
Expand Down Expand Up @@ -506,6 +506,8 @@ mir_build_unused_unsafe = unnecessary `unsafe` block
mir_build_unused_unsafe_enclosing_block_label = because it's nested under this `unsafe` block
mir_build_upper_range_bound_cannot_be_min = exclusive upper bound for a range bound cannot be the minimum
mir_build_variant_defined_here = not covered
mir_build_wrap_suggestion = consider wrapping the function body in an unsafe block
7 changes: 7 additions & 0 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,13 @@ pub(crate) struct LowerRangeBoundMustBeLessThanUpper {
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(mir_build_upper_range_bound_cannot_be_min, code = E0579)]
pub(crate) struct UpperRangeBoundCannotBeMin {
#[primary_span]
pub(crate) span: Span,
}

#[derive(LintDiagnostic)]
#[diag(mir_build_leading_irrefutable_let_patterns)]
#[note]
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
teach: self.tcx.sess.teach(E0030),
})
}
RangeEnd::Excluded if lo_expr.is_none() => {
self.tcx.dcx().emit_err(UpperRangeBoundCannotBeMin { span })
}
RangeEnd::Excluded => {
self.tcx.dcx().emit_err(LowerRangeBoundMustBeLessThanUpper { span })
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_mir_transform/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den
return DenseBitSet::new_empty(0);
}

// Don't run unused pass for items generated by foreign macros
if tcx.def_span(parent).in_external_macro(tcx.sess.source_map()) {
return DenseBitSet::new_empty(0);
}

let mut body = &*tcx.mir_promoted(def_id).0.borrow();
let mut body_mem;

Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1925,6 +1925,24 @@ impl Arch {
Self::Other(name) => rustc_span::Symbol::intern(name),
}
}

pub fn supports_c_variadic_definitions(&self) -> bool {
use Arch::*;

match self {
// These targets just do not support c-variadic definitions.
Bpf | SpirV => false,

// We don't know if the target supports c-variadic definitions, but we don't want
// to needlessly restrict custom target.json configurations.
Other(_) => true,

AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64
| M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC
| PowerPC64 | PowerPC64LE | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32
| Wasm64 | X86 | X86_64 | Xtensa => true,
}
}
}

crate::target_spec_enum! {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ pub fn try_evaluate_const<'tcx>(

(args, typing_env)
}
_ => {
Some(ty::AnonConstKind::MCG) | Some(ty::AnonConstKind::NonTypeSystem) | None => {
// We are only dealing with "truly" generic/uninferred constants here:
// - GCEConsts have been handled separately
// - Repeat expr count back compat consts have also been handled separately
Expand All @@ -700,7 +700,7 @@ pub fn try_evaluate_const<'tcx>(

// Since there is no generic parameter, we can just drop the environment
// to prevent query cycle.
let typing_env = infcx.typing_env(ty::ParamEnv::empty());
let typing_env = ty::TypingEnv::fully_monomorphized();

(uv.args, typing_env)
}
Expand Down
62 changes: 62 additions & 0 deletions library/coretests/tests/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,68 @@ macro_rules! uint_module {
}
}

#[cfg(not(miri))] // Miri is too slow
#[test]
fn test_lots_of_gather_scatter() {
// Generate a handful of bit patterns to use as inputs
let xs = {
let mut xs = vec![];
let mut x: $T = !0;
let mut w = $T::BITS;
while w > 0 {
w >>= 1;
xs.push(x);
xs.push(!x);
x ^= x << w;
}
xs
};
if $T::BITS == 8 {
assert_eq!(&xs, &[0xff, 0x00, 0x0f, 0xf0, 0x33, 0xcc, 0x55, 0xaa]);
}

// `256 * (BITS / 5)` masks
let sparse_masks = (i8::MIN..=i8::MAX)
.map(|i| (i as i128 as $T).rotate_right(4))
.flat_map(|x| (0..$T::BITS).step_by(5).map(move |r| x.rotate_right(r)));

for sparse in sparse_masks {
// Collect the set bits to sequential low bits
let dense = sparse.gather_bits(sparse);
let count = sparse.count_ones();
assert_eq!(count, dense.count_ones());
assert_eq!(count, dense.trailing_ones());

// Check that each bit is individually mapped correctly
let mut t = sparse;
let mut bit = 1 as $T;
for _ in 0..count {
let lowest_one = t.isolate_lowest_one();
assert_eq!(lowest_one, bit.scatter_bits(sparse));
assert_eq!(bit, lowest_one.gather_bits(sparse));
t ^= lowest_one;
bit <<= 1;
}
// Other bits are ignored
assert_eq!(0, bit.wrapping_neg().scatter_bits(sparse));
assert_eq!(0, (!sparse).gather_bits(sparse));

for &x in &xs {
// Gather bits from `x & sparse` to `dense`
let dx = x.gather_bits(sparse);
assert_eq!(dx & !dense, 0);

// Scatter bits from `x & dense` to `sparse`
let sx = x.scatter_bits(sparse);
assert_eq!(sx & !sparse, 0);

// The other recovers the input (within the mask)
assert_eq!(dx.scatter_bits(sparse), x & sparse);
assert_eq!(sx.gather_bits(sparse), x & dense);
}
}
}

test_runtime_and_compiletime! {
fn test_div_floor() {
assert_eq_const_safe!($T: (8 as $T).div_floor(3), 2);
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ fn handle_rt_panic<T>(e: Box<dyn Any + Send>) -> T {
// `compiler/rustc_session/src/config/sigpipe.rs`.
#[cfg_attr(test, allow(dead_code))]
unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
// Remember the main thread ID to give it the correct name.
// SAFETY: this is the only time and place where we call this function.
unsafe { main_thread::set(thread::current_id()) };

#[cfg_attr(target_os = "teeos", allow(unused_unsafe))]
unsafe {
sys::init(argc, argv, sigpipe)
};

// Remember the main thread ID to give it the correct name.
// SAFETY: this is the only time and place where we call this function.
unsafe { main_thread::set(thread::current_id()) };
}

/// Clean up the thread-local runtime state. This *should* be run after all other
Expand Down
Loading
Loading