Open
Description
cargo init
currently produces boilerplate that looks like this:
fn main() {
println!("Hello, world!");
}
However, if someone starts from this boilerplate and pastes in examples from documentation that use ?
, they'll get an error. main doesn't return Result, so ?
can't be used. The API guidelines recommend that examples use ?
rather than unwrap.
As an example, if someone tries to paste in this small File example:
use std::fs::File;
use std::io::prelude::*;
fn main() {
let mut file = File::create("foo.txt")?;
file.write_all(b"Hello, world!")?;
}
They get some rather confusing errors (what's FromResidual?):
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/main.rs:5:43
|
4 | / fn main() {
5 | | let mut file = File::create("foo.txt")?;
| | ^ cannot use the `?` operator in a function that returns `()`
6 | | file.write_all(b"Hello, world!")?;
7 | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
note: required by `from_residual`
--> /home/jsha/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/try_trait.rs:339:5
|
339 | fn from_residual(residual: R) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/main.rs:6:37
|
4 | / fn main() {
5 | | let mut file = File::create("foo.txt")?;
6 | | file.write_all(b"Hello, world!")?;
| | ^ cannot use the `?` operator in a function that returns `()`
7 | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
note: required by `from_residual`
--> /home/jsha/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/try_trait.rs:339:5
|
339 | fn from_residual(residual: R) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0277`.
This is a problem I remember running into when I was first learning the language. I suspect it may be an issue for other language learners too.
I propose changing the boilerplate to:
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
println!("Hello, world!");
Ok(())
}
This compiles cleanly and passes clippy.