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

suggest Ok-wrapping for ?-originating type mismatch when (and only when) applicable #55429

Closed
zackmdavis opened this issue Oct 27, 2018 · 2 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@zackmdavis
Copy link
Member

Sometimes E0308 on a try-expression can be fixed by wrapping with Ok. This is a somewhat common mistake in the form of a ?-expression appearing in tail position of a function that is expected to Result

fn foo() -> Result<isize, ()> {
     Ok(1)
}
 
fn bar() -> Result<isize, ()> {
    foo()? // `Ok(foo()?)` would work
}

fn main() {}

However, not all type mismatches on ? are like this. Here's a negative example—

fn maybe_numbers() -> Result<Vec<i32>, ()> {
    Ok(vec![1, 2, 3])
}

fn try_it() -> Result<String, ()> {
    let n: i32 = maybe_numbers()?; // `Ok(maybe_numbers()?)` is not the right move here
    Ok(format!("{:?}", n))
}

fn main() {}

We want to suggest Ok-wrapping when that's the correct fix. (This issue is being filed because a previous attempt at this suggestion had too many false positives and is likely to be removed.)

See discussion on #52537 for one idea on how to proceed.

@zackmdavis zackmdavis added the A-diagnostics Area: Messages for errors, warnings, and lints label Oct 27, 2018
@estebank
Copy link
Contributor

estebank commented Jun 11, 2019

Current (correct) output for the first case:

error[E0308]: try expression alternatives have incompatible types
 --> src/main.rs:6:5
  |
6 |     foo()?
  |     ^^^^^-
  |     |    |
  |     |    help: try removing this `?`
  |     expected enum `std::result::Result`, found isize
  |
  = note: expected type `std::result::Result<isize, ()>`
             found type `isize`

@estebank estebank added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Sep 26, 2019
@crlf0710 crlf0710 added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jun 11, 2020
@estebank
Copy link
Contributor

estebank commented Aug 3, 2023

Current output:

error[[E0308]](https://doc.rust-lang.org/stable/error_codes/E0308.html): `?` operator has incompatible types
 --> src/main.rs:6:5
  |
6 |     foo()?
  |     ^^^^^^ expected `Result<isize, ()>`, found `isize`
  |
  = note: `?` operator cannot convert from `isize` to `Result<isize, ()>`
  = note: expected enum `Result<isize, ()>`
             found type `isize`
help: try removing this `?`
  |
6 -     foo()?
6 +     foo()
  |
help: try wrapping the expression in `Ok`
  |
6 |     Ok(foo()?)
  |     +++      +
error[[E0308]](https://doc.rust-lang.org/stable/error_codes/E0308.html): `?` operator has incompatible types
 --> src/main.rs:6:18
  |
6 |     let n: i32 = maybe_numbers()?; // `Ok(maybe_numbers()?)` is not the right move here
  |                  ^^^^^^^^^^^^^^^^ expected `i32`, found `Vec<i32>`
  |
  = note: `?` operator cannot convert from `Vec<i32>` to `i32`
  = note: expected type `i32`
           found struct `Vec<i32>`

@estebank estebank closed this as completed Aug 3, 2023
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 C-enhancement Category: An issue proposing an enhancement or a PR with one. 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

3 participants