rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.69k stars 12.75k forks source link

hrtb + infer types break auto traits with return type notation #109924

Open compiler-errors opened 1 year ago

compiler-errors commented 1 year ago

I tried this code:

#![feature(async_fn_in_trait)]
#![feature(return_type_notation)]

trait Foo {
    async fn bar(&self);
}

struct Bar;
impl Foo for Bar {
    async fn bar(&self) {}
}

fn build<T>(_: T) where T: Foo<bar(..): Send> {}

fn main() {
    build(Bar);
}

I expected it to compile, instead:

error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
  --> src/main.rs:16:11
   |
16 |     build(Bar);
   |     ----- ^^^ `impl Future<Output = ()>` cannot be sent between threads safely
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `for<'a> Send` is not implemented for `impl Future<Output = ()>`
note: required by a bound in `build`
  --> src/main.rs:13:41
   |
13 | fn build<T>(_: T) where T: Foo<bar(..): Send> {}
   |                                         ^^^^ required by this bound in `build`

For more information about this error, try `rustc --explain E0277`.

This error message is not super clear, but it's essentially equvialent to this code:

trait Foo {
    type Bar<'a> where Self: 'a;

    fn bar(&self) -> Self::Bar<'_>;
}

struct Bar;
impl Foo for Bar {
    type Bar<'a> = ();

    fn bar(&self) {}
}

fn build<T>(_: T) where T: Foo, for<'a> T::Bar<'a>: Send {}

fn main() {
    build(Bar);
}

Which results in:

error[E0277]: `<_ as Foo>::Bar<'a>` cannot be sent between threads safely
  --> src/main.rs:17:11
   |
17 |     build(Bar);
   |     ----- ^^^ `<_ as Foo>::Bar<'a>` cannot be sent between threads safely
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `for<'a> Send` is not implemented for `<_ as Foo>::Bar<'a>`
note: required by a bound in `build`
  --> src/main.rs:14:53
   |
14 | fn build<T>(_: T) where T: Foo, for<'a> T::Bar<'a>: Send {}
   |                                                     ^^^^ required by this bound in `build`

So this is related to other higher-ranked projection normalization problems.

compiler-errors commented 1 year ago

I've put up a PR that improves the explanation of this error: #115625

And one that makes the RTN future a bit easier to understand: #115624