Skip to content

nightly-only types are confusing in error[E0277]: ? couldn't convert the error to ... #121521

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

Open
ericseppanen opened this issue Feb 23, 2024 · 4 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ericseppanen
Copy link
Contributor

ericseppanen commented Feb 23, 2024

Code

struct BarError;

fn bar() -> Result<(), BarError> {
    Ok(())
}

struct FooError;

fn foo() -> Result<(), FooError> {
    bar()?;

    Ok(())
}

fn main() {
    foo();
}

Current output

error[E0277]: `?` couldn't convert the error to `FooError`
  --> src/main.rs:11:10
   |
10 | fn foo() -> Result<(), FooError> {
   |             -------------------- expected `FooError` because of this
11 |     bar()?;
   |     -----^ the trait `From<BarError>` is not implemented for `FooError`
   |     |
   |     this can't be annotated with `?` because it has type `Result<_, BarError>`
   |
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
   = help: the following other types implement trait `FromResidual<R>`:
             <Result<T, F> as FromResidual<Yeet<E>>>
             <Result<T, F> as FromResidual<Result<Infallible, E>>>
   = note: required for `Result<(), FooError>` to implement `FromResidual<Result<Infallible, BarError>>`

Desired output

I'm not sure.

Rationale and extra context

This is a very common error, and it's likely to be encountered by people new to Rust.

The note and help text mentions two different types that are nightly-only (Yeet, FromResidual). To someone who is learning the language or only using the stable compiler, this is both confusing and unhelpful.

I think the stable compiler should avoid mentioning internal or nightly-only types, and when possible, the advice given should be understandable and actionable by someone new to the language.

If the last two messages are only going to talk about nightly only types, and they're not actually helpful to someone using the stable compiler, maybe they should just be removed?

Other cases

No response

Rust Version

rustc 1.76.0 (07dca489a 2024-02-04)
binary: rustc
commit-hash: 07dca489ac2d933c78d3c5158e3f43beefeb02ce
commit-date: 2024-02-04
host: x86_64-unknown-linux-gnu
release: 1.76.0
LLVM version: 17.0.6

Anything else?

I filed this bug after a conversation with @estebank on mastodon. 👋

@ericseppanen ericseppanen 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 Feb 23, 2024
@jieyouxu jieyouxu added D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue labels Feb 23, 2024
@ericseppanen
Copy link
Contributor Author

I should also note that the "terminal" representation of this error isn't that bad, but in rust-analyzer (in vscode anyway) it's a lot more confusing, because it mashes all the text together, making it harder to identify the useful part.

weiznich added a commit to weiznich/rust that referenced this issue Jul 20, 2024
This commit starts using `#[diagnostic::do_not_recommend]` in the
standard library to improve some error messages. In this case we just
hide a certain nightly only impl as suggested in rust-lang#121521
weiznich added a commit to weiznich/rust that referenced this issue Jul 22, 2024
This commit starts using `#[diagnostic::do_not_recommend]` in the
standard library to improve some error messages. In this case we just
hide a certain nightly only impl as suggested in rust-lang#121521
tgross35 added a commit to tgross35/rust that referenced this issue Jul 22, 2024
Start using `#[diagnostic::do_not_recommend]` in the standard library

This commit starts using `#[diagnostic::do_not_recommend]` in the standard library to improve some error messages. In this case we just hide a certain nightly only impl as suggested in rust-lang#121521

The result in not perfect yet, but at least the `Yeet` suggestion is not shown anymore. I would consider that as a minor improvement.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jul 22, 2024
Rollup merge of rust-lang#128008 - weiznich:fix/121521, r=lcnr

Start using `#[diagnostic::do_not_recommend]` in the standard library

This commit starts using `#[diagnostic::do_not_recommend]` in the standard library to improve some error messages. In this case we just hide a certain nightly only impl as suggested in rust-lang#121521

The result in not perfect yet, but at least the `Yeet` suggestion is not shown anymore. I would consider that as a minor improvement.
@RodBurman
Copy link

Using this version:

 % cargo -v -V
cargo 1.86.0 (adf9b6ad1 2025-02-28)
release: 1.86.0
commit-hash: adf9b6ad14cfa10ff680d5806741a144f7163698
commit-date: 2025-02-28
host: aarch64-apple-darwin
libgit2: 1.9.0 (sys:0.20.0 vendored)
libcurl: 8.7.1 (sys:0.4.79+curl-8.12.0 system ssl:(SecureTransport) LibreSSL/3.3.6)
ssl: OpenSSL 1.1.1w  11 Sep 2023
os: Mac OS 15.4.0 [64-bit]

The error is now this:

 % cargo build
   Compiling nightlyonly v0.1.0 (/Users/rod/code/rust/triage/nightlyonly)
error[E0277]: `?` couldn't convert the error to `FooError`
  --> src/main.rs:10:10
   |
9  | fn foo() -> Result<(), FooError> {
   |             -------------------- expected `FooError` because of this
10 |     bar()?;
   |     -----^ the trait `From<BarError>` is not implemented for `FooError`
   |     |
   |     this can't be annotated with `?` because it has type `Result<_, BarError>`
   |
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
   = help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
   = note: required for `Result<(), FooError>` to implement `FromResidual<Result<Infallible, BarError>>`

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

Which is not so confusing, I think. So can this issue be closed?

@ericseppanen
Copy link
Contributor Author

I agree, it's better than it was before. But I think we can do better.

The FromResidual trait is unstable so it still seems unhelpful to print it in errors from the stable toolchain. A new rust developer would probably not understand this error.

It's also unhelpful that two lines of the error message go on about ``FromResidual<Result<Infallible, _>>` which is completely irrelevant to this code. This must be one of the most common beginner errors, so it seems like a good place to be as clear and helpful as we can.

@RodBurman
Copy link

Agreed, what we really need (I think) is a message that "de-sugars" the ? to its equivalent match expression, which makes the error much plainer, so something like:

= note: bar()? is syntactic sugar for:
   match bar() {
        Err(err) => return Err(From::from(err)),
        Ok(ok) => ok,
    }
which returns a Result<(), BarError> not the Result<(), FooError> required by the definition fn foo() -> Result<(), FooError>

Note if I replace bar()? with match (as above) in the sample code the error becomes:

% cargo build   
   Compiling nightlyonly v0.1.0 (/Users/rod/code/rust/triage/nightlyonly)
error[E0277]: the trait bound `FooError: From<BarError>` is not satisfied
  --> src/main.rs:12:43
   |
12 |         Err(err) => return Err(From::from(err)),
   |                                ---------- ^^^ the trait `From<BarError>` is not implemented for `FooError`
   |                                |
   |                                required by a bound introduced by this call

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

Which does nicely explain the problem and gives one way to solve it (implement From for FooError).

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 D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue 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