Skip to content
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

Using anonymous lifetimes fails to compile #18

Closed
udoprog opened this issue Aug 2, 2019 · 3 comments
Closed

Using anonymous lifetimes fails to compile #18

udoprog opened this issue Aug 2, 2019 · 3 comments

Comments

@udoprog
Copy link

udoprog commented Aug 2, 2019

The following:

struct Baz;

#[async_trait]
trait Foo {
    async fn test(value: &Baz);
}

struct Bar<'a>(&'a ());

#[async_trait]
impl Foo for Bar<'_> {
    async fn test(value: &Baz) {
    }
}

Results in:

error[E0261]: use of undeclared lifetime name `'_`

error: aborting due to previous error

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

To learn more, run the command again with --verbose.
@udoprog udoprog changed the title Using multiple anonymous lifetimes in fails to compile Using multiple anonymous lifetimes fails to compile Aug 2, 2019
@udoprog udoprog changed the title Using multiple anonymous lifetimes fails to compile Using anonymous lifetimes fails to compile Aug 2, 2019
@dtolnay
Copy link
Owner

dtolnay commented Aug 2, 2019

Thanks! I won't be able to fix this right away but I would accept a PR with a fix. We need to figure out where the macro is incorrectly copying the '_ into the macro output and figure out what it should be putting there instead.

@udoprog
Copy link
Author

udoprog commented Aug 2, 2019

Well, looked briefly, but this is over my head.
Compiler: rustc 1.38.0-nightly (8a58268b5 2019-07-31)

This is the generated code:

impl Foo for Bar<'_> {
    fn test<'life0, 'async_trait>(
        value: &'life0 Baz,
    ) -> core::pin::Pin<
        Box<dyn core::future::Future<Output = ()> + core::marker::Send + 'async_trait>,
    >
    where
        'life0: 'async_trait,
    {
        async fn __test(value: &Baz) {}
        core::pin::Pin::from(Box::new(__test(value)))
    }
}

Which doesn't compile.
But then there's this which does (what you get after naming the lifetime to 'a):

impl<'a> Foo for Bar<'a> {
    fn test<'life0, 'async_trait>(
        value: &'life0 Baz,
    ) -> core::pin::Pin<
        Box<dyn core::future::Future<Output = ()> + core::marker::Send + 'async_trait>,
    >
    where
        'life0: 'async_trait,
    {
        async fn __test<'a>(value: &Baz) {}
        core::pin::Pin::from(Box::new(__test(value)))
    }
}

Then there's this that does work:

impl Foo for Bar<'_> {
    fn test<'life0, 'async_trait>(
        value: &'life0 Baz,
    ) -> core::pin::Pin<
        Box<dyn core::future::Future<Output = ()> + core::marker::Send + 'async_trait>,
    >
    where
        'life0: 'async_trait,
    {
        core::pin::Pin::from(Box::new(async move {}))
    }
}

But just including the async fn __test(value: &Baz) {} in the function body breaks it again.

So this seems to be some subtle interaction with how rustc deals with the desugaring of the nested async fn, which is beyond my understanding.

@dtolnay
Copy link
Owner

dtolnay commented Aug 2, 2019

I guess it's a compiler bug. Let's close in favor of tracking this in rust-lang/rust#63225. Thanks!

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

No branches or pull requests

2 participants