Skip to content

Incorrect lifetime bound check in async + impl_trait_in_assoc_type #114572

Closed
@xiaoyawei

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

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