I tried this code:
trait Id {
type SelfType;
}
impl<T> Id for T {
type SelfType = T;
}
trait Foo {
type Assoc<'a>
where
Self: 'a;
fn assoc(&mut self) -> Self::Assoc<'_>;
}
fn overlapping_mut<T>(mut t: T)
where
T: Foo,
for<'a> <T::Assoc<'a> as Id>::SelfType: 'static,
{
let a = t.assoc();
let b = t.assoc();
}
fn live_past_borrow<T>(mut t: T)
where
T: Foo,
for<'a> <T::Assoc<'a> as Id>::SelfType: 'static {
let x = t.assoc();
drop(t);
drop(x);
}
I expected to see this happen: It compiles like with the old solver.
Instead, this happened:
error[E0499]: cannot borrow `t` as mutable more than once at a time
--> counter_examples/unnormalized-into-outlive.rs:25:13
|
24 | let a = t.assoc();
| - first mutable borrow occurs here
25 | let b = t.assoc();
| ^ second mutable borrow occurs here
26 | }
| - first borrow might be used here, when `a` is dropped and runs the destructor for type `<T as Foo>::Assoc<'_>`
error[E0505]: cannot move out of `t` because it is borrowed
--> counter_examples/unnormalized-into-outlive.rs:33:10
|
28 | fn live_past_borrow<T>(mut t: T)
| ----- binding `t` declared here
...
32 | let x = t.assoc();
| - borrow of `t` occurs here
33 | drop(t);
| ^ move out of `t` occurs here
34 | drop(x);
| - borrow later used here
error: aborting due to 2 previous errors
Meta
rustc --version --verbose:
rustc 1.98.0-dev (2026--6-26)
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.98.0-dev
LLVM version: 22.1.8
Analysis
We try to record free regions from TypeOutlives bounds.
We only care about the region if the outlive ty is equal to current alias ty.
But the outlive ty from param env is unnormalized and fails the equality check.
Related tests
These can be adapted into regression tests for the fix:
tests/ui/borrowck/alias-liveness/gat-static.rs - just use the example code above.
tests/ui/borrowck/alias-liveness/rtn-static.rs - exploiting RTN is harder, if possible. We can only use it in specific positions.
cc @lcnr
I tried this code:
I expected to see this happen: It compiles like with the old solver.
Instead, this happened:
Meta
rustc --version --verbose:Analysis
We try to record free regions from TypeOutlives bounds.
We only care about the region if the outlive ty is equal to current alias ty.
But the outlive ty from param env is unnormalized and fails the equality check.
Related tests
These can be adapted into regression tests for the fix:
tests/ui/borrowck/alias-liveness/gat-static.rs- just use the example code above.tests/ui/borrowck/alias-liveness/rtn-static.rs- exploiting RTN is harder, if possible. We can only use it in specific positions.cc @lcnr