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

[ui] Incorrect hint: Ok(wrap) instead *Deref #52537

Closed
boozook opened this issue Jul 19, 2018 · 5 comments · Fixed by #55423
Closed

[ui] Incorrect hint: Ok(wrap) instead *Deref #52537

boozook opened this issue Jul 19, 2018 · 5 comments · Fixed by #55423
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug.

Comments

@boozook
Copy link

boozook commented Jul 19, 2018

Reproduced on versions:

  • rustc 1.29.0-nightly (12ed235ad 2018-07-18)
  • rustc 1.29.0-nightly (9fd3d7899 2018-07-07)
  • rustc 1.27.0 (3eda71b00 2018-06-19)

Isolated example to reproduce:

use std::ops::Deref;

struct Error {}
struct State {}
struct StateDeref { inner: State }

impl Deref for StateDeref {
	type Target = State;
	fn deref(&self) -> &Self::Target { &self.inner }
}

fn get_state() -> Result<StateDeref, Error> { Err(Error {}) }

fn need_ref_state_from(state: &State) -> bool { true }

fn state_info() -> Result<bool, Error> { Ok(need_ref_state_from(&get_state()?)) }

Actual error:

error[E0308]: try expression alternatives have incompatible types
   --> src/main.rs:16:66
    |
16  | fn state_info() -> Result<bool, Error> { Ok(need_ref_state_from(&get_state()?)) }
    |                                                                  ^^^^^^^^^^^^
    |                                                                  |
    |                                                                  expected struct `State`, found struct `StateDeref`
    |                                                                  help: try wrapping with a success variant: `Ok(get_state()?)`
    |
    = note: expected type `State`
               found type `StateDeref`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

Mentioned suggestion about "wrap into Ok" is incorrect at all. There we should deref the value from the get_state()?.


Expected error: (something like this)

...
expected struct `State`, found struct `StateDeref`
help: try re-dereference(?) with a success variant: `&*get_state()?`
@oli-obk oli-obk added A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. labels Jul 19, 2018
@zackmdavis
Copy link
Member

Here's where the suggestion gets issued:

hir::MatchSource::TryDesugar => { // Issue #51632
if let Ok(try_snippet) = self.tcx.sess.codemap().span_to_snippet(arm_span) {
err.span_suggestion_with_applicability(
arm_span,
"try wrapping with a success variant",
format!("Ok({})", try_snippet),
Applicability::MachineApplicable
);
}
},

The motivation was to solve #51632 (where a ?-expression appears in tail position, which seemed likely to be a common mistake), but it turns out that there are other situations where we run into a type mismatch between match arms of a desugared ? expression. We regret the error.

@kornelski
Copy link
Contributor

kornelski commented Aug 1, 2018

Here's another case of this:

struct Foo;

fn takes_ref(_r: &Foo) {}

fn returns_result() -> Result<Foo,()> {}

fn main() -> Result<(),()> {
    takes_ref(returns_result()?);
    Ok(())
}
8 |     takes_ref(returns_result()?);
  |               ^^^^^^^^^^^^^^^^^
  |               |
  |               expected &Foo, found struct `Foo`
  |               help: try wrapping with a success variant: `Ok(returns_result()?)`
  |
  = note: expected type `&Foo`
             found type `Foo`

@estebank
Copy link
Contributor

@zackmdavis I see what's happening, we're only checking wether the error came from a ? desugaring, disregarding the types involved. It should be possible to check that information as well, even if the suggestion is only provided when it's a Result where everything but the error type matches. (I think it's ok if the supplied error cannot be converted to the expected error, as this suggestion exposes newcomers to a non-obvious construct at least.)

@zackmdavis
Copy link
Member

even if the suggestion is only provided when it's a Result

Clippy has helper functions to detect this that we might want to uplift ...

@zackmdavis
Copy link
Member

(But for now I'm just going to remove the suggestion.)

zackmdavis added a commit to zackmdavis/rust that referenced this issue Oct 27, 2018
This suggestion was introduced in rust-lang#51938 / 6cc78bf (while
introducing different language for type errors coming from `?` rather
than a `match`), but it has a lot of false-positives (as repeatedly
reported in Issues rust-lang#52537, rust-lang#52598, rust-lang#54578, rust-lang#55336), and incorrect
suggestions carry more badness than marginal good suggestions do
goodness. Just get rid of it (unless and until someone figures out how
to do it correctly).

Resolves rust-lang#52537, resolves rust-lang#54578.
pietroalbini added a commit to pietroalbini/rust that referenced this issue Oct 29, 2018
…ng_suggestion, r=estebank

back out bogus `Ok`-wrapping suggestion on `?` arm type mismatch

This suggestion was introduced in rust-lang#51938 / 6cc78bf (while introducing different language for type errors coming from `?` rather than a `match`), but it has a lot of false-positives, and incorrect suggestions carry more badness than marginal good suggestions do goodness. I regret not doing this earlier. 😞

Resolves rust-lang#52537, resolves rust-lang#54578.

r? @estebank
pietroalbini pushed a commit to alexcrichton/rust that referenced this issue Oct 29, 2018
This suggestion was introduced in rust-lang#51938 / 6cc78bf (while
introducing different language for type errors coming from `?` rather
than a `match`), but it has a lot of false-positives (as repeatedly
reported in Issues rust-lang#52537, rust-lang#52598, rust-lang#54578, rust-lang#55336), and incorrect
suggestions carry more badness than marginal good suggestions do
goodness. Just get rid of it (unless and until someone figures out how
to do it correctly).

Resolves rust-lang#52537, resolves rust-lang#54578.
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-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants