Generator lifetime erasure question

Not sure if this belongs to users of internal. I'm trying to fix #64552, and I found this test in rustc generator/auto-trait-regions.rs.

I don't get why should the first one and the third one fail, is it intended behavior?

You may want to ask over the Zulip platform for Rust:

Well, yeah. I know zulip. I figured the question is not related to compiler internel, just language itself, so I posted here first.

1 Like

I believe it is this.

"Immovable generators" aren't really part of the (exposed, stable) language, despite async and whatnot relying on it. I think the closest thing is the experimental coroutines RFC.

Whoa this is old. This comment can be found in the current source. I get the part these lifetime should not be exposed, but this part doesn't sound right to me...

These lifetimes are used in auto trait impl checking (for example, if a Sync generator contains an &'α T , we need to check whether &'α T: Sync ), so knowledge of the exact relationships between them isn't particularly important.

There's another longer-form comment about it, for what it's worth, which matches my interpretation of the tests:

  • The first test makes sure that an auto-trait dependent on being 'static doesn't hold
  • The second test is ok because the auto-trait is implemented for any possible lifetime
  • The third test makes sure that an auto-trait depending on lifetime relationships ('a: 'b) doesn't hold

But that's the extent of my understanding.

My guess is that the comment you quote is about the third test: If there are relationships that must hold, it doesn't matter what they are really, so long as the auto-trait isn't inferred for the generator.

Note that we lose all information about relations between the lifetimes - we might have had impl Sync for Foo1<'static> , and the generator might have only ever stored a Foo1<'static> , but we don't try to handle that. I think this should be not that bad in practice because the generator's contents only get used for proving auto traits, which should not have weird lifetime constraints.

If I'm interpreting this comment correctly, current implementation is not the best possible behavior. It's built on a assumption that lifetime constraints doesn't not come up. But unfortunately, with GAT soon being stable, and with it (often) requiring a where Self: 'a on the associated type, writing code similar to

trait S {
   type T<'a> : Send where Self : 'a;
}

easily introduce lifetime bound on auto trait. Which results async code can not prove auto trait when S::T<'_> is used.

This caused problem in my real life code, and I had to stick a magic wrapper with unsafe impl Send to it.

Perhaps it is #71723 (or another of the issues it would fix, as listed) given the description of PR 92449.

1 Like