Unsatisfied bounds in case of earlier inner type mismatch error

62aac10
Opened by Mahmoud Al-Qudsi at 2023-07-28 13:05:33

In case of a type mismatch when chaining/mapping between a FutureResult<x,y> and FutureResult<x,z>, the compiler also emits (invalid) errors about unsatisfied bounds for any subsequent future operations, even though the type mismatch is only the inner type within the FutureResult<_,_> (i.e. in all cases the result of the operation is a future).

Here's an example (git link):

    let f = future::result::<(),()>(Ok(()))
        .map_err(|_| "&'static str error")
        .and_then(|_|
             future::result(Ok(())
                .map_err(|()| "String error".to_owned())
            )
        )
        .and_then(|_| future::result::<(), String>(Err("another &'static str error".to_owned())))

generating the following errors, the second of which is the point of this issue:

   Compiling futuretest v0.1.0 (file:///mnt/c/Users/Mahmoud/git/futuretest)
error[E0271]: type mismatch resolving `<futures::FutureResult<(), std::string::String> as futures::IntoFuture>::Error == &str`
  --> src/main.rs:12:10
   |
12 |         .and_then(|_|
   |          ^^^^^^^^ expected struct `std::string::String`, found &str
   |
   = note: expected type `std::string::String`
              found type `&str`

error[E0599]: no method named `and_then` found for type `futures::AndThen<futures::MapErr<futures::FutureResult<(), ()>, [closure@src/main.rs:11:18: 11:42]>, futures::FutureResult<(), std::string::String>, [closure@src/main.rs:12:19: 15:14]>` in the current scope
  --> src/main.rs:17:10
   |
17 |         .and_then(|_| future::result::<(), String>(Err("another &'static str error".to_owned())))
   |          ^^^^^^^^
   |
   = note: the method `and_then` exists but the following trait bounds were not satisfied:
           `futures::AndThen<futures::MapErr<futures::FutureResult<(), ()>, [closure@src/main.rs:11:18: 11:42]>, futures::FutureResult<(), std::string::String>, [closure@src/main.rs:12:19: 15:14]> : futures::Future`
           `&mut futures::AndThen<futures::MapErr<futures::FutureResult<(), ()>, [closure@src/main.rs:11:18: 11:42]>, futures::FutureResult<(), std::string::String>, [closure@src/main.rs:12:19: 15:14]> : futures::Future`

error: aborting due to 2 previous errors

error: Could not compile `futuretest`.

To learn more, run the command again with --verbose.

Resolving the type mismatch fixes the first error and makes the second error go away entirely.

As the trait is implemented regardless of the inner type, it should be possible for the compiler to detect that the second error is not real.

  1. Current output:

    error[E0271]: type mismatch resolving `<Done<(), String> as IntoFuture>::Error == &str`
       --> src/main.rs:12:10
        |
    12  |         .and_then(|_|
        |          ^^^^^^^^ expected `&str`, found struct `String`
        |
    note: required by a bound in `futures::Future::and_then`
       --> /home/gh-estebank/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.17/src/future/mod.rs:527:29
        |
    527 |               B: IntoFuture<Error = Self::Error>,
        |                             ^^^^^^^^^^^^^^^^^^^ required by this bound in `Future::and_then`
    
    error[E0599]: the method `and_then` exists for struct `AndThen<MapErr<Done<(), ()>, [closure@main.rs:11:18]>, Done<(), String>, [closure@main.rs:12:19]>`, but its trait bounds were not satisfied
      --> src/main.rs:17:10
       |
    17 |         .and_then(|_| future::result::<(), String>(Err("another &'static str error".to_owned())))
       |          ^^^^^^^^ method cannot be called due to unsatisfied trait bounds
       |
      ::: /home/gh-estebank/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.17/src/future/result.rs:13:1
       |
    13 | pub struct FutureResult<T, E> {
       | ----------------------------- doesn't satisfy `<_ as IntoFuture>::Error = &str`
       |
      ::: /home/gh-estebank/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.17/src/future/and_then.rs:10:1
       |
    10 | pub struct AndThen<A, B, F> where A: Future, B: IntoFuture {
       | --------------------------- doesn't satisfy `_: Future`
       |
       = note: the following trait bounds were not satisfied:
               `<Failed<(), String> as futures::IntoFuture>::Error = &str`
               which is required by `futures::AndThen<futures::MapErr<Failed<(), ()>, [closure@src/main.rs:11:18: 11:21]>, Failed<(), String>, [closure@src/main.rs:12:19: 12:22]>: futures::Future`
               `futures::AndThen<futures::MapErr<Failed<(), ()>, [closure@src/main.rs:11:18: 11:21]>, Failed<(), String>, [closure@src/main.rs:12:19: 12:22]>: futures::Future`
               which is required by `&mut futures::AndThen<futures::MapErr<Failed<(), ()>, [closure@src/main.rs:11:18: 11:21]>, Failed<(), String>, [closure@src/main.rs:12:19: 12:22]>: futures::Future`
    
    Some errors have detailed explanations: E0271, E0599.
    For more information about an error, try `rustc --explain E0271`.
    

    Esteban Kuber at 2023-07-28 13:05:33