Could we clarify type error messages that involve traits + closures?

ca328f9
Opened by David Teller at 2024-12-21 05:01:40

After a typo, I recently received the following error message:

error[E0277]: the trait bound `bintree::simple::BuilderError: std::convert::From<[closure@src/bintree/simple.rs:244:24: 244:51]>` is not satisfied
   --> src/bintree/simple.rs:243:24
    |
243 |               let kind = node.kind()
    |  ________________________^
244 | |                 .ok_or(|| BuilderError::MissingTag)?;
    | |____________________________________________________^ the trait `std::convert::From<[closure@src/bintree/simple.rs:244:24: 244:51]>` is not implemented for `bintree::simple::BuilderError`
    |
    = note: required by `std::convert::From::from`

The problem was that I used ok_or instead of ok_or_else. What I'd like to have seen (and what would have saved me a few minutes) is an additional line suggesting something like: « This operation does not work with a closure. »

Could we perhaps detect that the scope contains no implementation of From<T> where T is a closure? This could, of course, be extended to other traits, but I suspect that it is worse for Result<>, since the call to from is not visible in the syntax.

  1. It's likely that something can be improved here, I agree. Could you try to reproduce this in a smaller example (e.g., on playpen) so that it's easier to triage and get started on this bug for others?

    Mark Rousskov at 2017-06-23 12:21:45

  2. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ccf6631c29bce5cadfdc4b5dec5a52a4

    Esteban Kuber at 2020-04-29 22:48:57

  3. Current error:

    error[[E0277]](https://doc.rust-lang.org/nightly/error_codes/E0277.html): `?` couldn't convert the error to `()`
     --> src/main.rs:3:27
      |
    1 | fn foo() -> Result<(), ()> {
      |             -------------- expected `()` because of this
    2 |     let x: Option<i32> = Some(42);
    3 |     let _ = x.ok_or(|| ())?;
      |                           ^ the trait `From<[closure@src/main.rs:3:21: 3:23]>` is not implemented for `()`
      |
      = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
      = help: the following other types implement trait `From<T>`:
                <(T, T) as From<[T; 2]>>
                <(T, T, T) as From<[T; 3]>>
                <(T, T, T, T) as From<[T; 4]>>
                <(T, T, T, T, T) as From<[T; 5]>>
                <(T, T, T, T, T, T) as From<[T; 6]>>
                <(T, T, T, T, T, T, T) as From<[T; 7]>>
                <(T, T, T, T, T, T, T, T) as From<[T; 8]>>
                <(T, T, T, T, T, T, T, T, T) as From<[T; 9]>>
              and 4 others
      = note: required for `Result<(), ()>` to implement `FromResidual<Result<Infallible, [closure@src/main.rs:3:21: 3:23]>>`
    

    Dylan DPC at 2023-06-08 09:04:39