rust-lang / rust-lang/rust

Cascading errors from unsatisfied trait bounds

Open
#117,515 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
use futures_util::StreamExt;
use azure_storage_blobs::prelude::BlobClient;

async fn fetch_object(blob_client: BlobClient) -> Result<hyper::Body, Box<dyn std::error::Error>> {
    let azure_stream = blob_client.get().into_stream().flat_map(|chunk| {
        chunk.map(|blob| blob.data)
    });
    Ok(hyper::Body::wrap_stream(azure_stream))
}
Current output
error[E0277]: the trait bound `Result<azure_core::response::ResponseBody, azure_core::error::Error>: Stream` is not satisfied
   --> src/main.rs:5:56
    |
5   |     let azure_stream = blob_client.get().into_stream().flat_map(|chunk| {
    |                                                        ^^^^^^^^ the trait `Stream` is not implemented for `Result<azure_core::response::ResponseBody, azure_core::error::Error>`
    |
    = help: the following other types implement trait `Stream`:
              async_channel::Receiver<T>
              futures_channel::mpsc::Receiver<T>
              futures_channel::mpsc::UnboundedReceiver<T>
              tokio_util::sync::poll_semaphore::PollSemaphore
              Body
              Box<S>
              tokio_util::either::Either<L, R>
              tokio_util::io::sink_writer::SinkWriter<S>
            and 127 others
note: required by a bound in `futures_util::StreamExt::flat_map`
   --> /Users/jyn/.local/lib/cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.29/src/stream/stream/mod.rs:861:12
    |
858 |     fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
    |        -------- required by a bound in this associated function
...
861 |         U: Stream,
    |            ^^^^^^ required by this bound in `StreamExt::flat_map`

error[E0277]: the trait bound `Result<azure_core::response::ResponseBody, azure_core::error::Error>: Stream` is not satisfied
   --> src/main.rs:8:33
    |
8   |     Ok(hyper::Body::wrap_stream(azure_stream))
    |        ------------------------ ^^^^^^^^^^^^ the trait `Stream` is not implemented for `Result<azure_core::response::ResponseBody, azure_core::error::Error>`
    |        |
    |        required by a bound introduced by this call
    |
    = help: the following other types implement trait `Stream`:
              async_channel::Receiver<T>
              futures_channel::mpsc::Receiver<T>
              futures_channel::mpsc::UnboundedReceiver<T>
              tokio_util::sync::poll_semaphore::PollSemaphore
              Body
              Box<S>
              tokio_util::either::Either<L, R>
              tokio_util::io::sink_writer::SinkWriter<S>
            and 127 others
    = note: required for `Flatten<Map<Pageable<..., ...>, ...>, ...>` to implement `Stream`
    = note: the full type name has been written to '/Users/jyn/.local/lib/cargo/target/debug/deps/example-12c218bf13b78b0c.long-type-15395125195545820898.txt'
note: required by a bound in `Body::wrap_stream`
   --> /Users/jyn/.local/lib/cargo/registry/src/index.crates.io-6f17d22bba15001f/hyper-0.14.27/src/body/body.rs:192:19
    |
190 |     pub fn wrap_stream<S, O, E>(stream: S) -> Body
    |            ----------- required by a bound in this associated function
191 |     where
192 |         S: Stream<Item = Result<O, E>> + Send + 'static,
    |                   ^^^^^^^^^^^^^^^^^^^ required by this bound in `Body::wrap_stream`

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

No response

Rationale and extra context

There are a few things that could be improved from this output.

  1. Listing all possible types that implement Stream is unhelpful (there might already be an issue open for this); they are unrelated to the data I need to get out of azure_stream. Maybe it would be good to only suggest types which can be created from any of the intermediate types? e.g. into_stream returns a Pageable<GetBlobResponse> that implements stream, so suggest that type and things like Map<Pageable>?
  2. The first error points at flat_map, which is good, but it would be even better if it pointed at the place where it infers the return type of the closure (line 6). The signature of flat_map is
    fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
    where
        F: FnMut(Self::Item) -> U,
        U: Stream,

and the error complains about U, so it should point to U.
3. The error on wrap_stream is quite confusing. Here is the signature of wrap_stream:

    pub fn wrap_stream<S, O, E>(stream: S) -> Body
    where
        S: Stream<Item = Result<O, E>> + Send + 'static,
        O: Into<Bytes> + 'static,
        E: Into<Box<dyn StdError + Send + Sync>> + 'static

As far as I can tell, the problem here is actually the same as before: flat_map requires U to implement Stream. But the error has somehow lost the context of flat_map, and doesn't know how to name U, and so it settles for "required for Flatten<Map<Pageable<..., ...>, ...>, ...> to implement Stream". I think this error should just be hidden altogether, it doesn't add any info.

Other cases

No response

Anything else?

The full type name written to disk is stream::stream::flatten::Flatten<futures_util::stream::Map<azure_core::pageable::pageable::Pageable<GetBlobResponse, azure_core::error::Error>, {closure@src/main.rs:5:65: 5:72}>, Result<azure_core::response::ResponseBody, azure_core::error::Error>>.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the diagnostic with the Rust example in src/main.rs and inspect the E0277 output for flat_map and hyper::Body::wrap_stream. The work is complete when the output avoids unrelated Stream implementors, points the first error at the closure return type, and removes the redundant downstream error.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.