-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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 coercion of Result
using ?
#106583
Conversation
r? @oli-obk (rustbot has picked a reviewer for you, use r? to override) |
.must_apply_modulo_regions() | ||
{ | ||
err.multipart_suggestion( | ||
"you can rely on the implicit conversion that `?` does to transform the error type", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This phrasing feels a bit roundabout... Also, it should really mention that it's doing control flow, since it's not equivalent to .map_err(Into::into)
, which is what this currently reads like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In return position, it's fine to ignore the fact that this is doing control flow, but even if you hadn't applied my suggestion to extend this to all type mismatch suggestions, it's still happening on any block-tail usage of CoerceMany
, which is not always in the return of an fn.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before the requested change, this was checking the obligation cause code explicitly for the cases where this was happening in return
statements and function tails exclusively :-/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where this was happening in return statements and function tails exclusively :-/
Wait, like I said in:
but even if you hadn't applied my suggestion to extend this to all type mismatch suggestions, it's still happening on any block-tail usage of CoerceMany, which is not always in the return of an fn.
This concern still applies to the old code too.
The original commit bb0f8c1098d7191f1c27ce7ee3ee2bafcf99c6ca used the BlockTailExpression
obligation to gate this suggestion, which isn't equivalent to checking if something is in the function tail exclusively. For example:
struct A;
struct B;
impl From<A> for B {
fn from(_: A) -> Self { B }
}
fn foo() -> Result<(), B> {
let y = Err(A);
let z: Result<(), B> = { y };
Ok(())
}
Gives:
help: you can rely on the implicit conversion that `?` does to transform the error type
|
10 | let z: Result<(), B> = { Ok(y?) };
| +++ ++
Since the expression is in the tail of that block expression. This happens on that earlier commit, which still really deserves either fixing (making the suggestion only apply in tail position), or mentioning control flow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the wording, do you have one in mind? I'm somewhat relying on prior understanding of what ?
does, but because the suggestion is always for returned values, it should never affect behavior, regardless of understanding.
.must_apply_modulo_regions() | ||
{ | ||
err.multipart_suggestion( | ||
"you can rely on the implicit conversion that `?` does to transform the error type", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe something like
"you can rely on the implicit conversion that `?` does to transform the error type", | |
"use `?` then wrap the value in `Ok` to return an `Err` result and coerce the `Ok` variant into the right `Result` type", |
?? no idea if that's clearer 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too happy with that explanation because I feel it is too much. I want us to take into consideration the context we are in: we have some Result<_, A>
and we expected Result<_, B>
where B: Into<A>
. Because of that I want to focus on "writing the following you can turn the value you have into the expected type". Maybe "you can use ?
to coerce and return an appropriate Err
, and wrap the resulting value in Ok
so the expression remains of type Result
"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with that wording minus the "you can". I personally prefer suggestions worded in the imperative mood, but r=me either way.
600daa7
to
62aff3b
Compare
@bors r=compiler-errors |
…r=compiler-errors Suggest coercion of `Result` using `?` Fix rust-lang#47560.
…r=compiler-errors Suggest coercion of `Result` using `?` Fix rust-lang#47560.
Rollup of 9 pull requests Successful merges: - rust-lang#105552 (Add help message about function pointers) - rust-lang#106583 (Suggest coercion of `Result` using `?`) - rust-lang#106767 (Allow setting CFG_DISABLE_UNSTABLE_FEATURES to 0) - rust-lang#106823 (Allow fmt::Arguments::as_str() to return more Some(_).) - rust-lang#107166 (rustc_metadata: Support non-`Option` nullable values in metadata tables) - rust-lang#107213 (Add suggestion to remove if in let..else block) - rust-lang#107223 (`sub_ptr()` is equivalent to `usize::try_from().unwrap_unchecked()`, not `usize::from().unwrap_unchecked()`) - rust-lang#107227 (`new_outside_solver` -> `evaluate_root_goal`) - rust-lang#107232 (rustdoc: simplify settings popover DOM, CSS, JS) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
| | ||
LL | let _: Result<(), B> = { | ||
| ____________________________^ | ||
LL | | Err(A); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case has a mistake - you meant to test Err(A)
not Err(A);
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works as a negative test :)
I don't recall now if I intended for that to be the case, which is likely not.
Fix #47560.