From dd55e995f91b709daa5e11609c72f3110b8c6821 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Thu, 17 Sep 2026 11:03:37 -0300 Subject: [PATCH 01/14] Add regression test for ambiguous trait with mixed import ids Co-authored-by: Philip Sampaio (cherry picked from commit e9a87d0f7bcc2e6fc2ab2f687e2e6e2c1697fa49) --- ...ambiguous-trait-with-mixed-import-paths.rs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs diff --git a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs new file mode 100644 index 0000000000000..acc97a2491f8e --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs @@ -0,0 +1,27 @@ +//! Regression test for . +//@ check-pass + +mod vis1 { + pub trait Visitor { + fn visit_b(&self); + fn visit_c(&self); + } +} + +mod vis2 { + pub trait Visitor {} +} + +use crate::{vis1::*, vis2::*}; + +pub struct Impl; + +impl vis1::Visitor for Impl { + fn visit_b(&self) {} + + fn visit_c(&self) { + self.visit_b(); + } +} + +fn main() {} From 2ae056bbe25b5c9399bb67cac588f3598f298e11 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Thu, 17 Sep 2026 10:55:08 -0300 Subject: [PATCH 02/14] Fix ICE for ambiguous candidates on method probing The ICE was caused because the code assumed the import_ids would always be the same for all candidates, but it's not true. Sometimes the candidate is ambiguous with import_ids to be logged and sometimes the candidate is not ambigous and does not have the ids. Mixing the two (flag = true, without import_ids) ICEs. Co-authored-by: Philip Sampaio (cherry picked from commit 109c9176424c1b03e00db6ee5a1b6cc2100c061c) --- compiler/rustc_hir_typeck/src/method/probe.rs | 16 ++++++++++------ .../ambiguous-trait-with-mixed-import-paths.rs | 2 ++ ...mbiguous-trait-with-mixed-import-paths.stderr | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 58e482adff190..d5c8cb90c1623 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2382,18 +2382,22 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - // They are all the same, so if any of them is ambiguous, we report the pick as ambiguous. - let is_ambiguously_imported = probes.iter().any(|(p, _)| match p.kind { - TraitCandidate { is_ambiguously_imported, .. } => is_ambiguously_imported, - _ => false, + // We try and find the ambiguous candidate in order to report the pick as ambiguous. + let ambiguous_candidate = probes.iter().find_map(|(p, _)| match p.kind { + TraitCandidate { is_ambiguously_imported: true, .. } => Some(p), + _ => None, }); + // If there isn't any, then we just use the first probe. + let (is_ambiguously_imported, candidate) = + ambiguous_candidate.map(|c| (true, *c)).unwrap_or_else(|| (false, probes[0].0)); + // FIXME: check the return type here somehow. // If so, just use this trait and call it a day. Some(Pick { - item: probes[0].0.item, + item: candidate.item, kind: TraitPick { is_ambiguously_imported }, - import_ids: probes[0].0.import_ids, + import_ids: candidate.import_ids, autoderefs: 0, autoref_or_ptr_adjustment: None, self_ty, diff --git a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs index acc97a2491f8e..08f57d7feb7a3 100644 --- a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs +++ b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs @@ -21,6 +21,8 @@ impl vis1::Visitor for Impl { fn visit_c(&self) { self.visit_b(); + //~^ WARN: use of ambiguously glob imported trait `Visitor` [ambiguous_glob_imported_traits] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } } diff --git a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr new file mode 100644 index 0000000000000..d65f941f03671 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr @@ -0,0 +1,16 @@ +warning: use of ambiguously glob imported trait `Visitor` + --> $DIR/ambiguous-trait-with-mixed-import-paths.rs:23:14 + | +LL | use crate::{vis1::*, vis2::*}; + | ---- `Visitor` imported ambiguously here +... +LL | self.visit_b(); + | ^^^^^^^ + | + = help: import `Visitor` explicitly + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #152822 + = note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + From 07da0337e1c04874c456412ecb004d0a8b46098f Mon Sep 17 00:00:00 2001 From: Max Dexheimer Date: Fri, 25 Sep 2026 18:01:50 +0200 Subject: [PATCH 03/14] Don't imply incorrect things about `Global` in the docs of `System` (cherry picked from commit 9379da62b25d050b6aeb8caa80cea550e9e68635) --- library/std/src/alloc.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index fa977d16e2311..51f57db3d627d 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -102,8 +102,14 @@ use crate::{hint, mem, ptr}; /// } /// ``` /// +/// Note that this does *not* mean you can deallocate allocations from [`Global`] +/// with [`System`] (or vice-versa), as the [`Global`] allocator is special in +/// the compiler. For more details, see the relevant docs about +/// [`#[global_allocator]`][global_allocator]. +/// /// You can also define your own wrapper around `System` if you'd like, such as -/// keeping track of the number of all bytes allocated: +/// keeping track of the number of all bytes allocated (note that due to +/// optimizations, this may not be accurate): /// /// ```rust /// use std::alloc::{System, GlobalAlloc, Layout}; @@ -140,6 +146,8 @@ use crate::{hint, mem, ptr}; /// global allocator has been selected for a Rust program. For example if a Rust /// program opts in to using jemalloc as the global allocator, `System` will /// still allocate memory using `malloc` and `HeapAlloc`. +/// +/// [global_allocator]: GlobalAlloc#the-global_allocator-attribute #[stable(feature = "alloc_system_type", since = "1.28.0")] #[derive(Copy, Debug)] #[derive_const(Clone, Default)] From 3bd7095d9eb31e82687efa3d9a1e88423509cf25 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 14 Sep 2026 14:53:57 +0200 Subject: [PATCH 04/14] make semicolon_in_expressions_from_non_local_macros not report-in-deps (cherry picked from commit 3631ff3d02d9278a1bf878f0ed94be226833ed63) --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- .../foreign-crate.stderr | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2a0901e0243b6..22eb1471bd572 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3024,7 +3024,7 @@ declare_lint! { "trailing semicolon in macro body used as expression", @future_incompatible = FutureIncompatibleInfo { reason: fcw!(FutureReleaseError #79813), - report_in_deps: true, + report_in_deps: false, }; } diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.stderr b/tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.stderr index b335df57496ef..9414364bfa6d9 100644 --- a/tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.stderr +++ b/tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.stderr @@ -15,19 +15,3 @@ LL | #![deny(semicolon_in_expressions_from_non_local_macros)] error: aborting due to 1 previous error -Future incompatibility report: Future breakage diagnostic: -error: trailing semicolon in macro used in expression position - --> $DIR/foreign-crate.rs:8:13 - | -LL | let _ = foreign_crate::my_macro!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #79813 -note: the lint level is defined here - --> $DIR/foreign-crate.rs:2:9 - | -LL | #![deny(semicolon_in_expressions_from_non_local_macros)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `foreign_crate::my_macro` (in Nightly builds, run with -Z macro-backtrace for more info) - From f30a903839f9d9baa3c7a1939eedca4cdff74f8f Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 28 Sep 2026 16:01:46 +0200 Subject: [PATCH 05/14] Force the correct type variable to never for method resolution on an adjusted never type (cherry picked from commit ceee44bc9df314e1b522e6e479764b96ad5db82d) --- compiler/rustc_hir_typeck/src/method/probe.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index d5c8cb90c1623..4e204e1dc76eb 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -523,8 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, MethodCallOnDivergingInferenceVariable, ); - let root_ty = Ty::new_var(self.tcx, ty_id); - self.demand_eqtype(span, root_ty, self.tcx.types.never); + self.demand_eqtype(span, ty, self.tcx.types.never); } else { let guar = match *ty.kind() { _ if let Some(guar) = self.tainted_by_errors() => guar, From c19205ba27d028d2085120dad9177f9fe987fa82 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 28 Sep 2026 16:02:04 +0200 Subject: [PATCH 06/14] Run the `method-on-never` type on the next trait solver (cherry picked from commit f3b65028f7a6f4cf250929317375d06437b445a2) --- ....stderr => method-on-never.current.stderr} | 20 ++-- .../basic/method-on-never.next.stderr | 113 ++++++++++++++++++ tests/ui/never_type/basic/method-on-never.rs | 2 + 3 files changed, 125 insertions(+), 10 deletions(-) rename tests/ui/never_type/basic/{method-on-never.stderr => method-on-never.current.stderr} (93%) create mode 100644 tests/ui/never_type/basic/method-on-never.next.stderr diff --git a/tests/ui/never_type/basic/method-on-never.stderr b/tests/ui/never_type/basic/method-on-never.current.stderr similarity index 93% rename from tests/ui/never_type/basic/method-on-never.stderr rename to tests/ui/never_type/basic/method-on-never.current.stderr index f5903616be6f4..ec89b37bc403e 100644 --- a/tests/ui/never_type/basic/method-on-never.stderr +++ b/tests/ui/never_type/basic/method-on-never.current.stderr @@ -1,5 +1,5 @@ warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:42:7 + --> $DIR/method-on-never.rs:44:7 | LL | x.method(); | ^^^^^^ @@ -10,7 +10,7 @@ LL | x.method(); = note: `#[warn(method_call_on_diverging_infer_var)]` (part of `#[warn(future_incompatible)]`) on by default warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:46:17 + --> $DIR/method-on-never.rs:48:17 | LL | { loop {} }.method(); | ^^^^^^ @@ -20,7 +20,7 @@ LL | { loop {} }.method(); = note: for more information, see issue #156047 warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:51:16 + --> $DIR/method-on-never.rs:53:16 | LL | y => y.method(), | ^^^^^^ @@ -30,7 +30,7 @@ LL | y => y.method(), = note: for more information, see issue #156047 warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:57:27 + --> $DIR/method-on-never.rs:59:27 | LL | error => (&error).anyhow_kind().new(error), | ^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | error => (&error).anyhow_kind().new(error), = note: for more information, see issue #156047 warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:63:9 + --> $DIR/method-on-never.rs:65:9 | LL | res.method(); | ^^^^^^ @@ -53,7 +53,7 @@ warning: 5 warnings emitted Future incompatibility report: Future breakage diagnostic: warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:42:7 + --> $DIR/method-on-never.rs:44:7 | LL | x.method(); | ^^^^^^ @@ -65,7 +65,7 @@ LL | x.method(); Future breakage diagnostic: warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:46:17 + --> $DIR/method-on-never.rs:48:17 | LL | { loop {} }.method(); | ^^^^^^ @@ -77,7 +77,7 @@ LL | { loop {} }.method(); Future breakage diagnostic: warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:51:16 + --> $DIR/method-on-never.rs:53:16 | LL | y => y.method(), | ^^^^^^ @@ -89,7 +89,7 @@ LL | y => y.method(), Future breakage diagnostic: warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:57:27 + --> $DIR/method-on-never.rs:59:27 | LL | error => (&error).anyhow_kind().new(error), | ^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | error => (&error).anyhow_kind().new(error), Future breakage diagnostic: warning: method call on a diverging inference variable - --> $DIR/method-on-never.rs:63:9 + --> $DIR/method-on-never.rs:65:9 | LL | res.method(); | ^^^^^^ diff --git a/tests/ui/never_type/basic/method-on-never.next.stderr b/tests/ui/never_type/basic/method-on-never.next.stderr new file mode 100644 index 0000000000000..ec89b37bc403e --- /dev/null +++ b/tests/ui/never_type/basic/method-on-never.next.stderr @@ -0,0 +1,113 @@ +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:44:7 + | +LL | x.method(); + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + = note: `#[warn(method_call_on_diverging_infer_var)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:48:17 + | +LL | { loop {} }.method(); + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:53:16 + | +LL | y => y.method(), + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:59:27 + | +LL | error => (&error).anyhow_kind().new(error), + | ^^^^^^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:65:9 + | +LL | res.method(); + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + +warning: 5 warnings emitted + +Future incompatibility report: Future breakage diagnostic: +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:44:7 + | +LL | x.method(); + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + = note: `#[warn(method_call_on_diverging_infer_var)]` (part of `#[warn(future_incompatible)]`) on by default + +Future breakage diagnostic: +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:48:17 + | +LL | { loop {} }.method(); + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + = note: `#[warn(method_call_on_diverging_infer_var)]` (part of `#[warn(future_incompatible)]`) on by default + +Future breakage diagnostic: +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:53:16 + | +LL | y => y.method(), + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + = note: `#[warn(method_call_on_diverging_infer_var)]` (part of `#[warn(future_incompatible)]`) on by default + +Future breakage diagnostic: +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:59:27 + | +LL | error => (&error).anyhow_kind().new(error), + | ^^^^^^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + = note: `#[warn(method_call_on_diverging_infer_var)]` (part of `#[warn(future_incompatible)]`) on by default + +Future breakage diagnostic: +warning: method call on a diverging inference variable + --> $DIR/method-on-never.rs:65:9 + | +LL | res.method(); + | ^^^^^^ + | + = help: consider providing a type annotation + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #156047 + = note: `#[warn(method_call_on_diverging_infer_var)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/never_type/basic/method-on-never.rs b/tests/ui/never_type/basic/method-on-never.rs index 4194884ade9ea..ac928a0e9d071 100644 --- a/tests/ui/never_type/basic/method-on-never.rs +++ b/tests/ui/never_type/basic/method-on-never.rs @@ -1,3 +1,5 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver //@ check-pass // Regression test for https://github.com/rust-lang/rust/issues/143349 From a7aee79d006fe3e74df8d127ac6c1e597d9e8e77 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 1 Oct 2026 18:23:50 +0200 Subject: [PATCH 07/14] Update LLVM submodule to latest release/23.x branch (cherry picked from commit a7709ec3b3181ea7d4acc612af50a132b42e8c0e) --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 1b9c0d5ff9bbe..aab11ee0ea5ea 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 1b9c0d5ff9bbe7634aead059efe6b11a7eeba145 +Subproject commit aab11ee0ea5ea9a1d462ad0bc1fae9d9bb643019 From 6806e8887883fe95e05691564c37607aa4d62006 Mon Sep 17 00:00:00 2001 From: Max Dexheimer Date: Mon, 5 Oct 2026 15:09:28 +0200 Subject: [PATCH 08/14] Adjust the adjustment to wasi TLS to no longer adjust (cherry picked from commit 87ec21a3e7f9ad0d40c6073475977eafd92c3ad8) --- library/std/src/sys/thread_local/mod.rs | 8 ++++---- src/doc/rustc/src/platform-support/wasm32-wasip1.md | 4 ++-- tests/run-make/wasm-panic-small/rmake.rs | 6 +++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 809ef5cfe9c60..f86d25e38efb5 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -35,7 +35,7 @@ cfg_select! { any( - all(target_family = "wasm", not(target_feature = "atomics"), not(target_env = "p3")), + all(target_family = "wasm", not(target_feature = "atomics"), not(target_os = "wasi")), target_os = "uefi", target_os = "zkvm", target_os = "trusty", @@ -66,7 +66,7 @@ cfg_select! { /// single callback that runs all of the destructors in the list. #[cfg(all( target_thread_local, - not(all(target_family = "wasm", not(target_feature = "atomics"), not(target_env = "p3"))) + not(all(target_family = "wasm", not(target_feature = "atomics"), not(target_os = "wasi"))) ))] pub(crate) mod destructors { cfg_select! { @@ -106,7 +106,7 @@ pub(crate) mod guard { pub(crate) use windows::enable; } any( - all(target_family = "wasm", not(target_env = "p3")), + all(target_family = "wasm", not(target_os = "wasi")), target_os = "uefi", target_os = "zkvm", target_os = "trusty", @@ -154,7 +154,7 @@ pub(crate) mod key { all(not(target_vendor = "apple"), not(target_family = "wasm"), target_family = "unix"), all(not(target_thread_local), target_vendor = "apple"), target_os = "teeos", - all(target_os = "wasi", target_env = "p3"), + target_os = "wasi", ) => { mod racy; mod unix; diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index 16499659291a0..3cc0f5a96c597 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -73,13 +73,13 @@ be used instead. ## Building the target in rustc To build this target first acquire a copy of [`wasi-sdk`]. At this time version -33 is the minimum needed. +34 is the minimum needed. Next configure the `WASI_SDK_PATH` environment variable to point to where this is installed. For example: ```text -export WASI_SDK_PATH=/path/to/wasi-sdk-33.0 +export WASI_SDK_PATH=/path/to/wasi-sdk-34.0 ``` Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld` diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs index f6504830a5263..64c17571437c5 100644 --- a/tests/run-make/wasm-panic-small/rmake.rs +++ b/tests/run-make/wasm-panic-small/rmake.rs @@ -24,5 +24,9 @@ fn test(cfg: &str) { let bytes = rfs::read("foo.wasm"); println!("{}", bytes.len()); - assert!(bytes.len() < 45_000, "bytes len was: {}", bytes.len()); + assert!( + bytes.len() < 50_000, + "wasm binary was larger than expected. size in bytes: {}", + bytes.len() + ); } From 653b7625eefa66d29e787db981b87fadc4b82d96 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 6 Oct 2026 07:27:13 +0000 Subject: [PATCH 09/14] use the type name instead of `Self` in constructor paths again (cherry picked from commit e1a95eb0a930ec95cdd1802a677ed8ffbf226b90) --- .../src/deriving/clone.rs | 9 +-- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 11 +-- .../rustc_builtin_macros/src/deriving/eq.rs | 2 +- .../rustc_builtin_macros/src/deriving/from.rs | 2 +- .../src/deriving/generic/mod.rs | 77 +++++++++++++++---- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../src/deriving/partial_eq.rs | 2 +- .../src/deriving/partial_ord.rs | 2 +- .../derives/attr-macro-changes-type-kind.rs | 15 ++++ tests/ui/derives/auxiliary/struct-to-enum.rs | 18 +++++ tests/ui/derives/deriving-all-codegen.stdout | 56 ++++++++------ tests/ui/stats/macro-stats.stderr | 4 +- 13 files changed, 145 insertions(+), 57 deletions(-) create mode 100644 tests/ui/derives/attr-macro-changes-type-kind.rs create mode 100644 tests/ui/derives/auxiliary/struct-to-enum.rs diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 370c0ceeda909..5c2c3052d1d51 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -147,7 +147,7 @@ fn cs_clone_simple( &[sym::clone, sym::AssertParamIsCopy], ); } else { - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } @@ -169,18 +169,17 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> Blo cx.expr_call_global(field.span, fn_path.clone(), args) }; - let self_ident = Ident::new(kw::SelfUpper, trait_span); let ctor_path; let all_fields; let vdata; - match substr { + match substr.fields { Struct(vdata_, af) => { - ctor_path = cx.path(trait_span, vec![self_ident]); + ctor_path = cx.path(trait_span, vec![substr.type_ident]); all_fields = af; vdata = vdata_; } EnumMatching(.., variant, af) => { - ctor_path = cx.path(trait_span, vec![self_ident, variant.ident]); + ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]); all_fields = af; vdata = &variant.data; } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 2f3d2058773d8..d8355d733a7f3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -68,7 +68,7 @@ fn show_substructure( return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new()))); } - let (ident, vdata, fields) = match substr { + let (ident, vdata, fields) = match substr.fields { Struct(vdata, fields) => (type_ident, vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 28526bdef6b9d..268153c1cbb31 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -37,9 +37,9 @@ pub(crate) fn expand_deriving_default( attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { - match substr { + match substr.fields { StaticStruct(variant_data) => { - default_struct_substructure(cx, trait_span, variant_data) + default_struct_substructure(cx, trait_span, variant_data, substr.type_ident) } StaticEnum(enum_def) => { default_enum_substructure(cx, trait_span, enum_def, item.span) @@ -67,15 +67,16 @@ fn default_struct_substructure( cx: &ExtCtxt<'_>, trait_span: Span, variant_data: &VariantData, + type_ident: Ident, ) -> BlockOrExpr { let expr = match variant_data { - VariantData::Unit(_) => cx.expr_ident(trait_span, Ident::new(kw::SelfUpper, trait_span)), + VariantData::Unit(_) => cx.expr_ident(trait_span, type_ident), VariantData::Tuple(fields, _) => { let exprs = fields .iter() .map(|field| default_call(cx, field.span.with_ctxt(trait_span.ctxt()))) .collect(); - cx.expr_call_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), exprs) + cx.expr_call_ident(trait_span, type_ident, exprs) } VariantData::Struct { fields, .. } => { let default_fields = fields @@ -95,7 +96,7 @@ fn default_struct_substructure( cx.field_imm(span, field.ident.unwrap(), value) }) .collect(); - cx.expr_struct_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), default_fields) + cx.expr_struct_ident(trait_span, type_ident, default_fields) } }; BlockOrExpr::new_expr(expr) diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index da38045994c7f..27be8a8cb6dff 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -72,7 +72,7 @@ fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<' } }; - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index df95ccd99f3e6..edd1cf75488fc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -88,7 +88,7 @@ pub(crate) fn expand_deriving_from( }; let self_kw = Ident::new(kw::SelfUpper, span); - let expr: Box = match substructure { + let expr: Box = match substructure.fields { StaticStruct(variant) => match variant { // Self { field: value } VariantData::Struct { .. } => cx.expr_struct_ident( diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 71329da76c481..e95231c419b67 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -177,7 +177,7 @@ use std::ops::Not; use std::vec; -pub(crate) use Substructure::*; +pub(crate) use SubstructureFields::*; pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentKind, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; @@ -281,8 +281,16 @@ pub(crate) struct FieldInfo { pub maybe_scalar: bool, } +pub(crate) struct Substructure<'a> { + pub fields: SubstructureFields<'a>, + // FIXME: this is currently required to avoid issues with attribute macros after derives, + // such as https://github.com/rust-lang/rust/issues/163800. + // Ideally we would just use `Self` instead. + pub type_ident: Ident, +} + /// A summary of the possible sets of fields. -pub(crate) enum Substructure<'a> { +pub(crate) enum SubstructureFields<'a> { /// A non-static method where `Self` is a struct. Struct(&'a ast::VariantData, Vec), @@ -474,9 +482,15 @@ impl<'a> TraitDef<'a> { let fields = struct_def.fields().iter(); let methods = self.methods.iter().filter_map(|method_def| { let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method(cx, span, StaticStruct(struct_def)) + method_def.call_substructure_method( + cx, + span, + StaticStruct(struct_def), + *ident, + ) } else { - method_def.expand_struct_method_body(cx, span, struct_def, is_packed) + method_def + .expand_struct_method_body(cx, span, struct_def, is_packed, *ident) }; method_def.create_method(cx, span, body) @@ -494,9 +508,9 @@ impl<'a> TraitDef<'a> { let fields = enum_def.variants.iter().flat_map(|variant| variant.data.fields()); let methods = self.methods.iter().filter_map(|method_def| { let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method(cx, span, StaticEnum(enum_def)) + method_def.call_substructure_method(cx, span, StaticEnum(enum_def), *ident) } else { - method_def.expand_enum_method_body(cx, span, enum_def) + method_def.expand_enum_method_body(cx, span, enum_def, *ident) }; method_def.create_method(cx, span, body) @@ -794,9 +808,10 @@ impl<'a> MethodDef<'a> { &self, cx: &ExtCtxt<'_>, span: Span, - substructure: Substructure<'_>, + fields: SubstructureFields<'_>, + type_ident: Ident, ) -> BlockOrExpr { - (self.combine_substructure)(cx, span, substructure) + (self.combine_substructure)(cx, span, Substructure { fields, type_ident }) } fn is_static(&self) -> bool { @@ -922,12 +937,13 @@ impl<'a> MethodDef<'a> { span: Span, struct_def: &'b VariantData, is_packed: bool, + type_ident: Ident, ) -> BlockOrExpr { let selflike_args = self.get_selflike_args(cx, span); let selflike_fields = create_struct_field_access_fields(span, cx, &selflike_args, struct_def, is_packed); - self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields)) + self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), type_ident) } /// ``` @@ -970,6 +986,7 @@ impl<'a> MethodDef<'a> { cx: &ExtCtxt<'_>, span: Span, enum_def: &'b EnumDef, + type_ident: Ident, ) -> BlockOrExpr { let variants = &enum_def.variants; @@ -1005,17 +1022,32 @@ impl<'a> MethodDef<'a> { // If the type is fieldless and the trait uses the discriminant and // there are multiple variants, we need just an operation on // the discriminant(s). - return self.call_substructure_method(cx, span, EnumDiscr(None)); + return self.call_substructure_method( + cx, + span, + EnumDiscr(None), + type_ident, + ); } FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => { - return self.call_substructure_method(cx, span, AllFieldlessEnum(enum_def)); + return self.call_substructure_method( + cx, + span, + AllFieldlessEnum(enum_def), + type_ident, + ); } FieldlessVariantsStrategy::Default => (), } } else if let [variant] = variants.as_slice() { // If there is a single variant, we don't need an operation on // the discriminant(s). Just use the most degenerate result. - return self.call_substructure_method(cx, span, EnumMatching(variant, Vec::new())); + return self.call_substructure_method( + cx, + span, + EnumMatching(variant, Vec::new()), + type_ident, + ); } } @@ -1055,8 +1087,9 @@ impl<'a> MethodDef<'a> { // Self arg, assuming all are instances of VariantK. // Build up code associated with such a case. let substructure = EnumMatching(variant, fields); - let arm_expr = - self.call_substructure_method(cx, span, substructure).into_expr(cx, span); + let arm_expr = self + .call_substructure_method(cx, span, substructure, type_ident) + .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) }) @@ -1068,8 +1101,13 @@ impl<'a> MethodDef<'a> { Some(v) if unify_fieldless_variants => { // We need a default case that handles all the fieldless variants. Some( - self.call_substructure_method(cx, span, EnumMatching(v, Vec::new())) - .into_expr(cx, span), + self.call_substructure_method( + cx, + span, + EnumMatching(v, Vec::new()), + type_ident, + ) + .into_expr(cx, span), ) } _ if variants.len() > 1 && selflike_args.len() > 1 => { @@ -1106,7 +1144,12 @@ impl<'a> MethodDef<'a> { // is enough. if unify_fieldless_variants && variants.len() > 1 { // Combine a discriminant check with the match. - self.call_substructure_method(cx, span, EnumDiscr(Some(get_match_expr(selflike_args)))) + self.call_substructure_method( + cx, + span, + EnumDiscr(Some(get_match_expr(selflike_args))), + type_ident, + ) } else { BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args))) } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 3d3023b39955d..4f39a1a06a1e7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -65,7 +65,7 @@ fn hash_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> cx.stmt_expr(expr) }; - let (stmts, match_expr) = match substr { + let (stmts, match_expr) = match substr.fields { Struct(_, fields) | EnumMatching(.., fields) => { let stmts = fields.into_iter().map(|field| call_hash(field.span, field.self_expr)).collect(); diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 377a32dcca4f0..180800aa72025 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -119,7 +119,7 @@ fn get_substructure_equality_expr( span: Span, substructure: Substructure<'_>, ) -> BlockOrExpr { - BlockOrExpr::new_expr(match substructure { + BlockOrExpr::new_expr(match substructure.fields { EnumMatching(.., fields) | Struct(.., fields) => { let combine = move |acc, field: &FieldInfo| { let rhs = field diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 8c3e2ee58f8e2..4ce695a16200f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -202,7 +202,7 @@ pub(crate) fn cmp_body( } }; - match substructure { + match substructure.fields { EnumMatching(.., all_fields) | Struct(_, all_fields) => { let op = |old, field: FieldInfo| { // The basic case: a field expression for one or more selflike args. E.g. diff --git a/tests/ui/derives/attr-macro-changes-type-kind.rs b/tests/ui/derives/attr-macro-changes-type-kind.rs new file mode 100644 index 0000000000000..98e05af3b33b6 --- /dev/null +++ b/tests/ui/derives/attr-macro-changes-type-kind.rs @@ -0,0 +1,15 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/163800, +//! where the generated code always referred to `Self`, which was invalid +//! when an attribute macro rewrites the type to an enum. + +//@ check-pass +//@ proc-macro: struct-to-enum.rs + +extern crate struct_to_enum; +use struct_to_enum::*; + +#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[struct_to_enum::phantom] +struct Spooky; + +fn main() {} diff --git a/tests/ui/derives/auxiliary/struct-to-enum.rs b/tests/ui/derives/auxiliary/struct-to-enum.rs new file mode 100644 index 0000000000000..458d8453d5076 --- /dev/null +++ b/tests/ui/derives/auxiliary/struct-to-enum.rs @@ -0,0 +1,18 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn phantom(_: TokenStream, _: TokenStream) -> TokenStream { + " +mod __value_Spooky { + pub use super::Spooky::Spooky; +} +pub enum Spooky { + __Phantom(std::marker::PhantomData), + Spooky, +} +pub use self::__value_Spooky::*; + " + .parse() + .unwrap() +} diff --git a/tests/ui/derives/deriving-all-codegen.stdout b/tests/ui/derives/deriving-all-codegen.stdout index 05412aca82360..163658d2106dd 100644 --- a/tests/ui/derives/deriving-all-codegen.stdout +++ b/tests/ui/derives/deriving-all-codegen.stdout @@ -46,7 +46,7 @@ impl ::core::fmt::Debug for Empty { #[automatically_derived] impl ::core::default::Default for Empty { #[inline] - fn default() -> Self { Self } + fn default() -> Self { Empty } } #[automatically_derived] impl ::core::hash::Hash for Empty { @@ -109,7 +109,7 @@ impl ::core::fmt::Debug for Point { impl ::core::default::Default for Point { #[inline] fn default() -> Self { - Self { + Point { x: ::core::default::Default::default(), y: ::core::default::Default::default(), } @@ -193,7 +193,7 @@ impl ::core::fmt::Debug for PackedPoint { impl ::core::default::Default for PackedPoint { #[inline] fn default() -> Self { - Self { + PackedPoint { x: ::core::default::Default::default(), y: ::core::default::Default::default(), } @@ -270,7 +270,9 @@ impl ::core::fmt::Debug for TupleSingleField { #[automatically_derived] impl ::core::default::Default for TupleSingleField { #[inline] - fn default() -> Self { Self(::core::default::Default::default()) } + fn default() -> Self { + TupleSingleField(::core::default::Default::default()) + } } #[automatically_derived] impl ::core::convert::From for TupleSingleField { @@ -343,7 +345,9 @@ impl ::core::fmt::Debug for SingleField { #[automatically_derived] impl ::core::default::Default for SingleField { #[inline] - fn default() -> Self { Self { foo: ::core::default::Default::default() } } + fn default() -> Self { + SingleField { foo: ::core::default::Default::default() } + } } #[automatically_derived] impl ::core::convert::From for SingleField { @@ -431,7 +435,7 @@ impl ::core::fmt::Debug for Big { impl ::core::default::Default for Big { #[inline] fn default() -> Self { - Self { + Big { b1: ::core::default::Default::default(), b2: ::core::default::Default::default(), b3: ::core::default::Default::default(), @@ -622,7 +626,7 @@ struct NonCopy(u32); #[automatically_derived] impl ::core::clone::Clone for NonCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { NonCopy(::core::clone::Clone::clone(&self.0)) } } // A packed struct that doesn't impl `Copy`, which means it gets the non-trivial @@ -632,7 +636,9 @@ struct PackedNonCopy(u32); #[automatically_derived] impl ::core::clone::Clone for PackedNonCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&{ self.0 })) } + fn clone(&self) -> Self { + PackedNonCopy(::core::clone::Clone::clone(&{ self.0 })) + } } // A struct that impls `Copy` manually, which means it gets the non-trivial @@ -641,7 +647,9 @@ struct ManualCopy(u32); #[automatically_derived] impl ::core::clone::Clone for ManualCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { + ManualCopy(::core::clone::Clone::clone(&self.0)) + } } impl Copy for ManualCopy {} @@ -652,7 +660,9 @@ struct PackedManualCopy(u32); #[automatically_derived] impl ::core::clone::Clone for PackedManualCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&{ self.0 })) } + fn clone(&self) -> Self { + PackedManualCopy(::core::clone::Clone::clone(&{ self.0 })) + } } impl Copy for PackedManualCopy {} @@ -725,7 +735,7 @@ impl ::core::clone::Clone for Generic where T::A: ::core::clone::Clone { #[inline] fn clone(&self) -> Self { - Self { + Generic { t: ::core::clone::Clone::clone(&self.t), ta: ::core::clone::Clone::clone(&self.ta), u: ::core::clone::Clone::clone(&self.u), @@ -751,7 +761,7 @@ impl T::A: ::core::default::Default { #[inline] fn default() -> Self { - Self { + Generic { t: ::core::default::Default::default(), ta: ::core::default::Default::default(), u: ::core::default::Default::default(), @@ -844,7 +854,7 @@ impl Self { - Self(::core::clone::Clone::clone(&{ self.0 }), + PackedGeneric(::core::clone::Clone::clone(&{ self.0 }), ::core::clone::Clone::clone(&{ self.1 }), ::core::clone::Clone::clone(&{ self.2 })) } @@ -871,7 +881,7 @@ impl T::A: ::core::default::Default { #[inline] fn default() -> Self { - Self(::core::default::Default::default(), + PackedGeneric(::core::default::Default::default(), ::core::default::Default::default(), ::core::default::Default::default()) } @@ -1019,7 +1029,7 @@ impl ::core::clone::Clone for Enum1 { fn clone(&self) -> Self { match self { Self::Single { x: __self_0 } => - Self::Single { x: ::core::clone::Clone::clone(__self_0) }, + Enum1::Single { x: ::core::clone::Clone::clone(__self_0) }, } } } @@ -1093,7 +1103,7 @@ enum Fieldless1 { #[automatically_derived] impl ::core::clone::Clone for Fieldless1 { #[inline] - fn clone(&self) -> Self { Self::A } + fn clone(&self) -> Self { Fieldless1::A } } #[automatically_derived] impl ::core::fmt::Debug for Fieldless1 { @@ -1408,11 +1418,11 @@ impl ::core::clone::Clone for Fielded { fn clone(&self) -> Self { match self { Self::X(__self_0) => - Self::X(::core::clone::Clone::clone(__self_0)), + Fielded::X(::core::clone::Clone::clone(__self_0)), Self::Y(__self_0) => - Self::Y(::core::clone::Clone::clone(__self_0)), + Fielded::Y(::core::clone::Clone::clone(__self_0)), Self::Z(__self_0) => - Self::Z(::core::clone::Clone::clone(__self_0)), + Fielded::Z(::core::clone::Clone::clone(__self_0)), } } } @@ -1511,9 +1521,9 @@ impl ::core::clone::Clone fn clone(&self) -> Self { match self { Self::One(__self_0) => - Self::One(::core::clone::Clone::clone(__self_0)), + EnumGeneric::One(::core::clone::Clone::clone(__self_0)), Self::Two(__self_0) => - Self::Two(::core::clone::Clone::clone(__self_0)), + EnumGeneric::Two(::core::clone::Clone::clone(__self_0)), } } } @@ -1712,7 +1722,9 @@ impl ::core::marker::Copy for FooCloneAndCopy { } #[automatically_derived] impl ::core::clone::Clone for FooCloneAndCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { + FooCloneAndCopy(::core::clone::Clone::clone(&self.0)) + } } struct FooPartialOrdOrd(i32); diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index efc3785878c39..e549d315e7fdb 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -2,11 +2,11 @@ macro-stats ==================================================================== macro-stats MACRO EXPANSION STATS: macro_stats macro-stats Macro Name Uses Lines Avg Lines Bytes Avg Bytes macro-stats ----------------------------------------------------------------------------------- -macro-stats #[derive(Clone)] 8 67 8.4 1_909 238.6 +macro-stats #[derive(Clone)] 8 67 8.4 1_895 236.9 macro-stats #[derive(Hash)] 2 17 8.5 536 268.0 macro-stats q! 1 26 26.0 519 519.0 macro-stats #[derive(Ord)] 1 15 15.0 505 505.0 -macro-stats #[derive(Default)] 2 16 8.0 409 204.5 +macro-stats #[derive(Default)] 2 16 8.0 407 203.5 macro-stats #[derive(Eq)] 1 11 11.0 312 312.0 macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 macro-stats #[derive(PartialEq)] 1 9 9.0 269 269.0 From 198b1899ccf546afb94cb16a397f96800d1a0bfd Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 6 Oct 2026 23:49:52 -0400 Subject: [PATCH 10/14] Add test coverage (cherry picked from commit 294ff0f9d8ee6c81147737e3cc3fa35d2abef115) --- .../some-abis-do-extend-params-to-32-bits.rs | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs index fdaf0dc58f106..906ce15145694 100644 --- a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs @@ -1,10 +1,12 @@ //@ add-minicore //@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 -//@ revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv +//@ revisions:x86_64-linux x86_64-uefi i686 aarch64-apple aarch64-windows aarch64-linux arm riscv -//@[x86_64] compile-flags: --target x86_64-unknown-uefi -//@[x86_64] needs-llvm-components: x86 +//@[x86_64-uefi] compile-flags: --target x86_64-unknown-uefi +//@[x86_64-uefi] needs-llvm-components: x86 +//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64-linux] needs-llvm-components: x86 //@[i686] compile-flags: --target i686-unknown-linux-musl //@[i686] needs-llvm-components: x86 //@[aarch64-windows] compile-flags: --target aarch64-pc-windows-msvc @@ -33,7 +35,8 @@ use minicore::*; // // ZERO/SIGN-EXTENDING TO 32 BITS NON-EXTENDING // ============================== ======================= -// x86_64: void @c_arg_bool(i1 zeroext %_a) +// x86_64-linux: void @c_arg_bool(i1 zeroext %_a) +// x86_64-uefi: void @c_arg_bool(i1 zeroext %_a) // i686: void @c_arg_bool(i1 zeroext %_a) // aarch64-apple: void @c_arg_bool(i1 zeroext %_a) // aarch64-windows: void @c_arg_bool(i1 %_a) @@ -43,7 +46,8 @@ use minicore::*; #[no_mangle] pub extern "C" fn c_arg_bool(_a: bool) {} -// x86_64: void @c_arg_u8(i8 zeroext %_a) +// x86_64-linux: void @c_arg_u8(i8 zeroext %_a) +// x86_64-uefi: void @c_arg_u8(i8 zeroext %_a) // i686: void @c_arg_u8(i8 zeroext %_a) // aarch64-apple: void @c_arg_u8(i8 zeroext %_a) // aarch64-windows: void @c_arg_u8(i8 %_a) @@ -53,7 +57,8 @@ pub extern "C" fn c_arg_bool(_a: bool) {} #[no_mangle] pub extern "C" fn c_arg_u8(_a: u8) {} -// x86_64: void @c_arg_u16(i16 zeroext %_a) +// x86_64-linux: void @c_arg_u16(i16 zeroext %_a) +// x86_64-uefi: void @c_arg_u16(i16 zeroext %_a) // i686: void @c_arg_u16(i16 zeroext %_a) // aarch64-apple: void @c_arg_u16(i16 zeroext %_a) // aarch64-windows: void @c_arg_u16(i16 %_a) @@ -63,7 +68,8 @@ pub extern "C" fn c_arg_u8(_a: u8) {} #[no_mangle] pub extern "C" fn c_arg_u16(_a: u16) {} -// x86_64: void @c_arg_u32(i32 %_a) +// x86_64-linux: void @c_arg_u32(i32 %_a) +// x86_64-uefi: void @c_arg_u32(i32 %_a) // i686: void @c_arg_u32(i32 %_a) // aarch64-apple: void @c_arg_u32(i32 %_a) // aarch64-windows: void @c_arg_u32(i32 %_a) @@ -73,7 +79,8 @@ pub extern "C" fn c_arg_u16(_a: u16) {} #[no_mangle] pub extern "C" fn c_arg_u32(_a: u32) {} -// x86_64: void @c_arg_u64(i64 %_a) +// x86_64-linux: void @c_arg_u64(i64 %_a) +// x86_64-uefi: void @c_arg_u64(i64 %_a) // i686: void @c_arg_u64(i64 %_a) // aarch64-apple: void @c_arg_u64(i64 %_a) // aarch64-windows: void @c_arg_u64(i64 %_a) @@ -83,7 +90,8 @@ pub extern "C" fn c_arg_u32(_a: u32) {} #[no_mangle] pub extern "C" fn c_arg_u64(_a: u64) {} -// x86_64: void @c_arg_i8(i8 signext %_a) +// x86_64-linux: void @c_arg_i8(i8 signext %_a) +// x86_64-uefi: void @c_arg_i8(i8 signext %_a) // i686: void @c_arg_i8(i8 signext %_a) // aarch64-apple: void @c_arg_i8(i8 signext %_a) // aarch64-windows: void @c_arg_i8(i8 %_a) @@ -93,7 +101,8 @@ pub extern "C" fn c_arg_u64(_a: u64) {} #[no_mangle] pub extern "C" fn c_arg_i8(_a: i8) {} -// x86_64: void @c_arg_i16(i16 signext %_a) +// x86_64-linux: void @c_arg_i16(i16 signext %_a) +// x86_64-uefi: void @c_arg_i16(i16 signext %_a) // i686: void @c_arg_i16(i16 signext %_a) // aarch64-apple: void @c_arg_i16(i16 signext %_a) // aarch64-windows: void @c_arg_i16(i16 %_a) @@ -103,7 +112,8 @@ pub extern "C" fn c_arg_i8(_a: i8) {} #[no_mangle] pub extern "C" fn c_arg_i16(_a: i16) {} -// x86_64: void @c_arg_i32(i32 %_a) +// x86_64-linux: void @c_arg_i32(i32 %_a) +// x86_64-uefi: void @c_arg_i32(i32 %_a) // i686: void @c_arg_i32(i32 %_a) // aarch64-apple: void @c_arg_i32(i32 %_a) // aarch64-windows: void @c_arg_i32(i32 %_a) @@ -113,7 +123,8 @@ pub extern "C" fn c_arg_i16(_a: i16) {} #[no_mangle] pub extern "C" fn c_arg_i32(_a: i32) {} -// x86_64: void @c_arg_i64(i64 %_a) +// x86_64-linux: void @c_arg_i64(i64 %_a) +// x86_64-uefi: void @c_arg_i64(i64 %_a) // i686: void @c_arg_i64(i64 %_a) // aarch64-apple: void @c_arg_i64(i64 %_a) // aarch64-windows: void @c_arg_i64(i64 %_a) @@ -123,7 +134,8 @@ pub extern "C" fn c_arg_i32(_a: i32) {} #[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) {} -// x86_64: zeroext i1 @c_ret_bool() +// x86_64-linux: i1 @c_ret_bool() +// x86_64-uefi: zeroext i1 @c_ret_bool() // i686: zeroext i1 @c_ret_bool() // aarch64-apple: zeroext i1 @c_ret_bool() // aarch64-windows: i1 @c_ret_bool() @@ -135,7 +147,8 @@ pub extern "C" fn c_ret_bool() -> bool { false } -// x86_64: zeroext i8 @c_ret_u8() +// x86_64-linux: i8 @c_ret_u8() +// x86_64-uefi: zeroext i8 @c_ret_u8() // i686: zeroext i8 @c_ret_u8() // aarch64-apple: zeroext i8 @c_ret_u8() // aarch64-windows: i8 @c_ret_u8() @@ -147,7 +160,8 @@ pub extern "C" fn c_ret_u8() -> u8 { 0 } -// x86_64: zeroext i16 @c_ret_u16() +// x86_64-linux: i16 @c_ret_u16() +// x86_64-uefi: zeroext i16 @c_ret_u16() // i686: zeroext i16 @c_ret_u16() // aarch64-apple: zeroext i16 @c_ret_u16() // aarch64-windows: i16 @c_ret_u16() @@ -159,7 +173,8 @@ pub extern "C" fn c_ret_u16() -> u16 { 0 } -// x86_64: i32 @c_ret_u32() +// x86_64-linux: i32 @c_ret_u32() +// x86_64-uefi: i32 @c_ret_u32() // i686: i32 @c_ret_u32() // aarch64-apple: i32 @c_ret_u32() // aarch64-windows: i32 @c_ret_u32() @@ -171,7 +186,8 @@ pub extern "C" fn c_ret_u32() -> u32 { 0 } -// x86_64: i64 @c_ret_u64() +// x86_64-linux: i64 @c_ret_u64() +// x86_64-uefi: i64 @c_ret_u64() // i686: i64 @c_ret_u64() // aarch64-apple: i64 @c_ret_u64() // aarch64-windows: i64 @c_ret_u64() @@ -183,7 +199,8 @@ pub extern "C" fn c_ret_u64() -> u64 { 0 } -// x86_64: signext i8 @c_ret_i8() +// x86_64-linux: i8 @c_ret_i8() +// x86_64-uefi: signext i8 @c_ret_i8() // i686: signext i8 @c_ret_i8() // aarch64-apple: signext i8 @c_ret_i8() // aarch64-windows: i8 @c_ret_i8() @@ -195,7 +212,8 @@ pub extern "C" fn c_ret_i8() -> i8 { 0 } -// x86_64: signext i16 @c_ret_i16() +// x86_64-linux: i16 @c_ret_i16() +// x86_64-uefi: signext i16 @c_ret_i16() // i686: signext i16 @c_ret_i16() // aarch64-apple: signext i16 @c_ret_i16() // aarch64-windows: i16 @c_ret_i16() @@ -207,7 +225,8 @@ pub extern "C" fn c_ret_i16() -> i16 { 0 } -// x86_64: i32 @c_ret_i32() +// x86_64-linux: i32 @c_ret_i32() +// x86_64-uefi: i32 @c_ret_i32() // i686: i32 @c_ret_i32() // aarch64-apple: i32 @c_ret_i32() // aarch64-windows: i32 @c_ret_i32() @@ -219,7 +238,8 @@ pub extern "C" fn c_ret_i32() -> i32 { 0 } -// x86_64: i64 @c_ret_i64() +// x86_64-linux: i64 @c_ret_i64() +// x86_64-uefi: i64 @c_ret_i64() // i686: i64 @c_ret_i64() // aarch64-apple: i64 @c_ret_i64() // aarch64-windows: i64 @c_ret_i64() From 0dfb1c03be71cd4e99706888330ff4decf6843dd Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 6 Oct 2026 23:54:55 -0400 Subject: [PATCH 11/14] Fix the bug by enabling extension for bool returns on x86_64 (cherry picked from commit a0f1885963480bfefb3495377a72f65886a373b1) --- compiler/rustc_target/src/callconv/mod.rs | 4 +++- compiler/rustc_target/src/callconv/x86_64.rs | 5 +++++ tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index edc23b6c50b45..6be16e8d822ae 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -565,7 +565,9 @@ impl<'a, Ty> ArgAbi<'a, Ty> { // Only integers have signedness if let BackendRepr::Scalar(scalar) = self.layout.backend_repr && let Primitive::Int(i, signed) = scalar.primitive() - && i.size().bits() < bits + // bools are i1 but their primitive is i8. Unlike other types, + // bools can be extended to their primitive size. + && (i.size().bits() < bits || self.layout.backend_repr.is_bool()) && let PassMode::Direct(ref mut attrs) = self.mode { if signed { diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index 5ab2834807d67..378989a07246f 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -248,6 +248,11 @@ where } else if is_arg || cx.target_spec().is_like_darwin { arg.extend_integer_width_to(32); } + // The x86_64 psABI requires bools to be zero-extended to 8-bits, with high bits unspecified. + // zeroext i1 has this behavior in the LLVM X86 backend. + if !is_arg && arg.layout.backend_repr.is_bool() { + arg.extend_integer_width_to(8); + } } } }; diff --git a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs index 906ce15145694..79be3bd5f57b4 100644 --- a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs @@ -134,7 +134,7 @@ pub extern "C" fn c_arg_i32(_a: i32) {} #[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) {} -// x86_64-linux: i1 @c_ret_bool() +// x86_64-linux: zeroext i1 @c_ret_bool() // x86_64-uefi: zeroext i1 @c_ret_bool() // i686: zeroext i1 @c_ret_bool() // aarch64-apple: zeroext i1 @c_ret_bool() From 512e30549c3d12ad996799d5fee70ac22bb454d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 7 Oct 2026 13:05:25 +0200 Subject: [PATCH 12/14] Sort windows-gnullvm dist libs (cherry picked from commit 5d6aec67fd423a2f344bc826ddb16faaa7fd32f2) --- src/bootstrap/src/core/build_steps/dist.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 7073b334c414d..b6dcf3948166c 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -354,12 +354,12 @@ fn make_win_llvm_dist(plat_root: &Path, target: TargetSelection, builder: &Build "libmingwex.a", "libmsvcrt.a", // Windows import libs, remove them once std transitions to raw-dylib + "libdbghelp.a", "libkernel32.a", - "libuser32.a", "libntdll.a", + "libuser32.a", "libuserenv.a", "libws2_32.a", - "libdbghelp.a", ]; //Find mingw artifacts we want to bundle From 4bbf5348275aeb90ec48076d17ac50b88f40b089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 7 Oct 2026 13:09:34 +0200 Subject: [PATCH 13/14] Add `synchronization` import lib to windows-gnullvm dist (cherry picked from commit 94fa86c197dcb3e8f160182afb57bf2680e66e8a) --- src/bootstrap/src/core/build_steps/dist.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index b6dcf3948166c..954e54547308d 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -357,6 +357,7 @@ fn make_win_llvm_dist(plat_root: &Path, target: TargetSelection, builder: &Build "libdbghelp.a", "libkernel32.a", "libntdll.a", + "libsynchronization.a", "libuser32.a", "libuserenv.a", "libws2_32.a", From 6aac464d544905048746b00ebc1279ca25309b03 Mon Sep 17 00:00:00 2001 From: rami3l Date: Wed, 7 Oct 2026 17:41:33 +0200 Subject: [PATCH 14/14] fix(bootstrap/darwin): fix rpath for distributed LLD (cherry picked from commit 7b151cff4f8a56df4bea875a0337affcfd309147) --- src/bootstrap/download-ci-llvm-stamp | 2 +- src/bootstrap/src/core/build_steps/llvm.rs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index ad3fbce51d1d2..58691539edfa3 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/161049 +Last change is for: https://github.com/rust-lang/rust/pull/163954 diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 6700392fc7add..7f0aa2a2747be 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -1724,7 +1724,6 @@ impl CommandLineStep for Lld { if builder.config.rpath_enabled(target) && helpers::use_host_linker(target) && llvm_output.link_shared() - && target.contains("linux") { // So we inform LLD where it can find LLVM's libraries by adding an rpath entry to the // expected parent `lib` directory. @@ -1732,7 +1731,12 @@ impl CommandLineStep for Lld { // Be careful when changing this path, we need to ensure it's quoted or escaped: // `$ORIGIN` would otherwise be expanded when the `LdFlags` are passed verbatim to // cmake. - ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'"); + if target.contains("linux") { + ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'"); + } + if target.contains("apple-darwin") { + ldflags.push_all("-Wl,-rpath,'@loader_path/../../../'"); + } } configure_cmake(builder, target, &mut cfg, true, ldflags, CcFlags::default(), &[]);