Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved messaging for ? within a function with () return type - E0277 #101281

Closed
amanjeev opened this issue Sep 1, 2022 · 5 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@amanjeev
Copy link
Member

amanjeev commented Sep 1, 2022

This is mostly a suggestion if there can be some improvement to the diagnostics.

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0aa16f03b3a56a8133bf2023fd8a0c4e

use std::num::ParseIntError;

fn retoptionres(x: &str) -> Result<Option<u32>, ParseIntError> {
    let n = x.parse::<u32>()?;
    Ok(Some(n))
}

fn main() {
    let x = retoptionres("4")??;
    println!("{:?}", x);
}

The current output is:

Compiling playground v0.0.1 (/playground)
error[[E0277]](https://doc.rust-lang.org/stable/error-index.html#E0277): the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
  --> src/main.rs:9:30
   |
8  | / fn main() {
9  | |     let x = retoptionres("4")??;
   | |                              ^ cannot use the `?` operator in a function that returns `()`
10 | |     println!("{:?}", x);
11 | | }
   | |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `FromResidual<Result<Infallible, ParseIntError>>` is not implemented for `()`

Ideally the output should look like:

Compiling playground v0.0.1 (/playground)
error[[E0277]](https://doc.rust-lang.org/stable/error-index.html#E0277): the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
  --> src/main.rs:9:30
   |
8  | / fn main() {
9  | |     let x = retoptionres("4")??;
   | |                              ^ cannot use the `?` operator in a function that returns `()`
10 | |     println!("{:?}", x);
11 | | }
   | |_- this function (crate::main) should return `Result` or `Option` to accept `?`
   |    - Hint: add an `Option` or `Result` return type to `main`
   = help: the trait `FromResidual<Result<Infallible, ParseIntError>>` is not implemented for `()`

This error is easier to miss because busy-ness and not knowing which function needs the return type.

@amanjeev amanjeev added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 1, 2022
@compiler-errors
Copy link
Member

compiler-errors commented Sep 1, 2022

I'm not sure if that hint: you suggested adds more value than the labeled message that's directly above it.

Regarding "not knowing which function needs the return type", it's already being pointed out in the error message? Do you have a better example for where this is particularly confusing?

@amanjeev
Copy link
Member Author

amanjeev commented Sep 2, 2022

Regarding "not knowing which function needs the return type", it's already being pointed out in the error message? Do you have a better example for where this is particularly confusing?

I think the pointed out part is using those ascii characters (| and /). I feel that having at least the function name that the error is talking about would be beneficial.

If you think the hint I suggested does not add more value, thats fine.

bors added a commit to rust-lang-ci/rust that referenced this issue Sep 4, 2022
…ing-scope, r=oli-obk

Use head span for `rustc_on_unimplemented`'s `enclosing_scope` attr

This may make rust-lang#101281 slightly easier to understand
@compiler-errors
Copy link
Member

This error now looks like:

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:9:30
  |
8 | fn main() {
  | --------- this function should return `Result` or `Option` to accept `?`
9 |     let x = retoptionres("4")??;
  |                              ^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `FromResidual<Result<Infallible, ParseIntError>>` 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`)
 --> src/main.rs:9:31
  |
8 | fn main() {
  | --------- this function should return `Result` or `Option` to accept `?`
9 |     let x = retoptionres("4")??;
  |                               ^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`

Is that better?

@amanjeev
Copy link
Member Author

amanjeev commented Sep 9, 2022

Thank you! I think this is better. Are you ok with this change?

@compiler-errors
Copy link
Member

I'm gonna close this issue as completed then, please re-open an issue if you continue to find this error message confusing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants