Skip to content

Suggest changing mains return type on E0277 (? / from_residual) #125997

Open

Description

@epage

Code

use std::fs::File;
use std::io::prelude::*;

fn main() {
    let mut file = File::create("foo.txt")?;
    file.write_all(b"Hello, world!")?;
}

Current output

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that
implements `FromResidual`)
 --> cargo-14007.rs:5:43
  |
4 | fn main() {
  | --------- this function should return `Result` or `Option` to accept `?`
5 |     let mut file = File::create("foo.txt")?;
  |                                           ^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that
implements `FromResidual`)
 --> cargo-14007.rs:6:37
  |
4 | fn main() {
  | --------- this function should return `Result` or `Option` to accept `?`
5 |     let mut file = File::create("foo.txt")?;
6 |     file.write_all(b"Hello, world!")?;
  |                                     ^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `cargo-14007` (bin "cargo-14007") due to 2 previous errors

Desired output

To suggest changing

fn main() {
    // ...
}

to

fn main() -> Result<(), Box<dyn Error>> {
    // ...
    Ok(())
}

Rationale and extra context

In rust-lang/cargo#14007, concern was raised over people generating a trivial fn main() {} with cargo new and copy/pasting example code that uses ? (which is encouraged in API guidelines). Regardless of the decision made for cargo new, this applies just as well to users hand writing a trivial fn main() {}. These are likely new users who would be intimidated by the current message and wouldn't know what next steps to take

Other cases

No response

Rust Version

rustc 1.78.0 (9b00956e5 2024-04-29)
binary: rustc
commit-hash: 9b00956e56009bab2aa15d7bff10916599e3d6d6
commit-date: 2024-04-29
host: x86_64-unknown-linux-gnu
release: 1.78.0
LLVM version: 18.1.2

Anything else?

No response

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jun 4, 2024
  2. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    on Jun 4, 2024
  3. surechen commented on Jun 7, 2024

    @surechen
    Contributor

    @rustbot claim

  4. added a commit that references this issue on Jun 9, 2024
    5daeba9
  5. added 2 commits that reference this issue on Jun 12, 2024
  6. added a commit that references this issue on Jun 12, 2024
  7. added 2 commits that reference this issue on Aug 18, 2024
  8. added 2 commits that reference this issue on Aug 18, 2024
  9. added a commit that references this issue on Aug 19, 2024
  10. added a commit that references this issue on Aug 19, 2024
  11. epage commented on Apr 29, 2025

    @epage
    ContributorAuthor

    I believe #126187 addressed my primary concern (fn main) and #128084 went further than that. I'm fine with this being closed.

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=b681e44892295838385e98410ed31197

       Compiling playground v0.0.1 (/playground)
    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:2:53
      |
    1 | fn main() {
      | --------- this function should return `Result` or `Option` to accept `?`
    2 |     let mut _file = std::fs::File::create("foo.txt")?;
      |                                                     ^ cannot use the `?` operator in a function that returns `()`
      |
      = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
    help: consider adding return type
      |
    1 ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
    2 |     let mut _file = std::fs::File::create("foo.txt")?;
    3 +     Ok(())
      |
    
    For more information about this error, try `rustc --explain E0277`.
    error: could not compile `playground` (bin "playground") due to 1 previous error
    
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions