From bd9ac5bca39deb9970788c7cde2940b4e0289d98 Mon Sep 17 00:00:00 2001 From: zedddie Date: Tue, 7 Jul 2026 23:16:40 +0200 Subject: [PATCH 01/12] move batch --- .../unconstrained-dyn-assoc-type-lifetime.rs} | 0 .../unconstrained-dyn-assoc-type-lifetime.stderr} | 0 .../{issues/issue-34334.rs => binding/tuple-binder-on-err-ty.rs} | 0 .../issue-34334.stderr => binding/tuple-binder-on-err-ty.stderr} | 0 tests/ui/{issues/issue-33525.rs => errors/error-count.rs} | 0 tests/ui/{issues/issue-33525.stderr => errors/error-count.stderr} | 0 .../cyclic-default-type-param-via-alias.rs} | 0 .../cyclic-default-type-param-via-alias.stderr} | 0 .../cloned-hashmap-iter-type-mismatch-diag.current.stderr} | 0 .../cloned-hashmap-iter-type-mismatch-diag.next.stderr} | 0 .../cloned-hashmap-iter-type-mismatch-diag.rs} | 0 .../lifetime-in-unit-struct-pattern.rs} | 0 .../ui/{issues/issue-35423.rs => match/range-arm-and-ref-arm.rs} | 0 .../issue-33504.rs => shadowed/shadow-unit-struct-in-closure.rs} | 0 .../shadow-unit-struct-in-closure.stderr} | 0 .../generic-recursive-list-struct.rs} | 0 .../no-double-lock-same-thread.rs} | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-35139.rs => associated-types/unconstrained-dyn-assoc-type-lifetime.rs} (100%) rename tests/ui/{issues/issue-35139.stderr => associated-types/unconstrained-dyn-assoc-type-lifetime.stderr} (100%) rename tests/ui/{issues/issue-34334.rs => binding/tuple-binder-on-err-ty.rs} (100%) rename tests/ui/{issues/issue-34334.stderr => binding/tuple-binder-on-err-ty.stderr} (100%) rename tests/ui/{issues/issue-33525.rs => errors/error-count.rs} (100%) rename tests/ui/{issues/issue-33525.stderr => errors/error-count.stderr} (100%) rename tests/ui/{issues/issue-34373.rs => generics/cyclic-default-type-param-via-alias.rs} (100%) rename tests/ui/{issues/issue-34373.stderr => generics/cyclic-default-type-param-via-alias.stderr} (100%) rename tests/ui/{issues/issue-33941.current.stderr => iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr} (100%) rename tests/ui/{issues/issue-33941.next.stderr => iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr} (100%) rename tests/ui/{issues/issue-33941.rs => iterators/cloned-hashmap-iter-type-mismatch-diag.rs} (100%) rename tests/ui/{issues/issue-34751.rs => lifetimes/lifetime-in-unit-struct-pattern.rs} (100%) rename tests/ui/{issues/issue-35423.rs => match/range-arm-and-ref-arm.rs} (100%) rename tests/ui/{issues/issue-33504.rs => shadowed/shadow-unit-struct-in-closure.rs} (100%) rename tests/ui/{issues/issue-33504.stderr => shadowed/shadow-unit-struct-in-closure.stderr} (100%) rename tests/ui/{issues/issue-3447.rs => structs-enums/generic-recursive-list-struct.rs} (100%) rename tests/ui/{issues/issue-33770.rs => threads-sendsync/no-double-lock-same-thread.rs} (100%) diff --git a/tests/ui/issues/issue-35139.rs b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs similarity index 100% rename from tests/ui/issues/issue-35139.rs rename to tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs diff --git a/tests/ui/issues/issue-35139.stderr b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr similarity index 100% rename from tests/ui/issues/issue-35139.stderr rename to tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr diff --git a/tests/ui/issues/issue-34334.rs b/tests/ui/binding/tuple-binder-on-err-ty.rs similarity index 100% rename from tests/ui/issues/issue-34334.rs rename to tests/ui/binding/tuple-binder-on-err-ty.rs diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/binding/tuple-binder-on-err-ty.stderr similarity index 100% rename from tests/ui/issues/issue-34334.stderr rename to tests/ui/binding/tuple-binder-on-err-ty.stderr diff --git a/tests/ui/issues/issue-33525.rs b/tests/ui/errors/error-count.rs similarity index 100% rename from tests/ui/issues/issue-33525.rs rename to tests/ui/errors/error-count.rs diff --git a/tests/ui/issues/issue-33525.stderr b/tests/ui/errors/error-count.stderr similarity index 100% rename from tests/ui/issues/issue-33525.stderr rename to tests/ui/errors/error-count.stderr diff --git a/tests/ui/issues/issue-34373.rs b/tests/ui/generics/cyclic-default-type-param-via-alias.rs similarity index 100% rename from tests/ui/issues/issue-34373.rs rename to tests/ui/generics/cyclic-default-type-param-via-alias.rs diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/generics/cyclic-default-type-param-via-alias.stderr similarity index 100% rename from tests/ui/issues/issue-34373.stderr rename to tests/ui/generics/cyclic-default-type-param-via-alias.stderr diff --git a/tests/ui/issues/issue-33941.current.stderr b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr similarity index 100% rename from tests/ui/issues/issue-33941.current.stderr rename to tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr diff --git a/tests/ui/issues/issue-33941.next.stderr b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr similarity index 100% rename from tests/ui/issues/issue-33941.next.stderr rename to tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr diff --git a/tests/ui/issues/issue-33941.rs b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs similarity index 100% rename from tests/ui/issues/issue-33941.rs rename to tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs diff --git a/tests/ui/issues/issue-34751.rs b/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs similarity index 100% rename from tests/ui/issues/issue-34751.rs rename to tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs diff --git a/tests/ui/issues/issue-35423.rs b/tests/ui/match/range-arm-and-ref-arm.rs similarity index 100% rename from tests/ui/issues/issue-35423.rs rename to tests/ui/match/range-arm-and-ref-arm.rs diff --git a/tests/ui/issues/issue-33504.rs b/tests/ui/shadowed/shadow-unit-struct-in-closure.rs similarity index 100% rename from tests/ui/issues/issue-33504.rs rename to tests/ui/shadowed/shadow-unit-struct-in-closure.rs diff --git a/tests/ui/issues/issue-33504.stderr b/tests/ui/shadowed/shadow-unit-struct-in-closure.stderr similarity index 100% rename from tests/ui/issues/issue-33504.stderr rename to tests/ui/shadowed/shadow-unit-struct-in-closure.stderr diff --git a/tests/ui/issues/issue-3447.rs b/tests/ui/structs-enums/generic-recursive-list-struct.rs similarity index 100% rename from tests/ui/issues/issue-3447.rs rename to tests/ui/structs-enums/generic-recursive-list-struct.rs diff --git a/tests/ui/issues/issue-33770.rs b/tests/ui/threads-sendsync/no-double-lock-same-thread.rs similarity index 100% rename from tests/ui/issues/issue-33770.rs rename to tests/ui/threads-sendsync/no-double-lock-same-thread.rs From f566a8a937919a7b4397265399f5b120cb3014ac Mon Sep 17 00:00:00 2001 From: zedddie Date: Tue, 7 Jul 2026 23:24:05 +0200 Subject: [PATCH 02/12] bless batch --- .../unconstrained-dyn-assoc-type-lifetime.rs | 2 ++ .../unconstrained-dyn-assoc-type-lifetime.stderr | 2 +- tests/ui/binding/tuple-binder-on-err-ty.rs | 3 +++ tests/ui/binding/tuple-binder-on-err-ty.stderr | 6 +++--- tests/ui/errors/error-count.rs | 4 ++++ tests/ui/errors/error-count.stderr | 6 +++--- .../ui/generics/cyclic-default-type-param-via-alias.rs | 3 +++ .../cyclic-default-type-param-via-alias.stderr | 6 +++--- ...oned-hashmap-iter-type-mismatch-diag.current.stderr | 6 +++--- .../cloned-hashmap-iter-type-mismatch-diag.next.stderr | 6 +++--- .../cloned-hashmap-iter-type-mismatch-diag.rs | 3 +++ tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs | 7 ++++--- tests/ui/match/range-arm-and-ref-arm.rs | 3 +++ tests/ui/shadowed/shadow-unit-struct-in-closure.rs | 3 ++- tests/ui/shadowed/shadow-unit-struct-in-closure.stderr | 2 +- .../ui/structs-enums/generic-recursive-list-struct.rs | 3 +++ .../ui/threads-sendsync/no-double-lock-same-thread.rs | 10 ++++++++++ 17 files changed, 54 insertions(+), 21 deletions(-) diff --git a/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs index e462f35437358..bce0a3729a820 100644 --- a/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs +++ b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs @@ -1,3 +1,5 @@ +//! Regression test for . + use std::fmt; pub trait MethodType { diff --git a/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr index 4568b9b70f412..73663e85ef37c 100644 --- a/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr +++ b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr @@ -1,5 +1,5 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-35139.rs:9:6 + --> $DIR/unconstrained-dyn-assoc-type-lifetime.rs:11:6 | LL | impl<'a> MethodType for MTFn { | ^^ unconstrained lifetime parameter diff --git a/tests/ui/binding/tuple-binder-on-err-ty.rs b/tests/ui/binding/tuple-binder-on-err-ty.rs index 51486bc40de0c..3357dd42f4e35 100644 --- a/tests/ui/binding/tuple-binder-on-err-ty.rs +++ b/tests/ui/binding/tuple-binder-on-err-ty.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test tuple pattern syntax doesn't ICE on erroneous type. + fn main () { let sr: Vec<(u32, _, _) = vec![]; //~^ ERROR expected one of diff --git a/tests/ui/binding/tuple-binder-on-err-ty.stderr b/tests/ui/binding/tuple-binder-on-err-ty.stderr index 6bf6732311fcf..f8f9cd73035d6 100644 --- a/tests/ui/binding/tuple-binder-on-err-ty.stderr +++ b/tests/ui/binding/tuple-binder-on-err-ty.stderr @@ -1,5 +1,5 @@ error: expected one of `,`, `:`, or `>`, found `=` - --> $DIR/issue-34334.rs:2:29 + --> $DIR/tuple-binder-on-err-ty.rs:5:29 | LL | let sr: Vec<(u32, _, _) = vec![]; | - ^ expected one of `,`, `:`, or `>` @@ -12,7 +12,7 @@ LL | let sr: Vec<(u32, _, _)> = vec![]; | + error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()` - --> $DIR/issue-34334.rs:5:87 + --> $DIR/tuple-binder-on-err-ty.rs:8:87 | LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` @@ -22,7 +22,7 @@ help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL = help: for that trait implementation, expected `(u32, _, _)`, found `()` note: the method call chain might not have had the expected associated types - --> $DIR/issue-34334.rs:5:43 + --> $DIR/tuple-binder-on-err-ty.rs:8:43 | LL | let sr: Vec<(u32, _, _) = vec![]; | ------ this expression has type `Vec<(_, _, _)>` diff --git a/tests/ui/errors/error-count.rs b/tests/ui/errors/error-count.rs index 74f21eff20f69..08eb56bc2040d 100644 --- a/tests/ui/errors/error-count.rs +++ b/tests/ui/errors/error-count.rs @@ -1,3 +1,7 @@ +//! Regression test for . +//! Test rustc emits right error count. +//! (this used to return `aborting due to 2 previous errors`) + fn main() { a; //~ ERROR cannot find value `a` "".lorem; //~ ERROR no field diff --git a/tests/ui/errors/error-count.stderr b/tests/ui/errors/error-count.stderr index ee9f4d4c3016d..e53c2c5882c47 100644 --- a/tests/ui/errors/error-count.stderr +++ b/tests/ui/errors/error-count.stderr @@ -1,17 +1,17 @@ error[E0425]: cannot find value `a` in this scope - --> $DIR/issue-33525.rs:2:5 + --> $DIR/error-count.rs:6:5 | LL | a; | ^ not found in this scope error[E0609]: no field `lorem` on type `&'static str` - --> $DIR/issue-33525.rs:3:8 + --> $DIR/error-count.rs:7:8 | LL | "".lorem; | ^^^^^ unknown field error[E0609]: no field `ipsum` on type `&'static str` - --> $DIR/issue-33525.rs:4:8 + --> $DIR/error-count.rs:8:8 | LL | "".ipsum; | ^^^^^ unknown field diff --git a/tests/ui/generics/cyclic-default-type-param-via-alias.rs b/tests/ui/generics/cyclic-default-type-param-via-alias.rs index 02e1048e5a330..ae83dfc7c6f74 100644 --- a/tests/ui/generics/cyclic-default-type-param-via-alias.rs +++ b/tests/ui/generics/cyclic-default-type-param-via-alias.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test cyclic default type param through alias doesn't ICE. + #![allow(warnings)] //@ ignore-parallel-frontend query cycle trait Trait { diff --git a/tests/ui/generics/cyclic-default-type-param-via-alias.stderr b/tests/ui/generics/cyclic-default-type-param-via-alias.stderr index 9f85e4d5e5a93..4d05d45286529 100644 --- a/tests/ui/generics/cyclic-default-type-param-via-alias.stderr +++ b/tests/ui/generics/cyclic-default-type-param-via-alias.stderr @@ -1,17 +1,17 @@ error[E0391]: cycle detected when computing type of `Foo::T` - --> $DIR/issue-34373.rs:7:34 + --> $DIR/cyclic-default-type-param-via-alias.rs:10:34 | LL | pub struct Foo>>; | ^^^^^^^^^^ | note: ...which requires expanding type alias `DefaultFoo`... - --> $DIR/issue-34373.rs:9:19 + --> $DIR/cyclic-default-type-param-via-alias.rs:12:19 | LL | type DefaultFoo = Foo; | ^^^ = note: ...which again requires computing type of `Foo::T`, completing the cycle note: cycle used when checking that `Foo` is well-formed - --> $DIR/issue-34373.rs:7:1 + --> $DIR/cyclic-default-type-param-via-alias.rs:10:1 | LL | pub struct Foo>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr index d653bbd327427..9ceacdc7bfbdd 100644 --- a/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr +++ b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr @@ -1,5 +1,5 @@ error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:36 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:36 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^ expected `&_`, found `(&_, &_)` @@ -7,7 +7,7 @@ LL | for _ in HashMap::new().iter().cloned() {} = note: expected reference `&_` found tuple `(&_, &_)` note: the method call chain might not have had the expected associated types - --> $DIR/issue-33941.rs:9:29 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:29 | LL | for _ in HashMap::new().iter().cloned() {} | -------------- ^^^^^^ `Iterator::Item` is `(&_, &_)` here @@ -17,7 +17,7 @@ note: required by a bound in `cloned` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:14 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:14 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `(&_, &_)` diff --git a/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr index d653bbd327427..9ceacdc7bfbdd 100644 --- a/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr +++ b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr @@ -1,5 +1,5 @@ error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:36 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:36 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^ expected `&_`, found `(&_, &_)` @@ -7,7 +7,7 @@ LL | for _ in HashMap::new().iter().cloned() {} = note: expected reference `&_` found tuple `(&_, &_)` note: the method call chain might not have had the expected associated types - --> $DIR/issue-33941.rs:9:29 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:29 | LL | for _ in HashMap::new().iter().cloned() {} | -------------- ^^^^^^ `Iterator::Item` is `(&_, &_)` here @@ -17,7 +17,7 @@ note: required by a bound in `cloned` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:14 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:14 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `(&_, &_)` diff --git a/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs index e49efc3bfd496..de402fbb7fba5 100644 --- a/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs +++ b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test iterator type mismatch prints pretty error message. +//! This used to emit many duplicated, unhelpful error messages. //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver diff --git a/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs b/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs index 1e842049b14c1..b9eebc8dac0f2 100644 --- a/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs +++ b/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs @@ -1,8 +1,9 @@ +//! Regression test for . +//! This used to ICE with +//! `assertion failed: !substs.has_regions_escaping_depth(0)`. //@ check-pass -#![allow(dead_code)] -// #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)' -#[allow(dead_code)] +#![allow(dead_code)] use std::marker::PhantomData; diff --git a/tests/ui/match/range-arm-and-ref-arm.rs b/tests/ui/match/range-arm-and-ref-arm.rs index c43d35fea7837..d5a797aa1aaeb 100644 --- a/tests/ui/match/range-arm-and-ref-arm.rs +++ b/tests/ui/match/range-arm-and-ref-arm.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! This used to ICE. //@ run-pass + fn main () { let x = 4; match x { diff --git a/tests/ui/shadowed/shadow-unit-struct-in-closure.rs b/tests/ui/shadowed/shadow-unit-struct-in-closure.rs index 89cc06ede5e48..355c5f3c9f8d7 100644 --- a/tests/ui/shadowed/shadow-unit-struct-in-closure.rs +++ b/tests/ui/shadowed/shadow-unit-struct-in-closure.rs @@ -1,4 +1,5 @@ -// Shadowing a unit-like enum in a closure +//! Regression test for . +//! Test shadowing a unit-like struct in a closure doesn't cause ICE. struct Test; diff --git a/tests/ui/shadowed/shadow-unit-struct-in-closure.stderr b/tests/ui/shadowed/shadow-unit-struct-in-closure.stderr index e5a2eea751d0e..44845135c1deb 100644 --- a/tests/ui/shadowed/shadow-unit-struct-in-closure.stderr +++ b/tests/ui/shadowed/shadow-unit-struct-in-closure.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-33504.rs:7:13 + --> $DIR/shadow-unit-struct-in-closure.rs:8:13 | LL | struct Test; | ----------- unit struct defined here diff --git a/tests/ui/structs-enums/generic-recursive-list-struct.rs b/tests/ui/structs-enums/generic-recursive-list-struct.rs index ab844b0bb9061..f91cffecaa675 100644 --- a/tests/ui/structs-enums/generic-recursive-list-struct.rs +++ b/tests/ui/structs-enums/generic-recursive-list-struct.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! This used to overflow stack. //@ run-pass + #![allow(dead_code)] #![allow(non_snake_case)] #![allow(non_camel_case_types)] diff --git a/tests/ui/threads-sendsync/no-double-lock-same-thread.rs b/tests/ui/threads-sendsync/no-double-lock-same-thread.rs index 814e8f371765e..278ff0242950e 100644 --- a/tests/ui/threads-sendsync/no-double-lock-same-thread.rs +++ b/tests/ui/threads-sendsync/no-double-lock-same-thread.rs @@ -1,3 +1,13 @@ +//! Regression test for . +//! Ensure both `Mutex` and `RwLock` cannot be locked twice on same +//! thread. +//! +//! This was possible as mutexes were initialized with `PTHREAD_MUTEX_DEFAULT` +//! for which attempt to relock from the same thread is considered undefined +//! behaviour, and during glibc's lock-elision transaction lock appeared +//! unlocked, which allowed to lock it again from the same thread. +//! +//! This resulted in ability to aquire 2 mutable references at the same time. //@ run-pass //@ needs-subprocess From 8bb04f6b4cd36229ddd8e5199e06c3e87ca8589e Mon Sep 17 00:00:00 2001 From: Amirhossein Akhlaghpour Date: Wed, 8 Jul 2026 20:35:40 +0330 Subject: [PATCH 03/12] chore: add codegen test for Result is_ok unwrap Signed-off-by: Amirhossein Akhlaghpour --- .../issues/result-is-ok-unwrap.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/codegen-llvm/issues/result-is-ok-unwrap.rs diff --git a/tests/codegen-llvm/issues/result-is-ok-unwrap.rs b/tests/codegen-llvm/issues/result-is-ok-unwrap.rs new file mode 100644 index 0000000000000..ffcbb0ae142d9 --- /dev/null +++ b/tests/codegen-llvm/issues/result-is-ok-unwrap.rs @@ -0,0 +1,20 @@ +// Checking `Result::is_ok()` should make a following `unwrap()` branch-free. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +use std::hint::black_box; + +// CHECK-LABEL: @unwrap_after_is_ok +#[no_mangle] +pub fn unwrap_after_is_ok(arg: Result) { + // CHECK-NOT: unwrap_failed + // CHECK-NOT: panic + if arg.is_ok() { + let value = arg.unwrap(); + if value == 42 { + black_box(value); + } + } +} From eee2b6db50b8380066c86470ae401efd85023f79 Mon Sep 17 00:00:00 2001 From: zedddie Date: Wed, 8 Jul 2026 23:26:34 +0200 Subject: [PATCH 04/12] move batch --- .../issue-36474.rs => codegen/slice-iter-enumerate-opt.rs} | 0 .../issue-3559.rs => collections/hashmap/hashmap-debug-format.rs} | 0 .../no-spurious-unconstrained-param.rs} | 0 .../no-spurious-unconstrained-param.stderr} | 0 .../issue-36299.rs => generics/unused-type-and-lifetime-param.rs} | 0 .../unused-type-and-lifetime-param.stderr} | 0 .../assoc-type-projection-in-dyn-and-fn.rs} | 0 .../assoc-type-projection-in-dyn-and-fn.stderr} | 0 .../lifetime-param-in-fn-coercion.rs} | 0 .../{issues/issue-36816.rs => macros/macro-in-array-len-expr.rs} | 0 tests/ui/{issues/issue-3574.rs => match/match-borrowed-str.rs} | 0 .../trait-object-import-suggestion-on-method.rs} | 0 .../trait-object-import-suggestion-on-method.unimported.stderr} | 0 .../obligation-error-propagation.rs} | 0 .../obligation-error-propagation.stderr} | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-36474.rs => codegen/slice-iter-enumerate-opt.rs} (100%) rename tests/ui/{issues/issue-3559.rs => collections/hashmap/hashmap-debug-format.rs} (100%) rename tests/ui/{issues/issue-36836.rs => derived-errors/no-spurious-unconstrained-param.rs} (100%) rename tests/ui/{issues/issue-36836.stderr => derived-errors/no-spurious-unconstrained-param.stderr} (100%) rename tests/ui/{issues/issue-36299.rs => generics/unused-type-and-lifetime-param.rs} (100%) rename tests/ui/{issues/issue-36299.stderr => generics/unused-type-and-lifetime-param.stderr} (100%) rename tests/ui/{issues/issue-35570.rs => higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs} (100%) rename tests/ui/{issues/issue-35570.stderr => higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr} (100%) rename tests/ui/{issues/issue-36744-bitcast-args-if-needed.rs => lifetimes/lifetime-param-in-fn-coercion.rs} (100%) rename tests/ui/{issues/issue-36816.rs => macros/macro-in-array-len-expr.rs} (100%) rename tests/ui/{issues/issue-3574.rs => match/match-borrowed-str.rs} (100%) rename tests/ui/{issues/issue-35976.rs => suggestions/trait-object-import-suggestion-on-method.rs} (100%) rename tests/ui/{issues/issue-35976.unimported.stderr => suggestions/trait-object-import-suggestion-on-method.unimported.stderr} (100%) rename tests/ui/{issues/issue-34503.rs => where-clauses/obligation-error-propagation.rs} (100%) rename tests/ui/{issues/issue-34503.stderr => where-clauses/obligation-error-propagation.stderr} (100%) diff --git a/tests/ui/issues/issue-36474.rs b/tests/ui/codegen/slice-iter-enumerate-opt.rs similarity index 100% rename from tests/ui/issues/issue-36474.rs rename to tests/ui/codegen/slice-iter-enumerate-opt.rs diff --git a/tests/ui/issues/issue-3559.rs b/tests/ui/collections/hashmap/hashmap-debug-format.rs similarity index 100% rename from tests/ui/issues/issue-3559.rs rename to tests/ui/collections/hashmap/hashmap-debug-format.rs diff --git a/tests/ui/issues/issue-36836.rs b/tests/ui/derived-errors/no-spurious-unconstrained-param.rs similarity index 100% rename from tests/ui/issues/issue-36836.rs rename to tests/ui/derived-errors/no-spurious-unconstrained-param.rs diff --git a/tests/ui/issues/issue-36836.stderr b/tests/ui/derived-errors/no-spurious-unconstrained-param.stderr similarity index 100% rename from tests/ui/issues/issue-36836.stderr rename to tests/ui/derived-errors/no-spurious-unconstrained-param.stderr diff --git a/tests/ui/issues/issue-36299.rs b/tests/ui/generics/unused-type-and-lifetime-param.rs similarity index 100% rename from tests/ui/issues/issue-36299.rs rename to tests/ui/generics/unused-type-and-lifetime-param.rs diff --git a/tests/ui/issues/issue-36299.stderr b/tests/ui/generics/unused-type-and-lifetime-param.stderr similarity index 100% rename from tests/ui/issues/issue-36299.stderr rename to tests/ui/generics/unused-type-and-lifetime-param.stderr diff --git a/tests/ui/issues/issue-35570.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs similarity index 100% rename from tests/ui/issues/issue-35570.rs rename to tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs diff --git a/tests/ui/issues/issue-35570.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr similarity index 100% rename from tests/ui/issues/issue-35570.stderr rename to tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr diff --git a/tests/ui/issues/issue-36744-bitcast-args-if-needed.rs b/tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs similarity index 100% rename from tests/ui/issues/issue-36744-bitcast-args-if-needed.rs rename to tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs diff --git a/tests/ui/issues/issue-36816.rs b/tests/ui/macros/macro-in-array-len-expr.rs similarity index 100% rename from tests/ui/issues/issue-36816.rs rename to tests/ui/macros/macro-in-array-len-expr.rs diff --git a/tests/ui/issues/issue-3574.rs b/tests/ui/match/match-borrowed-str.rs similarity index 100% rename from tests/ui/issues/issue-3574.rs rename to tests/ui/match/match-borrowed-str.rs diff --git a/tests/ui/issues/issue-35976.rs b/tests/ui/suggestions/trait-object-import-suggestion-on-method.rs similarity index 100% rename from tests/ui/issues/issue-35976.rs rename to tests/ui/suggestions/trait-object-import-suggestion-on-method.rs diff --git a/tests/ui/issues/issue-35976.unimported.stderr b/tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr similarity index 100% rename from tests/ui/issues/issue-35976.unimported.stderr rename to tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr diff --git a/tests/ui/issues/issue-34503.rs b/tests/ui/where-clauses/obligation-error-propagation.rs similarity index 100% rename from tests/ui/issues/issue-34503.rs rename to tests/ui/where-clauses/obligation-error-propagation.rs diff --git a/tests/ui/issues/issue-34503.stderr b/tests/ui/where-clauses/obligation-error-propagation.stderr similarity index 100% rename from tests/ui/issues/issue-34503.stderr rename to tests/ui/where-clauses/obligation-error-propagation.stderr From 3c9b183b76abbc326798a96227d49fc40e6fd46b Mon Sep 17 00:00:00 2001 From: zedddie Date: Wed, 8 Jul 2026 23:26:44 +0200 Subject: [PATCH 05/12] bless batch --- tests/ui/codegen/slice-iter-enumerate-opt.rs | 4 ++++ .../hashmap/hashmap-debug-format.rs | 3 +++ .../no-spurious-unconstrained-param.rs | 19 ++++++++++--------- .../no-spurious-unconstrained-param.stderr | 2 +- .../unused-type-and-lifetime-param.rs | 3 +++ .../unused-type-and-lifetime-param.stderr | 4 ++-- .../assoc-type-projection-in-dyn-and-fn.rs | 4 ++++ ...assoc-type-projection-in-dyn-and-fn.stderr | 8 ++++---- .../lifetime-param-in-fn-coercion.rs | 7 ++++--- tests/ui/macros/macro-in-array-len-expr.rs | 3 +++ tests/ui/match/match-borrowed-str.rs | 4 ++-- ...rait-object-import-suggestion-on-method.rs | 3 +++ ...ort-suggestion-on-method.unimported.stderr | 2 +- .../obligation-error-propagation.rs | 4 ++++ .../obligation-error-propagation.stderr | 2 +- 15 files changed, 49 insertions(+), 23 deletions(-) diff --git a/tests/ui/codegen/slice-iter-enumerate-opt.rs b/tests/ui/codegen/slice-iter-enumerate-opt.rs index ddfa1829e3afc..21cb530953eaf 100644 --- a/tests/ui/codegen/slice-iter-enumerate-opt.rs +++ b/tests/ui/codegen/slice-iter-enumerate-opt.rs @@ -1,4 +1,8 @@ +//! Regression test for . +//! This used to trigger LLVM assertion when compiled with opt level 3. +//@ compile-flags: -Copt-level=3 //@ run-pass + fn main() { remove_axis(&3, 0); } diff --git a/tests/ui/collections/hashmap/hashmap-debug-format.rs b/tests/ui/collections/hashmap/hashmap-debug-format.rs index ffb937cf5d253..97e81db94c49c 100644 --- a/tests/ui/collections/hashmap/hashmap-debug-format.rs +++ b/tests/ui/collections/hashmap/hashmap-debug-format.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Test hashmap debug format doesn't ICE. //@ run-pass + use std::collections::HashMap; fn check_strs(actual: &str, expected: &str) -> bool { diff --git a/tests/ui/derived-errors/no-spurious-unconstrained-param.rs b/tests/ui/derived-errors/no-spurious-unconstrained-param.rs index 99c56213153e4..d56245a6ac83c 100644 --- a/tests/ui/derived-errors/no-spurious-unconstrained-param.rs +++ b/tests/ui/derived-errors/no-spurious-unconstrained-param.rs @@ -1,12 +1,13 @@ -// Previously, in addition to the real cause of the problem as seen below, -// the compiler would tell the user: -// -// ``` -// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or -// predicates -// ``` -// -// With this test, we check that only the relevant error is emitted. +//! Regression test for . +//! Previously, in addition to the real cause of the problem as seen below, +//! the compiler would tell the user: +//! +//! ``` +//! error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or +//! predicates +//! ``` +//! +//! With this test, we check that only the relevant error is emitted. trait Foo {} diff --git a/tests/ui/derived-errors/no-spurious-unconstrained-param.stderr b/tests/ui/derived-errors/no-spurious-unconstrained-param.stderr index 2d9a97df90520..0dde8afbc1c00 100644 --- a/tests/ui/derived-errors/no-spurious-unconstrained-param.stderr +++ b/tests/ui/derived-errors/no-spurious-unconstrained-param.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `Bar` in this scope - --> $DIR/issue-36836.rs:13:17 + --> $DIR/no-spurious-unconstrained-param.rs:14:17 | LL | impl Foo for Bar {} | ^^^ not found in this scope diff --git a/tests/ui/generics/unused-type-and-lifetime-param.rs b/tests/ui/generics/unused-type-and-lifetime-param.rs index 7b68420b71cb2..0ad7b087ceeee 100644 --- a/tests/ui/generics/unused-type-and-lifetime-param.rs +++ b/tests/ui/generics/unused-type-and-lifetime-param.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to ICE. + struct Foo<'a, A> {} //~^ ERROR parameter `'a` is never used //~| ERROR parameter `A` is never used diff --git a/tests/ui/generics/unused-type-and-lifetime-param.stderr b/tests/ui/generics/unused-type-and-lifetime-param.stderr index 29e8d7ca59a24..d21c44ec1fc87 100644 --- a/tests/ui/generics/unused-type-and-lifetime-param.stderr +++ b/tests/ui/generics/unused-type-and-lifetime-param.stderr @@ -1,5 +1,5 @@ error[E0392]: lifetime parameter `'a` is never used - --> $DIR/issue-36299.rs:1:12 + --> $DIR/unused-type-and-lifetime-param.rs:4:12 | LL | struct Foo<'a, A> {} | ^^ unused lifetime parameter @@ -7,7 +7,7 @@ LL | struct Foo<'a, A> {} = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` error[E0392]: type parameter `A` is never used - --> $DIR/issue-36299.rs:1:16 + --> $DIR/unused-type-and-lifetime-param.rs:4:16 | LL | struct Foo<'a, A> {} | ^ unused type parameter diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs index a2b0222d4f395..da83fe0a7ba04 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs @@ -1,3 +1,7 @@ +//! Regression test for . +//! Test associated type projection under `for<'a>` binder in the return +//! type of fn parameter and inside trait object doesn't ICE. + use std::mem; trait Trait1 {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr index b39b15fdf4b10..2aeca47b2ebb9 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:40 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:12:40 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/issue-35570.rs:4:1 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:8:1 | LL | trait Trait2<'a> { | ^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:16 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:12:16 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/issue-35570.rs:4:1 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:8:1 | LL | trait Trait2<'a> { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs b/tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs index 8fcd0c3f41c9a..7f8af7e6b49d4 100644 --- a/tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs +++ b/tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs @@ -1,7 +1,8 @@ +//! Regression test for . +//! This tests for an ICE (and, if ignored, subsequent LLVM abort) when +//! a lifetime-parametric fn is passed into a context whose expected +//! type has a differing lifetime parameterization. //@ run-pass -// This tests for an ICE (and, if ignored, subsequent LLVM abort) when -// a lifetime-parametric fn is passed into a context whose expected -// type has a differing lifetime parameterization. struct A<'a> { _a: &'a i32, diff --git a/tests/ui/macros/macro-in-array-len-expr.rs b/tests/ui/macros/macro-in-array-len-expr.rs index d15a9c7abe15b..272ee7f90cecc 100644 --- a/tests/ui/macros/macro-in-array-len-expr.rs +++ b/tests/ui/macros/macro-in-array-len-expr.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Macro invocation in len position in arrays used to ICE. //@ run-pass + macro_rules! m { () => { 1 } } macro_rules! n { () => { 1 + m!() } } diff --git a/tests/ui/match/match-borrowed-str.rs b/tests/ui/match/match-borrowed-str.rs index 36c1e2ad93ee8..48597ed2c18f1 100644 --- a/tests/ui/match/match-borrowed-str.rs +++ b/tests/ui/match/match-borrowed-str.rs @@ -1,6 +1,6 @@ +//! Regression test for . +//! Test pattern-matching on `&str` doesn't ICE. //@ run-pass -// rustc --test match_borrowed_str.rs.rs && ./match_borrowed_str.rs - fn compare(x: &str, y: &str) -> bool { match x { diff --git a/tests/ui/suggestions/trait-object-import-suggestion-on-method.rs b/tests/ui/suggestions/trait-object-import-suggestion-on-method.rs index 03d4a187f5557..d3600188e822d 100644 --- a/tests/ui/suggestions/trait-object-import-suggestion-on-method.rs +++ b/tests/ui/suggestions/trait-object-import-suggestion-on-method.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to emit spurious `Sized` bound unsatisfied error when trait +//! was not imported, instead of suggestion to import it. //@ edition:2015 //@ revisions: imported unimported //@[imported] check-pass diff --git a/tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr b/tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr index db2973d902efb..5f5e4b7f47294 100644 --- a/tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr +++ b/tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr @@ -1,5 +1,5 @@ error: the `wait` method cannot be invoked on a trait object - --> $DIR/issue-35976.rs:21:9 + --> $DIR/trait-object-import-suggestion-on-method.rs:24:9 | LL | fn wait(&self) where Self: Sized; | ----- this has a `Sized` requirement diff --git a/tests/ui/where-clauses/obligation-error-propagation.rs b/tests/ui/where-clauses/obligation-error-propagation.rs index 68d84bae3d859..501d89e6162d4 100644 --- a/tests/ui/where-clauses/obligation-error-propagation.rs +++ b/tests/ui/where-clauses/obligation-error-propagation.rs @@ -1,4 +1,8 @@ +//! Regression test for . +//! `(T, Option)` falsly marked Option as proved when T failed, +//! this made use of invalid Option bound possible anywhere. //@ run-pass + fn main() { struct X; trait Foo { diff --git a/tests/ui/where-clauses/obligation-error-propagation.stderr b/tests/ui/where-clauses/obligation-error-propagation.stderr index 1877e20bbc14d..a796002caf951 100644 --- a/tests/ui/where-clauses/obligation-error-propagation.stderr +++ b/tests/ui/where-clauses/obligation-error-propagation.stderr @@ -1,5 +1,5 @@ warning: methods `foo` and `bar` are never used - --> $DIR/issue-34503.rs:5:12 + --> $DIR/obligation-error-propagation.rs:9:12 | LL | trait Foo { | --- methods in this trait From 87bb7c92132495b7cb0d476bc11b10ac27c2ea24 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Wed, 24 Jun 2026 14:24:27 +0800 Subject: [PATCH 06/12] codegen_ssa: pack small const aggregates into immediate stores For small repr(C) aggregates with padding, direct constant initialization can still lower into field-wise construction plus memcpy. That leaves the backend to rediscover that the whole object is a single constant byte pattern. This is especially visible for non-zero constant aggregates. Instead of materializing them as separate field stores, we want codegen_ssa to emit the packed value directly. For example, a value like InnerPadded { a: 0, b: 1, c: 0 } can otherwise lower to something like store i16 0, ptr %val, align 4 store i8 1, ptr %val_plus_2, align 2 store i32 0, ptr %val_plus_4, align 4 call void @llvm.memcpy(..., ptr %val, ...) while this change produces store i64 65536, ptr %val, align 4 call void @llvm.memcpy(..., ptr %val, ...) Why not solve this in LLVM? At the problematic lowering point, rustc still knows that the MIR aggregate is small and fully constant. LLVM only sees a lowered stack temporary built from per-field stores and then copied out. Recovering that packed constant there would require rediscovering front-end aggregate semantics after lowering, so emitting the packed store in rustc is the simpler and more local fix. Why not keep the previous typed-copy approach? An earlier approach zeroed padding on typed copies whose source could be traced back to a constant assignment. That helped some cases, but it also widened the optimization to runtime copy paths and could introduce extra runtime stores purely to maintain padding knowledge. That is not an acceptable tradeoff here. Keep the scope narrow instead: only handle direct MIR aggregates whose fields are all constants, and pack them according to the target endianness before emitting a single integer store. Add a focused codegen test covering the original PR 157690 entry points together with non-zero constant cases. The test uses -Cno-prepopulate-passes so it checks the immediate-store shape directly at rustc codegen time, instead of depending on later LLVM store merging. --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 78 ++++++ tests/codegen-llvm/aggregate-padding-zero.rs | 244 +++++++++++++++++++ 2 files changed, 322 insertions(+) create mode 100644 tests/codegen-llvm/aggregate-padding-zero.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 469d6af12923e..7ad747689c44d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -1,5 +1,6 @@ use itertools::Itertools as _; use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT}; +use rustc_index::IndexVec; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; @@ -15,6 +16,79 @@ use crate::traits::*; use crate::{MemFlags, base}; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { + fn try_codegen_const_aggregate_as_immediate( + &mut self, + bx: &mut Bx, + dest: PlaceRef<'tcx, Bx::Value>, + kind: &mir::AggregateKind<'tcx>, + operands: &IndexVec>, + ) -> bool { + // Keep this allowlist limited to aggregate kinds with direct codegen coverage. + // Extract the variant index at the same time so we can verify it against + // the layout below. Tuples always use `FIRST_VARIANT` (index 0); the + // `None` in the `Adt` arm excludes unions (which carry an active field). + let variant_index = match kind { + mir::AggregateKind::Tuple => FIRST_VARIANT, + mir::AggregateKind::Adt(_, variant_index, _, _, None) => *variant_index, + _ => return false, + }; + if !matches!(dest.layout.fields, abi::FieldsShape::Arbitrary { .. }) { + return false; + } + // `dest.layout` is the layout of the *overall* type, not a specific + // variant. When the layout is `Variants::Single { index: M }`, the + // field offsets and counts below all refer to variant M. If the MIR + // aggregate is constructing a different variant N (e.g. because N is + // uninhabited and the layout collapsed to M), using `dest.layout` + // directly would read the wrong field metadata. Bail out and let the + // normal codegen path handle it via `project_downcast`. + if !matches!(dest.layout.variants, abi::Variants::Single { index } if index == variant_index) + { + return false; + } + // Now that the variant indices are known to match, the operand count + // and the layout field count must agree. + debug_assert_eq!(operands.len(), dest.layout.fields.count()); + + let size = dest.layout.size.bytes(); + let llty = match size { + 1 => bx.cx().type_i8(), + 2 => bx.cx().type_i16(), + 4 => bx.cx().type_i32(), + 8 => bx.cx().type_i64(), + 16 => bx.cx().type_i128(), + _ => return false, + }; + + let mut value = 0u128; + for (field_idx, operand) in operands.iter_enumerated() { + let field_layout = dest.layout.field(bx.cx(), field_idx.as_usize()); + if field_layout.is_zst() { + continue; + } + let mir::Operand::Constant(constant) = operand else { + return false; + }; + let Some(field_value) = self.eval_mir_constant(constant).try_to_bits(field_layout.size) + else { + return false; + }; + + let field_size = field_layout.size.bytes(); + let field_offset = dest.layout.fields.offset(field_idx.as_usize()).bytes(); + debug_assert!(field_offset + field_size <= size); + let shift = match bx.tcx().data_layout.endian { + abi::Endian::Little => field_offset * 8, + abi::Endian::Big => (size - field_offset - field_size) * 8, + }; + value |= field_value << shift; + } + + let value = bx.cx().const_uint_big(llty, value); + bx.store_to_place(value, dest.val); + true + } + #[instrument(level = "trace", skip(self, bx))] pub(crate) fn codegen_rvalue( &mut self, @@ -168,6 +242,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Aggregate(ref kind, ref operands) if !matches!(**kind, mir::AggregateKind::RawPtr(..)) => { + if self.try_codegen_const_aggregate_as_immediate(bx, dest, kind, operands) { + return; + } + let (variant_index, variant_dest, active_field_index) = match **kind { mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { let variant_dest = dest.project_downcast(bx, variant_index); diff --git a/tests/codegen-llvm/aggregate-padding-zero.rs b/tests/codegen-llvm/aggregate-padding-zero.rs new file mode 100644 index 0000000000000..8455b1d8583a5 --- /dev/null +++ b/tests/codegen-llvm/aggregate-padding-zero.rs @@ -0,0 +1,244 @@ +//@ add-minicore +//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Z merge-functions=disabled -Z randomize-layout=no +//@ revisions: powerpc64 x86_64 +//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//@[powerpc64] needs-llvm-components: powerpc +//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64] needs-llvm-components: x86 + +// Regression test for . +// +// These cases specifically exercise direct codegen of small non-zero constant +// aggregates as a single integer store. They are chosen so they fail without +// `try_codegen_const_aggregate_as_immediate`. + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; + +use minicore::*; + +#[inline(always)] +unsafe fn ptr_write(dest: *mut T, value: T) { + *dest = value; +} + +trait MaybeUninitExt { + fn as_mut_ptr(&mut self) -> *mut T; + fn write(&mut self, value: T); +} + +impl MaybeUninitExt for MaybeUninit { + fn as_mut_ptr(&mut self) -> *mut T { + self as *mut _ as *mut T + } + + fn write(&mut self, value: T) { + unsafe { + ptr_write(self.as_mut_ptr(), value); + } + } +} + +// Inner padding between b (offset 2, size 1) and c (offset 4, size 4). +#[repr(C)] +pub struct InnerPadded { + a: u16, + b: u8, + c: u32, +} + +#[repr(transparent)] +pub struct Nested1(InnerPadded); + +#[repr(transparent)] +pub struct Nested2(Nested1); + +// PR 157690's original ptr::write entry point, checked against the current +// aggregate-immediate codegen shape. +// CHECK-LABEL: @via_ptr_write( +#[no_mangle] +pub fn via_ptr_write(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 0, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // CHECK-NEXT: store i64 0, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest.as_mut_ptr(), val); + } +} + +// PR 157690's original MaybeUninit::write entry point. +// CHECK-LABEL: @via_maybe_uninit_write( +#[no_mangle] +pub fn via_maybe_uninit_write(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 0, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // CHECK-NEXT: store i64 0, ptr %val, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %{{.*}}, i64 8, i1 false) + dest.write(val); +} + +// Constant non-zero initialization: emitted as a single store including zero padding. +// CHECK-LABEL: @const_init_non_zero( +#[no_mangle] +pub fn const_init_non_zero(dest: *mut InnerPadded) { + let val = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 65536, ptr %val, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest, val); + } +} + +// From issue #157373: nesting wrapper structs used to change the lowering +// shape enough that LLVM would sometimes find the wide store only in the +// nested case. +// CHECK-LABEL: @bad( +#[no_mangle] +pub fn bad(a: &mut InnerPadded) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // x86_64: store i64 65536, ptr %x, align 4 + // powerpc64: store i64 1099511627776, ptr %x, align 4 + *a = x; +} + +// CHECK-LABEL: @good( +#[no_mangle] +pub fn good(a: &mut Nested2) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // x86_64: store i64 65536, ptr %x, align 4 + // powerpc64: store i64 1099511627776, ptr %x, align 4 + *a = Nested2(Nested1(x)); +} + +// The same direct constant aggregate packing should apply through ptr::write on MaybeUninit. +// CHECK-LABEL: @via_ptr_write_non_zero( +#[no_mangle] +pub fn via_ptr_write_non_zero(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 65536, ptr %val, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest.as_mut_ptr(), val); + } +} + +// The same direct constant aggregate packing should apply through MaybeUninit::write. +// CHECK-LABEL: @via_maybe_uninit_write_non_zero( +#[no_mangle] +pub fn via_maybe_uninit_write_non_zero(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 65536, ptr %val, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %val, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %{{.*}}, i64 8, i1 false) + dest.write(val); +} + +// CHECK-LABEL: @bad_non_zero( +#[no_mangle] +pub fn bad_non_zero(a: &mut InnerPadded) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %x = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %x) + // x86_64-NEXT: store i64 65536, ptr %x, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %x, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %x, i64 8, i1 false) + *a = x; +} + +// CHECK-LABEL: @good_non_zero( +#[no_mangle] +pub fn good_non_zero(a: &mut Nested2) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %x = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %x) + // x86_64-NEXT: store i64 65536, ptr %x, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %x, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %{{.*}}, i64 8, i1 false) + *a = Nested2(Nested1(x)); +} + +// Trailing padding only (no inter-field padding): a (offset 0, size 4), +// b (offset 4, size 2), c (offset 6, size 1), trailing pad (offset 7, size 1). +#[repr(C)] +pub struct TailOnly { + a: u32, + b: u16, + c: u8, +} + +type TupleTailOnly = (u32, u16, u8); + +// PR 157690's trailing-padding-only entry point. +// CHECK-LABEL: @tail_only_write( +#[no_mangle] +pub fn tail_only_write(dest: &mut MaybeUninit) { + let val = TailOnly { a: 0, b: 0, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // CHECK-NEXT: store i64 0, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest.as_mut_ptr(), val); + } +} + +// Tuple aggregates should use the same const-packing path as structs when the +// whole tuple is constant and small enough to fit in an integer store. +// CHECK-LABEL: @tuple_tail_only_non_zero( +#[no_mangle] +pub fn tuple_tail_only_non_zero(dest: *mut TupleTailOnly) { + let val: TupleTailOnly = (0, 1, 0); + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 4294967296, ptr %val, align 4 + // powerpc64-NEXT: store i64 65536, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest, val); + } +} + +// Regression test for the debug assertion failure in +// `try_codegen_const_aggregate_as_immediate` when the MIR aggregate's +// variant index doesn't match the layout's `Variants::Single { index }`. +// +// When `Data(Void)` is uninhabited, the layout of `E` collapses to +// `Variants::Single { index: 0 }` (only `Empty`). But generic code +// monomorphized with `T = Void` still contains an aggregate for `Data(x)` +// with 1 operand. The optimization must bail out gracefully instead of +// asserting `operands.len() == dest.layout.fields.count()` (1 == 0). +// +// See . +enum Void {} + +enum E { + Empty, + Data(T), +} + +#[inline(never)] +fn make_data(x: T) -> E { + E::Data(x) +} + +// Force codegen of `make_data::`. Without the variant index check, +// this triggers: assertion `left == right` failed (left: 1, right: 0). +// CHECK-LABEL: @force_variant_mismatch( +#[no_mangle] +pub fn force_variant_mismatch() -> fn(Void) -> E { + make_data:: +} From 79b72317fd2b6730b838fa63cb1cf10fa6a4af5a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 9 Jul 2026 12:27:19 +0200 Subject: [PATCH 07/12] Use `as_lang_item` instead of repeatedly matching --- .../src/coherence/builtin.rs | 46 +++++++------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 4ff870b405e5a..ecc7b170818d2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -34,44 +34,30 @@ pub(super) fn check_trait<'tcx>( impl_def_id: LocalDefId, impl_header: ty::ImplTraitHeader<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let lang_items = tcx.lang_items(); - let checker = Checker { tcx, trait_def_id, impl_def_id, impl_header }; - checker.check(lang_items.drop_trait(), visit_implementation_of_drop)?; - checker.check(lang_items.async_drop_trait(), visit_implementation_of_drop)?; - checker.check(lang_items.copy_trait(), visit_implementation_of_copy)?; - checker.check(lang_items.unpin_trait(), visit_implementation_of_unpin)?; - checker.check(lang_items.const_param_ty_trait(), |checker| { - visit_implementation_of_const_param_ty(checker) - })?; - checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)?; - checker.check(lang_items.reborrow(), visit_implementation_of_reborrow)?; - checker.check(lang_items.coerce_shared(), visit_implementation_of_coerce_shared)?; - checker - .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?; - checker.check( - lang_items.coerce_pointee_validated_trait(), - visit_implementation_of_coerce_pointee_validity, - )?; - Ok(()) + let checker = Checker { tcx, impl_def_id, impl_header }; + match tcx.as_lang_item(trait_def_id) { + Some(LangItem::Drop) => visit_implementation_of_drop(&checker), + Some(LangItem::AsyncDrop) => visit_implementation_of_drop(&checker), + Some(LangItem::Copy) => visit_implementation_of_copy(&checker), + Some(LangItem::Unpin) => visit_implementation_of_unpin(&checker), + Some(LangItem::ConstParamTy) => visit_implementation_of_const_param_ty(&checker), + Some(LangItem::CoerceUnsized) => visit_implementation_of_coerce_unsized(&checker), + Some(LangItem::Reborrow) => visit_implementation_of_reborrow(&checker), + Some(LangItem::CoerceShared) => visit_implementation_of_coerce_shared(&checker), + Some(LangItem::DispatchFromDyn) => visit_implementation_of_dispatch_from_dyn(&checker), + Some(LangItem::CoercePointeeValidated) => { + visit_implementation_of_coerce_pointee_validity(&checker) + } + _ => Ok(()), + } } struct Checker<'tcx> { tcx: TyCtxt<'tcx>, - trait_def_id: DefId, impl_def_id: LocalDefId, impl_header: ty::ImplTraitHeader<'tcx>, } -impl<'tcx> Checker<'tcx> { - fn check( - &self, - trait_def_id: Option, - f: impl FnOnce(&Self) -> Result<(), ErrorGuaranteed>, - ) -> Result<(), ErrorGuaranteed> { - if Some(self.trait_def_id) == trait_def_id { f(self) } else { Ok(()) } - } -} - fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; let impl_did = checker.impl_def_id; From 299a71d751139b1f269cd0f888b4f409f1505890 Mon Sep 17 00:00:00 2001 From: Calvin Prewitt Date: Thu, 9 Jul 2026 15:57:47 -0500 Subject: [PATCH 08/12] resolve: fix effective visibilities for items in ambiguous glob sets Since PR 154149, when one item is glob-imported into a module twice with different visibilities, the first-arrived declaration stays in the resolution slot and the most visible declaration of the ambiguous glob set is only recorded in `ambiguity_vis_max`. `DeclData::vis()` returns the max, so name resolution, metadata reexports and `cross_crate_inlinable` export the item at the maximum visibility, but `set_bindings_effective_visibilities` walked only the slot-resident declaration's reexport chain. When the restricted route arrives first, the definition's effective visibility caps at the restricted visibility while the item is still exported: spurious dead_code, the item missing from reachable_set, should_encode_mir returning false, and downstream crates failing with "missing optimized MIR" (a 1.96.1 -> 1.97.0 stable-to-stable regression). Generalize the one-level `ambiguity_vis_max` update that PR 154149 added in `update_import` (to keep the most visible import from being reported as unused) into a walk of that declaration's whole reexport chain: extract the chain walk into `update_decl_chain` and recurse into `ambiguity_vis_max` at every hop, so the most visible declaration drives the effective visibility of everything on its route, including the final definition. Updates are monotone, so the dual walk is order-independent. The `ambiguous_import_visibilities` lint and the PR 156284 diagnostic suppression are untouched. --- .../src/effective_visibilities.rs | 54 +++++++++++-------- ...mbiguous-import-visibility-globglob-mir.rs | 20 +++++++ ...us-import-visibility-globglob-reachable.rs | 26 +++++++++ ...mport-visibility-globglob-reachable.stderr | 8 +++ ...mbiguous-import-visibility-globglob-mir.rs | 19 +++++++ 5 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 tests/ui/imports/ambiguous-import-visibility-globglob-mir.rs create mode 100644 tests/ui/imports/ambiguous-import-visibility-globglob-reachable.rs create mode 100644 tests/ui/imports/ambiguous-import-visibility-globglob-reachable.stderr create mode 100644 tests/ui/imports/auxiliary/ambiguous-import-visibility-globglob-mir.rs diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index e20c86d65af3f..8f051cf02d41c 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -125,26 +125,42 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) { let module = self.r.expect_module(module_id.to_def_id()); for (_, name_resolution) in self.r.resolutions(module).borrow().iter() { - let Some(mut decl) = name_resolution.borrow().best_decl() else { + let Some(decl) = name_resolution.borrow().best_decl() else { continue; }; - // Set the given effective visibility level to `Level::Direct` and - // sets the rest of the `use` chain to `Level::Reexported` until - // we hit the actual exported item. - let priv_vis = |this: &Self, parent_id, decl| match parent_id { - ParentId::Def(_) => this.current_private_vis, - ParentId::Import(_) => this.r.private_vis_decl(decl), - }; - let mut parent_id = ParentId::Def(module_id); - while let DeclKind::Import { source_decl, .. } = decl.kind { - self.update_import(decl, parent_id, priv_vis(self, parent_id, decl)); - parent_id = ParentId::Import(decl); - decl = source_decl; - } - if let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) { - let priv_vis = priv_vis(self, parent_id, decl); - self.update_def(def_id, decl.vis().expect_local(), parent_id, priv_vis); + self.update_decl_chain(decl, ParentId::Def(module_id)); + } + } + + /// Update effective visibilities for the whole reexport chain of a declaration. + /// Set the given effective visibility level to `Level::Direct` and + /// sets the rest of the `use` chain to `Level::Reexported` until + /// we hit the actual exported item. + fn update_decl_chain(&mut self, mut decl: Decl<'ra>, mut parent_id: ParentId<'ra>) { + let priv_vis = |this: &Self, parent_id, decl| match parent_id { + ParentId::Def(_) => this.current_private_vis, + ParentId::Import(_) => this.r.private_vis_decl(decl), + }; + while let DeclKind::Import { source_decl, .. } = decl.kind { + self.update_import(decl, parent_id, priv_vis(self, parent_id, decl)); + if let Some(max_vis_decl) = decl.ambiguity_vis_max.get() { + // The name is exported with the visibility of the most visible declaration + // in its ambiguous glob set (see `DeclData::vis`), so everything on that + // declaration's reexport chain, including the final item, must get its + // effective visibility from that declaration as well. Otherwise the item + // would be considered unreachable by dead code analysis and metadata + // encoding despite being exported (see the regression test + // `ambiguous-import-visibility-globglob-mir.rs`). + // This also avoids the most visible import in an ambiguous glob set + // being reported as unused. + self.update_decl_chain(max_vis_decl, parent_id); } + parent_id = ParentId::Import(decl); + decl = source_decl; + } + if let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) { + let priv_vis = priv_vis(self, parent_id, decl); + self.update_def(def_id, decl.vis().expect_local(), parent_id, priv_vis); } } @@ -194,10 +210,6 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { parent_id.level(), tcx, ); - if let Some(max_vis_decl) = decl.ambiguity_vis_max.get() { - // Avoid the most visible import in an ambiguous glob set being reported as unused. - self.update_import(max_vis_decl, parent_id, priv_vis); - } } fn update_def( diff --git a/tests/ui/imports/ambiguous-import-visibility-globglob-mir.rs b/tests/ui/imports/ambiguous-import-visibility-globglob-mir.rs new file mode 100644 index 0000000000000..a411e2cc4394d --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-globglob-mir.rs @@ -0,0 +1,20 @@ +// Regression test for the 1.96 -> 1.97 stable-to-stable regression: an item exported +// only through a public glob, and also glob-imported with restricted visibility through +// a private facade, lost its exported effective visibility. The defining crate then +// skipped encoding its optimized MIR (and warned dead_code) while name resolution still +// exported the item and it remained `cross_crate_inlinable`, so downstream crates failed +// with "missing optimized MIR". The dead_code half is checked by `#![deny(dead_code)]` +// in the auxiliary crate itself. + +//@ build-pass +//@ aux-build:ambiguous-import-visibility-globglob-mir.rs + +extern crate ambiguous_import_visibility_globglob_mir as dep; + +pub fn call_f() -> u32 { + dep::f() +} + +fn main() { + call_f(); +} diff --git a/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.rs b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.rs new file mode 100644 index 0000000000000..1a533b1d4ee21 --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.rs @@ -0,0 +1,26 @@ +// Regression test for the 1.96 -> 1.97 stable-to-stable regression: an item exported +// only through a public glob, and also glob-imported with restricted visibility through +// a private facade, lost its exported effective visibility while name resolution still +// exported it. Downstream: spurious dead_code in this crate, "missing optimized MIR" in +// dependent crates (see ambiguous-import-visibility-globglob-mir.rs). The public glob +// declaration must drive the effective visibility of the whole reexport chain. + +#![feature(rustc_attrs)] +#![allow(internal_features)] +#![deny(dead_code)] + +mod inner { + #[rustc_effective_visibility] + pub fn f() {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub +} + +mod facade { + #[allow(unused_imports)] + pub(crate) use super::inner::f; +} + +#[allow(unused_imports)] +use facade::*; +pub use inner::*; + +fn main() {} diff --git a/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.stderr b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.stderr new file mode 100644 index 0000000000000..c27e6a2ac807b --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.stderr @@ -0,0 +1,8 @@ +error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + --> $DIR/ambiguous-import-visibility-globglob-reachable.rs:14:5 + | +LL | pub fn f() {} + | ^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/auxiliary/ambiguous-import-visibility-globglob-mir.rs b/tests/ui/imports/auxiliary/ambiguous-import-visibility-globglob-mir.rs new file mode 100644 index 0000000000000..a1e125bd55637 --- /dev/null +++ b/tests/ui/imports/auxiliary/ambiguous-import-visibility-globglob-mir.rs @@ -0,0 +1,19 @@ +// An item exported only through a public glob, while also glob-imported into the +// same module through a facade with restricted visibility. The restricted duplicate +// must not make `f` unreachable: its optimized MIR must still be encoded for +// downstream crates (it is `cross_crate_inlinable`). + +mod inner { + pub fn f() -> u32 { + 42 + } +} + +mod facade { + #[allow(unused_imports)] + pub(crate) use super::inner::f; +} + +#[allow(unused_imports)] +use facade::*; +pub use inner::*; From 22348eb6369bdb5d7a7a3114d4dbbeca8c4b5335 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Fri, 10 Jul 2026 12:20:41 +0800 Subject: [PATCH 09/12] assert only opaques with sub unified hidden infer are non-rigid --- .../src/solve/assembly/mod.rs | 2 +- .../dont-ice-replacing-non-rigid-opaque.rs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/next-solver/opaques/dont-ice-replacing-non-rigid-opaque.rs diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index db1a8228c43cb..5dd42b8f1154b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -1095,8 +1095,8 @@ where if let ty::Alias(is_rigid, alias_ty) = ty.kind() && let Some(opaque_ty) = alias_ty.try_to_opaque() { - debug_assert_eq!(is_rigid, ty::IsRigid::No); if opaque_ty == self.opaque_ty { + debug_assert_eq!(is_rigid, ty::IsRigid::No); return self.self_ty; } } diff --git a/tests/ui/traits/next-solver/opaques/dont-ice-replacing-non-rigid-opaque.rs b/tests/ui/traits/next-solver/opaques/dont-ice-replacing-non-rigid-opaque.rs new file mode 100644 index 0000000000000..69c53efa14c5c --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/dont-ice-replacing-non-rigid-opaque.rs @@ -0,0 +1,25 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Regression test for #158784 +// +// We should assert that only opaque types that is to be replaced +// are non-rigid. We can have rigid opaque types elsewhere. + +#![feature(type_alias_impl_trait)] +type Rigid = impl Sized; +#[define_opaque(Rigid)] +fn define_rigid() -> Rigid {} + +type MyIter = impl Iterator; + +#[define_opaque(MyIter)] +fn define_my_iter(a: T) -> MyIter { + if false { + // `Rigid` being rigid is totally fine here. + let _: MyIter = std::iter::once(define_rigid()); + } + std::iter::once(a) +} + +fn main() {} From e30103a61f63034e89c919bd7ad9aa301920c0a3 Mon Sep 17 00:00:00 2001 From: mehdiakiki Date: Fri, 3 Jul 2026 13:14:00 +0100 Subject: [PATCH 10/12] Move NativeLib::filename to the rmeta-link archive member --- compiler/rustc_codegen_ssa/src/back/link.rs | 101 +++++++++++++++--- .../rustc_codegen_ssa/src/back/rmeta_link.rs | 64 ++++++++++- compiler/rustc_codegen_ssa/src/lib.rs | 2 - compiler/rustc_metadata/src/lib.rs | 4 +- compiler/rustc_metadata/src/native_libs.rs | 24 +---- compiler/rustc_session/src/cstore.rs | 2 - 6 files changed, 152 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c41f6f30a1da3..7cc7e7d7b5a62 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -26,7 +26,7 @@ use rustc_lint_defs::builtin::LINKER_INFO; use rustc_macros::Diagnostic; use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file}; use rustc_metadata::{ - EncodedMetadata, NativeLibSearchFallback, find_native_static_library, + EncodedMetadata, NativeLibSearchFallback, find_bundled_library, find_native_static_library, walk_native_lib_search_dirs, }; use rustc_middle::bug; @@ -329,8 +329,25 @@ fn link_rlib<'a>( .map(|obj| obj.file_name().unwrap().to_str().unwrap().to_string()) .collect(); + let native_lib_filenames: Vec> = crate_info + .used_libraries + .iter() + .map(|lib| { + find_bundled_library( + lib.name, + Some(lib.verbatim), + lib.kind, + lib.cfg.is_some(), + sess, + &crate_info.crate_types, + ) + }) + .collect(); + let metadata_link_file = if matches!(flavor, RlibFlavor::Normal) { - let metadata_link = rmeta_link::RmetaLink { rust_object_files }; + let native_lib_filenames: Vec> = + native_lib_filenames.iter().map(|f| f.map(|s| s.to_string())).collect(); + let metadata_link = rmeta_link::RmetaLink { rust_object_files, native_lib_filenames }; let metadata_link_data = metadata_link.encode(); let (wrapper, _) = create_wrapper_file(sess, rmeta_link::SECTION.to_string(), &metadata_link_data); @@ -413,12 +430,12 @@ fn link_rlib<'a>( // feature then we'll need to figure out how to record what objects were // loaded from the libraries found here and then encode that into the // metadata of the rlib we're generating somehow. - for lib in crate_info.used_libraries.iter() { + for (i, lib) in crate_info.used_libraries.iter().enumerate() { let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else { continue; }; if flavor == RlibFlavor::Normal - && let Some(filename) = lib.filename + && let Some(filename) = native_lib_filenames[i] { let path = find_native_static_library(filename.as_str(), true, sess); let src = read(path) @@ -532,11 +549,21 @@ fn link_staticlib( let lto = are_upstream_rust_objects_already_included(sess) && !ignored_for_lto(sess, crate_info, cnum); - let native_libs = crate_info.native_libraries[&cnum].iter(); - let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib)); - let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect(); + let native_libs = &crate_info.native_libraries[&cnum]; + let bundled_filenames = + rmeta_link_cache.native_lib_filenames(&sess.target, path, native_libs); + let relevant_libs: FxIndexSet<_> = native_libs + .iter() + .enumerate() + .filter(|(_, lib)| relevant_lib(sess, lib)) + .filter_map(|(i, _)| bundled_filenames.get(i).copied().flatten()) + .collect(); - let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); + let bundled_libs: FxIndexSet<_> = native_libs + .iter() + .enumerate() + .filter_map(|(i, _)| bundled_filenames.get(i).copied().flatten()) + .collect(); ab.add_archive( path, AddArchiveKind::Rlib(rmeta_link_cache, &|fname: &str, entry_kind| { @@ -2739,6 +2766,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, link_output_kind, @@ -2761,6 +2789,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, link_output_kind, @@ -3060,6 +3089,7 @@ fn add_native_libs_from_crate( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, + rmeta_link_cache: &mut RmetaLinkCache, crate_info: &CrateInfo, tmpdir: &Path, bundled_libs: &FxIndexSet, @@ -3083,13 +3113,38 @@ fn add_native_libs_from_crate( .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); } - let native_libs = match cnum { - LOCAL_CRATE => &crate_info.used_libraries, - _ => &crate_info.native_libraries[&cnum], + let (native_libs, bundled_filenames): (&Vec, Vec>) = match cnum { + LOCAL_CRATE => { + let libs = &crate_info.used_libraries; + let filenames = libs + .iter() + .map(|lib| { + find_bundled_library( + lib.name, + Some(lib.verbatim), + lib.kind, + lib.cfg.is_some(), + sess, + &crate_info.crate_types, + ) + }) + .collect(); + (libs, filenames) + } + _ => { + let native_libs = &crate_info.native_libraries[&cnum]; + let filenames = + if let Some(rlib_path) = crate_info.used_crate_source[&cnum].rlib.as_ref() { + rmeta_link_cache.native_lib_filenames(&sess.target, rlib_path, native_libs) + } else { + Vec::new() + }; + (native_libs, filenames) + } }; let mut last = (None, NativeLibKind::Unspecified, false); - for lib in native_libs { + for (i, lib) in native_libs.iter().enumerate() { if !relevant_lib(sess, lib) { continue; } @@ -3109,7 +3164,7 @@ fn add_native_libs_from_crate( let bundle = bundle.unwrap_or(true); let whole_archive = whole_archive == Some(true); if bundle && cnum != LOCAL_CRATE { - if let Some(filename) = lib.filename { + if let Some(filename) = bundled_filenames.get(i).copied().flatten() { // If rlib contains native libs as archives, they are unpacked to tmpdir. let path = tmpdir.join(filename.as_str()); cmd.link_staticlib_by_path(&path, whole_archive); @@ -3161,6 +3216,7 @@ fn add_local_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, + rmeta_link_cache: &mut RmetaLinkCache, crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, @@ -3172,6 +3228,7 @@ fn add_local_native_libraries( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, &Default::default(), @@ -3231,10 +3288,17 @@ fn add_upstream_rust_crates( match linkage { Linkage::Static | Linkage::IncludedFromDylib | Linkage::NotLinked => { if link_static_crate { - bundled_libs = crate_info.native_libraries[&cnum] - .iter() - .filter_map(|lib| lib.filename) - .collect(); + if let Some(rlib_path) = crate_info.used_crate_source[&cnum].rlib.as_ref() { + bundled_libs = rmeta_link_cache + .native_lib_filenames( + &sess.target, + rlib_path, + &crate_info.native_libraries[&cnum], + ) + .into_iter() + .flatten() + .collect(); + } add_static_crate( cmd, sess, @@ -3268,6 +3332,7 @@ fn add_upstream_rust_crates( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, &bundled_libs, @@ -3283,6 +3348,7 @@ fn add_upstream_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, + rmeta_link_cache: &mut RmetaLinkCache, crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, @@ -3306,6 +3372,7 @@ fn add_upstream_native_libraries( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, &Default::default(), diff --git a/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs b/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs index 58da783277dfe..69ec3788ac632 100644 --- a/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs +++ b/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs @@ -2,27 +2,38 @@ //! and potentially other data collected and used when building or linking a rlib. //! See . +use std::fs::File; use std::path::{Path, PathBuf}; use object::read::archive::ArchiveFile; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::memmap::Mmap; +use rustc_hir::attrs::NativeLibKind; use rustc_serialize::opaque::mem_encoder::MemEncoder; use rustc_serialize::opaque::{MAGIC_END_BYTES, MemDecoder}; use rustc_serialize::{Decodable, Encodable}; +use rustc_span::Symbol; +use rustc_target::spec::Target; +use tracing::debug; -use super::metadata::search_for_section; +use super::metadata::{get_metadata_xcoff, search_for_section}; +use crate::NativeLib; pub(crate) const FILENAME: &str = "lib.rmeta-link"; pub(crate) const SECTION: &str = ".rmeta-link"; pub struct RmetaLink { pub rust_object_files: Vec, + /// Positionally aligned with `native_libraries` in regular metadata: index `i` is the + /// bundled filename for native library `i`, or `None` if that library needs no bundling. + pub native_lib_filenames: Vec>, } impl RmetaLink { pub(crate) fn encode(&self) -> Vec { let mut encoder = MemEncoder::new(); self.rust_object_files.encode(&mut encoder); + self.native_lib_filenames.encode(&mut encoder); let mut data = encoder.finish(); data.extend_from_slice(MAGIC_END_BYTES); data @@ -31,7 +42,8 @@ impl RmetaLink { pub(crate) fn decode(data: &[u8]) -> Option { let mut decoder = MemDecoder::new(data, 0).ok()?; let rust_object_files = Vec::::decode(&mut decoder); - Some(RmetaLink { rust_object_files }) + let native_lib_filenames = Vec::>::decode(&mut decoder); + Some(RmetaLink { rust_object_files, native_lib_filenames }) } } @@ -69,4 +81,52 @@ impl RmetaLinkCache { ) -> Option<&RmetaLink> { self.cache.entry(rlib_path.to_path_buf()).or_insert_with(load).as_ref() } + + pub fn native_lib_filenames( + &mut self, + target: &Target, + rlib_path: &Path, + native_libs: &[NativeLib], + ) -> Vec> { + if !crate_may_have_bundled_libs(native_libs) { + return Vec::new(); + } + self.get_or_insert_with(rlib_path, || read_from_path(target, rlib_path)) + .map(|rl| { + rl.native_lib_filenames.iter().map(|f| f.as_deref().map(Symbol::intern)).collect() + }) + .unwrap_or_default() + } +} + +fn crate_may_have_bundled_libs(libs: &[NativeLib]) -> bool { + libs.iter() + .any(|lib| matches!(lib.kind, NativeLibKind::Static { bundle: Some(true) | None, .. })) +} + +// FIXME: this is mostly a copy-paste of `DefaultMetadataLoader::get_rlib_metadata`. +fn read_from_path(target: &Target, path: &Path) -> Option { + let Ok(file) = File::open(path) else { + debug!("failed to open rlib for rmeta-link: {}", path.display()); + return None; + }; + let Ok(mmap) = (unsafe { Mmap::map(file) }) else { + debug!("failed to mmap rlib for rmeta-link: {}", path.display()); + return None; + }; + + if target.is_like_aix { + let archive = ArchiveFile::parse(&*mmap).ok()?; + for entry in archive.members() { + let entry = entry.ok()?; + if entry.name() == FILENAME.as_bytes() { + let member_data = entry.data(&*mmap).ok()?; + let section_data = get_metadata_xcoff(path, member_data).ok()?; + return RmetaLink::decode(section_data); + } + } + return None; + } + + read_from_data(&mmap, path) } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index f3f19f9e90d83..45aa64f332b6e 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -214,7 +214,6 @@ bitflags::bitflags! { pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol, - pub filename: Option, pub cfg: Option, pub verbatim: bool, pub dll_imports: Vec, @@ -224,7 +223,6 @@ impl From<&cstore::NativeLib> for NativeLib { fn from(lib: &cstore::NativeLib) -> Self { NativeLib { kind: lib.kind, - filename: lib.filename, name: lib.name, cfg: lib.cfg.clone(), verbatim: lib.verbatim.unwrap_or(false), diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 840b1c4c6fa2f..642dde52adb3c 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -29,7 +29,7 @@ pub mod locator; pub use fs::{METADATA_FILENAME, emit_wrapper_file}; pub use host_dylib::{DylibError, load_symbol_from_dylib}; pub use native_libs::{ - NativeLibSearchFallback, find_native_static_library, try_find_native_dynamic_library, - try_find_native_static_library, walk_native_lib_search_dirs, + NativeLibSearchFallback, find_bundled_library, find_native_static_library, + try_find_native_dynamic_library, try_find_native_static_library, walk_native_lib_search_dirs, }; pub use rmeta::{EncodedMetadata, METADATA_HEADER, ProcMacroKind, encode_metadata, rendered_const}; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index c9e4ce60e1a01..edf867d0b3b66 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -168,16 +168,16 @@ pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> }) } -fn find_bundled_library( +pub fn find_bundled_library( name: Symbol, verbatim: Option, kind: NativeLibKind, has_cfg: bool, - tcx: TyCtxt<'_>, + sess: &Session, + crate_types: &[CrateType], ) -> Option { - let sess = tcx.sess; if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive, .. } = kind - && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) + && crate_types.iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) { let verbatim = verbatim.unwrap_or(false); @@ -275,16 +275,8 @@ impl<'tcx> Collector<'tcx> { } }; - let filename = find_bundled_library( - attr.name, - attr.verbatim, - attr.kind, - attr.cfg.is_some(), - self.tcx, - ); self.libs.push(NativeLib { name: attr.name, - filename, kind: attr.kind, cfg: attr.cfg.clone(), foreign_module: Some(def_id.to_def_id()), @@ -366,16 +358,8 @@ impl<'tcx> Collector<'tcx> { // Add if not found let new_name: Option<&str> = passed_lib.new_name.as_deref(); let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name)); - let filename = find_bundled_library( - name, - passed_lib.verbatim, - passed_lib.kind, - false, - self.tcx, - ); self.libs.push(NativeLib { name, - filename, kind: passed_lib.kind, cfg: None, foreign_module: None, diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 94237132bd393..c2b517824a058 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -68,8 +68,6 @@ pub enum LinkagePreference { pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol, - /// If packed_bundled_libs enabled, actual filename of library is stored. - pub filename: Option, pub cfg: Option, pub foreign_module: Option, pub verbatim: Option, From 3a546a7c0ce9902a8794dbd6f9a584d0b48a8664 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 10 Jul 2026 11:49:51 +0200 Subject: [PATCH 11/12] Remove unused WEAK_ONLY_LANG_ITEMS static --- compiler/rustc_hir/src/weak_lang_items.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_hir/src/weak_lang_items.rs b/compiler/rustc_hir/src/weak_lang_items.rs index f9d94bd505724..a2541089a530b 100644 --- a/compiler/rustc_hir/src/weak_lang_items.rs +++ b/compiler/rustc_hir/src/weak_lang_items.rs @@ -25,8 +25,6 @@ macro_rules! weak_lang_items { macro_rules! weak_only_lang_items { ($($item:ident,)*) => { - pub static WEAK_ONLY_LANG_ITEMS: &[LangItem] = &[$(LangItem::$item,)*]; - impl LangItem { pub fn is_weak_only(self) -> bool { matches!(self, $(LangItem::$item)|*) From 2de1207818723b801380a808e92d4c844855d9bb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jul 2026 12:18:51 +0200 Subject: [PATCH 12/12] Apply MCP 1003 and move `diagnostics.rs` into its own module and move `error_helper.rs` into the `diagnostics` folder in `rustc_resolve` --- compiler/rustc_resolve/src/build_reduced_graph.rs | 2 +- .../src/{error_helper.rs => diagnostics/impls.rs} | 0 .../src/{diagnostics.rs => diagnostics/mod.rs} | 2 ++ compiler/rustc_resolve/src/imports.rs | 2 +- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 6 +++--- 6 files changed, 8 insertions(+), 6 deletions(-) rename compiler/rustc_resolve/src/{error_helper.rs => diagnostics/impls.rs} (100%) rename compiler/rustc_resolve/src/{diagnostics.rs => diagnostics/mod.rs} (99%) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index c35dc02fb1de1..974577fd89a54 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -31,7 +31,7 @@ use tracing::debug; use crate::Namespace::{MacroNS, TypeNS, ValueNS}; use crate::def_collector::DefCollector; -use crate::error_helper::{OnUnknownData, StructCtor}; +use crate::diagnostics::impls::{OnUnknownData, StructCtor}; use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef}; use crate::ref_mut::CmCell; diff --git a/compiler/rustc_resolve/src/error_helper.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs similarity index 100% rename from compiler/rustc_resolve/src/error_helper.rs rename to compiler/rustc_resolve/src/diagnostics/impls.rs diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics/mod.rs similarity index 99% rename from compiler/rustc_resolve/src/diagnostics.rs rename to compiler/rustc_resolve/src/diagnostics/mod.rs index 22cc6a581f19a..94616f1c679ea 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics/mod.rs @@ -10,6 +10,8 @@ use rustc_span::{Ident, Span, Spanned, Symbol}; use crate::Res; use crate::late::PatternSource; +pub(crate) mod impls; + #[derive(Diagnostic)] #[diag("can't use {$is_self -> [true] `Self` diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 379ae992c9a6e..db7c95fbd511e 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -25,13 +25,13 @@ use rustc_span::{Ident, Span, Symbol, kw, sym}; use tracing::debug; use crate::Namespace::{self, *}; +use crate::diagnostics::impls::{OnUnknownData, Suggestion}; use crate::diagnostics::{ self, CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate, CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates, ConsiderAddingMacroExport, ConsiderMarkingAsPub, ConsiderMarkingAsPubCrate, }; -use crate::error_helper::{OnUnknownData, Suggestion}; use crate::ref_mut::{CmCell, CmRefCell}; use crate::{ AmbiguityError, BindingKey, CmResolver, Decl, DeclData, DeclKind, Determinacy, Finalize, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 668278f13d9cf..4e901cd76b92e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -32,7 +32,7 @@ use thin_vec::{ThinVec, thin_vec}; use tracing::debug; use super::NoConstantGenericsReason; -use crate::error_helper::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; +use crate::diagnostics::impls::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; use crate::late::{ AliasPossibility, LateResolutionVisitor, LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet, QSelf, RibKind, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 911350665ed32..56e107c0c3369 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -29,7 +29,6 @@ use std::{fmt, mem}; use diagnostics::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use effective_visibilities::EffectiveVisibilitiesVisitor; -use error_helper::{ImportSuggestion, LabelSuggestion, StructCtor, Suggestion}; use hygiene::Macros20NormalizedSyntaxContext; use imports::{Import, ImportData, ImportKind, NameResolution, PendingDecl}; use late::{ @@ -77,7 +76,9 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; -use crate::error_helper::OnUnknownData; +use crate::diagnostics::impls::{ + ImportSuggestion, LabelSuggestion, OnUnknownData, StructCtor, Suggestion, +}; use crate::imports::NameResolutionRef; use crate::ref_mut::{CmCell, CmRefCell}; @@ -86,7 +87,6 @@ mod check_unused; mod def_collector; mod diagnostics; mod effective_visibilities; -mod error_helper; mod ident; mod imports; mod late;