[-Znext-solver] Outlive clauses in param env are incorrectly skipped in liveness analysis
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in compiler/rustc_infer/src/infer/outlives/for_liveness.rs, focusing on the TypeOutlives handling described in the issue. Review tests/ui/borrowck/alias-liveness/gat-static.rs and rtn-static.rs, adapt the supplied examples into regression coverage, and verify that the cases compile as expected without the reported borrow errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100