Semantics of nested `impl Trait` + HRTBs

I noticed that that Lazy type-alias-impl-trait take two by oli-obk · Pull Request #94081 · rust-lang/rust · GitHub makes the following code pass:

trait Tr<'a> {
	type Assoc;
}

impl<'a> Tr<'a> for () {
	type Assoc = ();
}

fn f() -> impl for<'a> Tr<'a, Assoc = impl Copy + 'a> {}

But I can't find a documentation of the intended semantics in this case.

From the following test it seems that it allows the existential impl Copy + 'a to be paramterized by 'a, and that's quite surprising behavior since adding a lifetime makes the test fails, which would pass otherwise.

fn check<Assoc>(_: impl for<'a> Tr<'a, Assoc = Assoc>) {}
fn main() { check(f()); }

playground link

see also yet another ICE with HRTB and RPIT · Issue #95647 · rust-lang/rust · GitHub

cc @oli-obk

In other words, I'm asking if

fn f() -> impl for<'a> Tr<'a, Assoc = impl Copy + 'a> {}

should be equivalent to:

type Assoc = impl for<'a> Copy + 'a;
fn f() -> impl for<'a> Tr<'a, Assoc = Assoc> {}

or:

type Assoc<'a> = impl Copy + 'a;
fn f() -> impl for<'a> Tr<'a, Assoc = Assoc<'a>> {}

I would think it should be the second one

If the lifetime is used in the assoc type in your example


impl<'a> Tr<'a> for () {
	type Assoc = &'a ();
}

the compiler ICEs. Though I do expect it to be a breaking change to add a lifetime to an impl Trait

I think we really need a decision here. For me it would be an inconsistent and and odd behavior.

For example, if for<'a> Tr<'a, Assoc = impl Copy + 'a> allows Assoc to be paramterized by 'a, I would expect the same behavior from for<'a> Tr<'a, Assoc = impl Copy> as well! Adding a lifetime bound shouldn't change semantics in this regard.

Agreed. I would expect that impl Copy to have access to 'a, just like the impl outside the for<'a> has access to generics of the surrounding function

EDIT: I wasn't paying attention when I wrote this. We do need the + 'a just like we need it for non-nested impls.

Can you summarize this in an issue so we can inform the lang team about the unintended stabilization and let them make a decision on it?

Otherwise i'll do that next week, I'm on vacation right now without a computer

2 Likes

opened an issue nested RPIT and HRTB: unclear semantics and future incompatibility · Issue #96194 · rust-lang/rust · GitHub

2 Likes