Skip to content

Using type in async trait will cause some problems? #34

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

Closed
UkonnRa opened this issue Sep 16, 2019 · 3 comments
Closed

Using type in async trait will cause some problems? #34

UkonnRa opened this issue Sep 16, 2019 · 3 comments

Comments

@UkonnRa
Copy link

UkonnRa commented Sep 16, 2019

Hi, me again. I found using type in trait will cause some problems...

  1. mismatched types
  2. cannot infer an appropriate lifetime for lifetime parameter 'a due to conflicting requirements
extern crate async_trait;

use async_trait::async_trait;
use futures::executor::block_on;

#[async_trait]
pub trait State<'a> {
    type Command: 'a + Send;

    async fn add_comm(mut self, more_str: Self::Command) -> Self where Self: Sized;
    async fn add_more_comm(mut self, str1: Self::Command, str2: Self::Command) -> Self where Self: Sized {
        let self1 = self.add_comm(str1).await;
        let self2 = self1.add_comm(str2).await;
        self2
    }
}

#[derive(Debug)]
pub struct RealState(String);
#[async_trait]
impl <'a> State<'a> for RealState {
    type Command = String;

    async fn add_comm(mut self, more_str: Self::Command) -> Self {
        self.0 = self.0.clone() + more_str.as_ref();
        self
    }
}

fn main() {
    let state = RealState(Default::default());
    let state1 = block_on(state.add_more_str("hello", " world"));
    println!("{:?}", state1);
}

Error:

error[E0308]: mismatched types
 --> src/lifetime-error.rs:6:1
  |
6 | #[async_trait]
  | ^^^^^^^^^^^^^^ one type is more general than the other
  |
  = note: expected type `std::marker::Send`
             found type `std::marker::Send`

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
 --> src/lifetime-error.rs:6:1
  |
6 | #[async_trait]
  | ^^^^^^^^^^^^^^
  |
note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 7:17...
 --> src/lifetime-error.rs:7:17
  |
7 | pub trait State<'a> {
  |                 ^^
  = note: ...so that the expression is assignable:
          expected <Self as State<'_>>::Command
             found <Self as State<'a>>::Command
note: but, the lifetime must be valid for the lifetime 'async_trait as defined on the method body at 6:1...
 --> src/lifetime-error.rs:6:1
  |
6 | #[async_trait]
  | ^^^^^^^^^^^^^^
  = note: ...so that the expression is assignable:
          expected std::pin::Pin<std::boxed::Box<(dyn core::future::future::Future<Output = Self> + std::marker::Send + 'async_trait)>>
             found std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = Self> + std::marker::Send>>

@UkonnRa UkonnRa changed the title Using type in async trait will cause lots of problem? Using type in async trait will cause some problem? Sep 16, 2019
@UkonnRa UkonnRa changed the title Using type in async trait will cause some problem? Using type in async trait will cause some problems? Sep 16, 2019
@dtolnay
Copy link
Owner

dtolnay commented Sep 18, 2019

This is a compiler bug. 😢 rust-lang/rust#60658

@wpbrown
Copy link

wpbrown commented Feb 20, 2021

I've run in to one type is more general than the other with the same types as well.

   | |_____^ one type is more general than the other
   |
   = note: expected type `FnOnce<(&Model,)>`
              found type `FnOnce<(&Model,)>`

This error only happens when the function call is in, or downstream of, an async_trait fn impl. There is no error when calling from outside an async_trait context.

I'm trying to figure out if this is the same issue or a different one? I've widdled down this repro (playground). The buffer_unordered() stream wrapper seems to trigger the issue. Calling the working function in build compiles.

@dtolnay
Copy link
Owner

dtolnay commented Nov 26, 2022

Closing in favor of rust-lang/rust#60658, since this is not going to be actionable in async-trait. We can reopen in the event that the rustc bug gets fixed in a way that doesn't immediately solve this.

@dtolnay dtolnay closed this as completed Nov 26, 2022
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

3 participants