Open dingxiangfei2009 opened 6 months ago
As pointed out in #121602, here is a similar issue #121670 but only for trait solver.
I consider there to be two separate issues here, firstly the following:
pub trait Trait<'a> {
type Assoc: 'a;
}
// Removing `Assoc = A` here makes this compile because you only get the
// alias-bound of `Assoc` if it is rigid
fn foo<'a, T: Trait<'a, Assoc = A>, A>() {
let _: &'a T::Assoc = todo!();
}
fn main() {}
and secondly, the one which is imo more applicable to your example:
pub trait Id<T> {
type This;
}
impl<T, U> Id<U> for T {
type This = T;
}
trait Trait {
type Assoc;
}
// Removing `Assoc = U` makes this compile. This is because
// `<T as Id<T::Assoc>>::This` normalizes to `T`, resulting in an implied `T: 'a`
// bound. No bound on either `T::Assoc` or `U` is added here. Instead, `T::Assoc: 'a`
// holds as `T: 'a` holds.
fn foo<'a, T: Trait<Assoc = U>, U>(x: &'a <T as Id<T::Assoc>>::This) {
let _: &'a T::Assoc = todo!();
}
fn main() {}
I wanted to write that fixing the second issue is trivial, we can just structurally walk types involved in implied bounds. That's unfortunately not true as doing so is unsound: Alias<U>: 'a
can hold regardless of whether U: 'a
holds 😅
It occurs to me that adding named type terms to associated type of trait bounds can lead to borrow check failure, while the same code without "naming" the associated type passes the borrow check.
I tried this code:
I expected to see this happen: It should compile just like the following rewrite, without naming the
Output1
toA
.Instead, this happened:
Mind that due to the trait definition, it is not possible to apply the suggestion that is emitted by
rustc
.Meta
This is found on the latest
master
, as of writing, and stable.rustc --version --verbose
:Backtrace
Not an ICE, so not applicable.