-
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
Report error for assignment in if
condition
#42649
Conversation
r? @pnkfelix (rust_highfive has picked a reviewer for you, use r? to override) |
The "expected bool, found ()" message was kinda educational - "it's not like assignments are special and can't be used in some contexts, it's just the result has inappropriate type". |
☔ The latest upstream changes (presumably #42644) made this pull request unmergeable. Please resolve the merge conflicts. |
For code like `if x = 3 {}`, output: ``` error[E0308]: mismatched types --> $DIR/issue-17283.rs:25:8 | 25 | if x = x { | ^^^^^ | | | help: did you mean to compare equality? `x == x` | expected bool, found () | = note: expected type `bool` found type `()` ```
@petrochenkov changed |
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.
r=me modulo the nits below -- this is nice
src/librustc_typeck/check/mod.rs
Outdated
let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty); | ||
|
||
match expected { | ||
ExpectIfCondition => (), |
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 makes me mildly nervous. Can you add a call like self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if; expected error elsehwere")
? That way, in case there is some edge condition, compilation will abort and not just succeed.
src/librustc_typeck/check/mod.rs
Outdated
self.check_expr_expect_type(expr, ExpectHasType(expected)) | ||
} | ||
|
||
fn check_expr_expect_type(&self, |
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 we can call this check_expr_meets_expectation_or_error
? I think this zoo of functions is sort of confusing, and the existing naming convention isn't the clearest (for bonus points, we could apply the _or_error
convention elsewhere, e.g. check_expr_has_type_or_error
)
src/librustc_typeck/check/mod.rs
Outdated
@@ -341,6 +344,7 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> { | |||
fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> { | |||
match self.resolve(fcx) { | |||
ExpectHasType(ty) => Some(ty), | |||
ExpectIfCondition => Some(fcx.tcx.types.bool), | |||
_ => None |
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.
Nit: Pre-existing, but I'd rather this match were exhaustive.
src/librustc_typeck/check/demand.rs
Outdated
self.demand_suptype_diag(sp, expected, actual).map(|mut e| e.emit()); | ||
} | ||
|
||
pub fn demand_suptype_diag(&self, sp: Span, |
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.
Nit, formatting: can you move the sp
to the next line so it's easier to see how many arguments this function takes?
@@ -24,25 +24,25 @@ fn main() { | |||
// `x { ... }` should not be interpreted as a struct literal here |
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 isn't really a 'regression test for obscure scenario'. Let's rename the test to assignment-in-if.rs
. While we're at it, can you add some other obscure cases, like this one:
if (if true { x = 4 } else { x = 5 }) { ... }
I don't really care what message it emits, although I think (if I read the code right...) that the expectation will be propagated. I just wanted to test it.
@@ -45,4 +45,9 @@ fn main() { | |||
//~| HELP did you mean to compare equality? | |||
println!("{}", x); | |||
} | |||
if (if true { x = 4 } else { x = 5 }) { | |||
//~^ ERROR mismatched types | |||
//~| HELP did you mean to compare equality? |
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.
Nit: we are not (currently) checking these annotations in ui tests (I want to...), but it doesn't appear that we emit a HELP in this case?
- exhaustive match - rename method to `check_expr_meets_expectation_or_error` - formatting - add `delay_span_bug` - add test
@bors r=nikomatsakis |
📌 Commit da78b4d has been approved by |
Report error for assignment in `if` condition For code like `if x = 3 {}`, output: ``` error[E0308]: mismatched types --> $DIR/issue-17283.rs:25:8 | 25 | if x = x { | ^^^^^ | | | help: did you mean to compare equality? `x == x` | expected bool, found () | = note: expected type `bool` found type `()` ``` Fix #40926.
☀️ Test successful - status-appveyor, status-travis |
For code like
if x = 3 {}
, output:Fix #40926.