rust-lang / rust

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

Improve output of E0271 #40186

Closed seanmonstar closed 1 year ago

seanmonstar commented 7 years ago

This error is encountered often with futures and tokio, where a returned future has an associated type that doesn't match the expected return type.

An example of current behavior:

error[E0271]: type mismatch resolving `<futures::AndThen<futures::stream::Fold<futures::stream::MapErr<hyper::Body, [closure@src/consumer/pinger.rs:100:41: 107:18 uri:_, request_type:_, correlation_id:_, tx:_, event:_]>, [closure@src/consumer/pinger.rs:107:35: 110:18], futures::FutureResult<std::vec::Vec<u8>, futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>>, std::vec::Vec<u8>>, futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>, [closure@src/consumer/pinger.rs:110:29: 127:18 timer:_, status_code:_, response_status:_, uri:_, tx:_, event:_, headers:_, request_type:_, correlation_id:_]> as futures::IntoFuture>::Error == futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>`
   |
16 |     Box::new(
   |     ^ expected futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>, found struct `io::Error`
   |
   = note: expected type `futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>`
   = note:    found type `io::Error`
   = note: required for the cast to the object type `Future<Error=futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>> + 'static`

And a playpen of a the current behavior (though the error is much smaller): https://is.gd/iigJ2p

A message like this pushes the actionable information down several lines. It may help to instead, output something like this:

error[E0271]: type mismatch resolving `<futures::AndThen<...>::Error`
   |
16 |     Box::new(
   |     ^ expected futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>, found struct `io::Error`
   |
   = note: expected type `futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>`
   = note:    found type `io::Error`
   = note: required for the cast to the object type `Future<Error=futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>> + 'static`
   = note: full type is `<futures::AndThen<futures::stream::Fold<futures::stream::MapErr<hyper::Body, [closure@src/consumer/pinger.rs:100:41: 107:18 uri:_, request_type:_, correlation_id:_, tx:_, event:_]>, [closure@src/consumer/pinger.rs:107:35: 110:18], futures::FutureResult<std::vec::Vec<u8>, futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>>, std::vec::Vec<u8>>, futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>, [closure@src/consumer/pinger.rs:110:29: 127:18 timer:_, status_code:_, response_status:_, uri:_, tx:_, event:_, headers:_, request_type:_, correlation_id:_]> as futures::IntoFuture>::Error == futures::sink::Send<futures::sync::mpsc::Sender<(events::http_request_event::HttpRequestEvent, std::result::Result<consumer::pinger::HttpResult, consumer::pinger::HttpResult>)>>`

Additionally, it might be even clearer to omit some of the type parameters (leaving enough to differentiate) in the 'expected' and 'found' notes, leaving the full type for the bottom note.

error[E0271]: type mismatch resolving `<futures::AndThen<...>::Error`
   |
16 |     Box::new(
   |     ^ expected futures::sink::Send<...>, found struct `io::Error`
   |
   = note: expected type `futures::sink::Send<...>`
   = note:    found type `io::Error`

cc @eddyb

eddyb commented 7 years ago

cc @jonathandturner

estebank commented 7 years ago

Related to #21025 (& closed PR #39906).

alexcrichton commented 7 years ago

I was searching around for this issue, writing down some keywords so I hopefully can find it easier in the future:

estebank commented 6 years ago

Re https://github.com/rust-lang/rust/issues/43354

estebank commented 5 years ago

Current output:

error[E0271]: type mismatch resolving `<std::result::Result<std::result::Result<(), std::result::Result<std::result::Result<(), std::result::Result<std::result::Result<(), std::option::Option<{integer}>>, ()>>, ()>>, ()> as Future>::Error == Foo`
  --> src/main.rs:16:5
   |
16 | /     Box::new(
17 | |         Ok::<_, ()>(
18 | |             Err::<(), _>(
19 | |                 Ok::<_, ()>(
...  |
28 | |         )
29 | |     )
   | |_____^ expected (), found struct `Foo`
   |
   = note: expected type `()`
              found type `Foo`
   = note: required for the cast to the object type `dyn Future<Error = Foo>`
estebank commented 1 year ago

Triage: few changes

error[[E0271]](https://doc.rust-lang.org/nightly/error-index.html#E0271): type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()> as Future>::Error == Foo`
  --> src/main.rs:16:5
   |
16 | /     Box::new(
17 | |         Ok::<_, ()>(
18 | |             Err::<(), _>(
19 | |                 Ok::<_, ()>(
...  |
28 | |         )
29 | |     )
   | |_____^ type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()> as Future>::Error == Foo`
   |
note: expected this to be `Foo`
  --> src/main.rs:6:18
   |
6  |     type Error = E;
   |                  ^
   = note: required for the cast from `Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()>` to the object type `dyn Future<Error = Foo>`