Rust 1.84 sometimes allows overlapping impls in incremental re-builds · Issue #135514 · rust-lang/rust (original) (raw)

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 line

into

/* // <- uncomment this line

The 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);

struct S(T); impl Trait for S where S0: 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 Other for S { 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 {}

fn use_first_impl<T: Trait, L, R>(l: L) -> <::To as Other>::Choose<L, R> { l }

fn use_second_impl<T, L, R>(l: <S as Other>::Choose<L, R>) -> R { l }

trait TyEq { type To; } impl TyEq for T { type To = T; }

fn transmute_inner<W, T, L, R>(l: L) -> R where T: Trait + TyEq<To = S>, { 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, 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