Rust 1.84 sometimes allows overlapping impls in incremental re-builds
This repro uses a bit of lexical comments trickery, but only for convenience. (Quite useful while manually testing multiple rust versions), so the whole change you need to do between incremental compilations is turning
// /* // <- uncomment this lineinto
/* // <- uncomment this lineThe main relevant change that this entails is
turning into
which makes the Other-impls overlapping. As an additional effect, the code turning the overlap into UB is also uncommented. (The const _ … stuff only “fixes” the * symbols left behind by the */* in the middle.)
trait Trait {} struct S0<T>(T); struct S<T>(T); impl<T> Trait for S<T> where S0<T>: Trait {} struct W; trait Other { type Choose<L, R>; } struct A; struct B; // first impl impl<T: Trait> Other for T { type Choose<L, R> = L; } // second impl impl<T> Other for S<T> { type Choose<L, R> = R; } const _: u8 = 0 // /* // <- uncomment this line *0; impl Trait for W {} pub fn transmute<L, R>(l: L) -> R { todo!(); } const _: u8 = 0 */* 0; impl Trait for S<W> {} fn use_first_impl<T: Trait, L, R>(l: L) -> <<T as TyEq>::To as Other>::Choose<L, R> { l } fn use_second_impl<T, L, R>(l: <S<T> as Other>::Choose<L, R>) -> R { l } trait TyEq { type To; } impl<T> TyEq for T { type To = T; } fn transmute_inner<W, T, L, R>(l: L) -> R where T: Trait + TyEq<To = S<W>>, { use_second_impl::<W, L, R>(use_first_impl::<T, L, R>(l)) } pub fn transmute<L, R>(l: L) -> R { transmute_inner::<W, S<W>, L, R>(l) } const _: u8 = // */ 0; fn main() { let v = vec![65_u8, 66, 67]; let s: String = transmute(v); println!("{}", s); }
Reproduce
cargo new repro cd repro …write above to src/main… cargo run …uncomment the line in question as described… cargo run
Compiling repro v0.1.0 (/home/frank/repro) warning: struct `A` is never constructed --> src/main.rs:14:8 | 14 | struct A; | ^ | = note: `#[warn(dead_code)]` on by default warning: struct `B` is never constructed --> src/main.rs:15:8 | 15 | struct B; | ^ warning: `repro` (bin "repro") generated 2 warnings Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s Running `target/debug/repro` ABC
Is safe code that compiles to UB, but only in incremental re-builds (compilation error otherwise), considered a soundness issue to be labelled I-unsound?
This was already fixed with #133828 (which also explains what was the underlying issue). That PR seems like a fairly small & straightforward fix to me… should it perhaps be considered for backporting to stable? cc @compiler-errors
@rustbot label regression-from-stable-to-stable, T-compiler, A-incr-comp, A-coherence