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

Report error for assignment in if condition #42649

Merged
merged 2 commits into from
Jun 17, 2017
Merged

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Jun 13, 2017

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.

@rust-highfive
Copy link
Collaborator

r? @pnkfelix

(rust_highfive has picked a reviewer for you, use r? to override)

@petrochenkov
Copy link
Contributor

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".
Maybe adding the "did you mean x == y" suggestion would be enough.

@bors
Copy link
Contributor

bors commented Jun 14, 2017

☔ The latest upstream changes (presumably #42644) made this pull request unmergeable. Please resolve the merge conflicts.

@aidanhs aidanhs added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 15, 2017
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 `()`
```
@estebank
Copy link
Contributor Author

@petrochenkov changed

@estebank
Copy link
Contributor Author

r? @nikomatsakis

Copy link
Contributor

@nikomatsakis nikomatsakis left a 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

let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);

match expected {
ExpectIfCondition => (),
Copy link
Contributor

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.

self.check_expr_expect_type(expr, ExpectHasType(expected))
}

fn check_expr_expect_type(&self,
Copy link
Contributor

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)

@@ -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
Copy link
Contributor

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.

self.demand_suptype_diag(sp, expected, actual).map(|mut e| e.emit());
}

pub fn demand_suptype_diag(&self, sp: Span,
Copy link
Contributor

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
Copy link
Contributor

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?
Copy link
Contributor

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
@estebank
Copy link
Contributor Author

@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented Jun 17, 2017

📌 Commit da78b4d has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Jun 17, 2017

⌛ Testing commit da78b4d with merge 78d8416...

bors added a commit that referenced this pull request Jun 17, 2017
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.
@bors
Copy link
Contributor

bors commented Jun 17, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 78d8416 to master...

@bors bors merged commit da78b4d into rust-lang:master Jun 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants