I tried this code:
trait Bar {
type BarAssoc: for<'a> Foo<FooAssoc<'a>: 'static>;
}
trait Foo {
type FooAssoc<'a>
where
Self: 'a;
fn assoc(&mut self) -> Self::FooAssoc<'_>;
}
fn overlapping_mut<T>(mut t: T::BarAssoc)
where
T: Bar,
{
let _a = t.assoc();
let _b = t.assoc();
}
I expected to see this happen: compiles.
Instead, this happened:
error[E0499]: cannot borrow `t` as mutable more than once at a time
--> counter_examples/indirect-outlive.rs:20:14
|
19 | let _a = t.assoc();
| - first mutable borrow occurs here
20 | let _b = t.assoc();
| ^ second mutable borrow occurs here
21 | }
| - first borrow might be used here, when `_a` is dropped and runs the destructor for type `<<T as Bar>::BarAssoc as Foo>::FooAssoc<'_>`
error: aborting due to 1 previous error
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
Expression t.assoc() has type T::BarAssoc::FooAssoc. We don't have any item bound on FooAssoc but we can constraint it in the item bounds of BarAssoc.
So we should consider the alias bounds recursively for consecutive aliases, like in fn assemble_alias_bound_candidates_recur.
relevant code
cc @lcnr
I tried this code:
I expected to see this happen: compiles.
Instead, this happened:
Meta
rustc --version --verbose:Analysis
Expression
t.assoc()has typeT::BarAssoc::FooAssoc. We don't have any item bound onFooAssocbut we can constraint it in the item bounds ofBarAssoc.So we should consider the alias bounds recursively for consecutive aliases, like in
fn assemble_alias_bound_candidates_recur.relevant code
cc @lcnr