-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Point at coercion reason for if
expressions without else clause if caused by return type
#58981
Conversation
r? @pnkfelix (rust_highfive has picked a reviewer for you, use r? to override) |
r? @davidtwco |
if
expressions without else clause if caused by return 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.
I'm unsure whether this was just me getting confused, but here are some thoughts.
| | ||
= note: expected type `()` | ||
found type `usize` | ||
= note: `if` expressions without `else` must evaluate to `()` |
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 found this error message was still quite confusing initially. It's clear to me that the function will return ()
and not usize
when the if
condition isn't true
and that this is the error, but perhaps outwith the if may be missing an else clause
part of the error, this isn't well articulated. I think there are two reasons for this:
-
It appears to me that we should expect a
usize
(due to the return type) and have found a()
(due to the missingelse
block). Currently the error suggests the reverse, which is correct only when we consider what would be required to have theif
without anelse
be valid. -
While the note is factually correct, I initially interpreted it as a suggestion rather than a statement of fact - that if I were to change the
if
block to evaluate to()
then this would fix the error, but that isn't the case. Rewording this to something like`if` expressions can only omit an `else` block when they are expected to evaluate to `()`
may help clear that up.
I think something along these lines could be more helpful for this particular test:
error[E0317]: if may be missing an else clause
--> $DIR/if-without-else-as-fn-expr.rs:2:5
|
LL | fn foo(bar: usize) -> usize {
| ----- expected `usize` because of this return type
LL | / if bar % 5 == 0 {
LL | | return 3;
LL | | }
| |_____^ expected usize, found ()
|
= note: expected type `usize`
found type `()`
= note: this function evaluates to `()` when the `if` condition is not `true`...
= note: ...consider adding a `else` block that evaluates to `usize`.
More generally, I think when an if
expression is expected to evaluate to ()
then the note as in this PR currently is excellent, but if it doesn't match, we should instead explain that a implicit else { }
block is returning the wrong type, and an else
block should be added.
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.
@davidtwco let me know what you think of the new output. It's not exactly the same you requested, as I was trying to avoid incorrect diagnostics in some cases where the coercion is failing from within the arm, not outside.
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.
Thanks, that's perfect.
``` error[E0317]: if may be missing an else clause --> $DIR/if-without-else-as-fn-expr.rs:2:5 | LL | fn foo(bar: usize) -> usize { | ----- found `usize` because of this return type LL | / if bar % 5 == 0 { LL | | return 3; LL | | } | |_____^ expected (), found usize | = note: expected type `()` found type `usize` = note: `if` expressions without `else` must evaluate to `()` ```
@bors r+ |
📌 Commit dcaec88 has been approved by |
Point at coercion reason for `if` expressions without else clause if caused by return type ``` error[E0317]: if may be missing an else clause --> $DIR/if-without-else-as-fn-expr.rs:2:5 | LL | fn foo(bar: usize) -> usize { | ----- found `usize` because of this return type LL | / if bar % 5 == 0 { LL | | return 3; LL | | } | |_____^ expected (), found usize | = note: expected type `()` found type `usize` = note: `if` expressions without `else` must evaluate to `()` ``` Fix #25228.
☀️ Test successful - checks-travis, status-appveyor |
Fix #25228.