Skip to content

existential Generator + lifetime type errors unless impl trait wrapper is used #58662

Closed
@anderspapitto

Description

@anderspapitto

I'm writing a simple Generator that takes a reference to an RNG, and yields values from it. This makes sense as long as the generator doesn't outlive the RNG which it references.

I want to name the type of the generator with an existential type, but I can't do so unless I wrap a version of the function that uses an impl Trait formulation.

Here's the direct version which doesn't work

existential type RandGenerator<'a>: 'a + Generator<Return=!, Yield=u64>;
fn rand_generator<'a>(rng: &'a mut MyRng) -> RandGenerator<'a> {
    move || {
        loop {
            yield rng.gen::<u64>();
        };
    }
}

and here's the more convoluted version which does

existential type RandGeneratorWithIndirection<'a>: 'a + Generator<Return=!, Yield=u64>;
fn rand_generator_with_indirection<'a>(rng: &'a mut MyRng) -> RandGeneratorWithIndirection<'a> {
    fn helper<'b>(rng: &'b mut MyRng) -> impl 'b + Generator<Return=!, Yield=u64> {
        move || {
            loop {
                yield rng.gen::<u64>();
            };
        }
    }

    helper(rng)
}

and here's a playground link containing both versions, as well as a bit of scaffolding

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=7c7b6ce96c2f1b7d5d4a4c3d2d65a33f

The full error message I'm seeing looks like this

   Compiling playground v0.0.1 (/playground)
error: non-defining existential type use in defining scope
  --> src/main.rs:16:64
   |
16 |   fn rand_generator<'a>(rng: &'a mut MyRng) -> RandGenerator<'a> {
   |  ________________________________________________________________^
17 | |     move || {
18 | |         loop {
19 | |             yield rng.gen::<u64>();
20 | |         };
21 | |     }
22 | | }
   | |_^ lifetime `` is part of concrete type but not used in parameter list of existential type

error: aborting due to previous error

error: Could not compile `playground`.

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

Labels

A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`requires-nightlyThis issue requires a nightly compiler in some way.

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions