Could we clarify type error messages that involve traits + closures?
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.
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
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ccf6631c29bce5cadfdc4b5dec5a52a4
Esteban Kuber at 2020-04-29 22:48:57
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