Skip to content

Incorrect lifetime bound check in async + impl_trait_in_assoc_type #114572

Description

@xiaoyawei

I tried this code:

#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]

use std::{fmt::Display, future::Future};

pub trait SharedDisplay: Display + Send + 'static {}

pub struct Message<T: AsRef<dyn SharedDisplay>> {
    inner: T,
}

pub trait AsyncPrinter: Send + Sync {
    type AsyncOutput<'a>: Future<Output = String> + Send
    where
        Self: 'a;

    fn to_string(&self, msg: Message<Box<dyn SharedDisplay>>) -> Self::AsyncOutput<'_>;
}

struct FooPrinter;

impl AsyncPrinter for FooPrinter {
    type AsyncOutput<'a> = impl Future<Output = String> + Send + 'a where Self: 'a;

    fn to_string(&self, msg: Message<Box<dyn SharedDisplay>>) -> Self::AsyncOutput<'_> {
        async move { msg.inner.to_string() }
    }
}

I expected to see this happen: The code correctly compiles

Instead, this happened: The code fails to compile with lifetime bound check errors.

More information that might be helpful

I did a bisect and found that the above code compiles in nightly-2023-03-14 but fails in nightly-2023-03-15, possibly due to #108909 but I didn't dig deep to find the root cause.

Also, by changing the implementation of the to_string function of FooPrinter by wrapping the async block with a smart pointer (see below), the code successfully compiles

fn to_string(&self, msg: Message<Box<dyn SharedDisplay>>) -> Self::AsyncOutput<'_> {
    Box::pin(async move { msg.inner.to_string() })
}

Let me know if more info is needed, or actually my codes fails to compile by design.

Meta

rustc --version --verbose:

rustc 1.73.0-nightly (474709a9a 2023-08-03)
binary: rustc
commit-hash: 474709a9a2a74a8bcf0055fadb335d0ca0d2d939
commit-date: 2023-08-03
host: x86_64-apple-darwin
release: 1.73.0-nightly
LLVM version: 16.0.5
Backtrace

error[E0478]: lifetime bound not satisfied
  --> src/lib.rs:23:28
   |
23 |     type AsyncOutput<'a> = impl Future<Output = String> + Send + 'a where Self: 'a;
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: lifetime parameter instantiated with the lifetime `'a` as defined here
  --> src/lib.rs:23:22
   |
23 |     type AsyncOutput<'a> = impl Future<Output = String> + Send + 'a where Self: 'a;
   |                      ^^
   = note: but lifetime parameter must outlive the static lifetime

Activity

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

Metadata

Metadata

Assignees

Labels

C-bugCategory: This is a bug.F-impl_trait_in_assoc_type`#![feature(impl_trait_in_assoc_type)]`F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`WG-asyncWorking group: Async & await

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions