New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Existential type captures lifetime that doesn't appear in bounds even though it does appear #57188

Open
Palladinium opened this Issue Dec 29, 2018 · 5 comments

Comments

Projects
None yet
5 participants
@Palladinium
Copy link

Palladinium commented Dec 29, 2018

#![feature(existential_type)]

struct Baz<'a> {
    source: &'a str,
}

trait Foo<'a> {
    type T: Iterator<Item = Baz<'a>> + 'a;
    fn foo(source: &'a str) -> Self::T;
}

struct Bar;
impl<'a> Foo<'a> for Bar {
    existential type T: Iterator<Item = Baz<'a>> + 'a;
    fn foo(source: &'a str) -> Self::T {
        std::iter::once(Baz { source })
    }
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
  --> src/lib.rs:15:5
   |
15 |     existential type T: Iterator<Item = Baz<'a>> + 'a;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: hidden type `std::iter::Once<Baz<'a>>` captures the lifetime 'a as defined on the impl at 14:6
  --> src/lib.rs:14:6
   |
14 | impl<'a> Foo<'a> for Bar {
   |      ^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0700`.
error: Could not compile `playground`.

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

May be related to #42940, but I'm not entirely sure.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Dec 29, 2018

@alexreg

This comment has been minimized.

Copy link
Contributor

alexreg commented Dec 29, 2018

@Centril I believe this is the same as #42940 as you suggest, but maybe @cramertj can confirm.

@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Jan 2, 2019

It doesn't seem the same as #42940 to me-- the only lifetime I see here is 'a, which is explicitly named in the bounds of the existential type. cc @oli-obk

@Arnavion

This comment has been minimized.

Copy link

Arnavion commented Jan 29, 2019

As a workaround, moving the existential type out and referencing it directly in the return type compiles fine:

#![feature(existential_type)]

struct Baz<'a> {
    source: &'a str,
}

trait Foo<'a> {
    type T: Iterator<Item = Baz<'a>> + 'a;
    fn foo(source: &'a str) -> Self::T;
}

existential type BarFooT<'a>: Iterator<Item = Baz<'a>> + 'a;

struct Bar;
impl<'a> Foo<'a> for Bar {
    type T = BarFooT<'a>;

    fn foo(source: &'a str) -> BarFooT<'a> { // Note: *not* Self::T
        std::iter::once(Baz { source })
    }
}
@alexreg

This comment has been minimized.

Copy link
Contributor

alexreg commented Jan 29, 2019

@Arnavion: @cramertj is working on a fix for a related issue. He thinks this is separate (as stated above), but who knows, a fix may cover this too, so stay tuned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment