Closed
Description
This is a thing that occured to me while giving a training on Rust: the diagnostics of ?
over try!
are worse, despite it being special syntax.
Compare:
fn main() {
}
try() {
try!(std::fs::File::open("foo"));
}
rustc 1.19.0-nightly (258ae6dd9 2017-06-15)
error[E0308]: mismatched types
--> <anon>:6:5
|
6 | try!(std::fs::File::open("foo"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::Result`
|
= note: expected type `()`
found type `std::result::Result<_, _>`
= note: this error originates in a macro outside of the current crate
error: aborting due to previous error(s)
over:
fn main() {
}
fn question() {
std::fs::File::open("foo")?;
}
rustc 1.19.0-nightly (258ae6dd9 2017-06-15)
error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
--> <anon>:6:5
|
6 | std::fs::File::open("foo")?;
| ---------------------------
| |
| the trait `std::ops::Try` is not implemented for `()`
| in this macro invocation
|
= note: required by `std::ops::Try::from_error`
While the second makes perfect sense to advanced Rust developers, it is confusing to newcomers and leaks a lot of internal details. People have to know about traits, about the ops
module, and similar. Also, it reports a macro invocation, where - from a user perspective - there is none. To my knowledge, this is the only place where we do this.
Considering that ?
raises a macro to syntax, I would also think it gives opportunity for better diagnostics. It is a crucial part of the language with non-trivial semantics and making a pass on giving better errors here would help newcomers a lot.