Skip to content

Backwards propagation of types leads to unhelpful errors [futures] #46606

Open
@mqudsi

Description

@mqudsi

In general, and I genuinely wish I had a citation for this, developers likely tend to write their software going from input to output, even if the output is the eventual, fixed "goal" they would like to reach.

For example, the code here (git checkout available): https://git.neosmart.net/mqudsi/futuretest/src/rust-46606

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

Two conflicting error types are mapped, the first is to &'static str and the second is to String, the compiler output indicates an error with the &'static str type instead of the String type usage:

   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:13:10
   |
13 |         .and_then(|_|
   |          ^^^^^^^^ expected struct `std::string::String`, found &str
   |
   = note: expected type `std::string::String`
              found type `&str`

error[E0271]: type mismatch resolving `<futures::FutureResult<(), std::string::String> as futures::IntoFuture>::Error == &str`
  --> src/main.rs:20:10
   |
20 |     core.run(f).unwrap();
   |          ^^^ expected struct `std::string::String`, found &str
   |
   = note: expected type `std::string::String`
              found type `&str`
   = note: required because of the requirements on the impl of `futures::Future` for `futures::AndThen<futures::Map<futures::MapErr<futures::FutureResult<(), ()>, [closure@src/main.rs:11:18: 11:43]>, [closure@src/main.rs:12:14: 12:67]>, futures::FutureResult<(), std::string::String>, [closure@src/main.rs:13:19: 16:14]>`

error: aborting due to 2 previous errors

error: Could not compile `futuretest`.

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

In an ideal situation, all types would match up and it wouldn't matter which line the type inference began with. But in the event of a type mismatch, such as here, the reported errors are based off the backwards type propagation, which doesn't seem right (opinion) and leads to an unhelpful error message (fact).

(To make the case a bit clearer, I included several uses of the correct type followed by a final usage of the incorrect type).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions