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

Wrong compiler error for assignment in if conditonal #17283

Closed
anshin opened this issue Sep 15, 2014 · 6 comments
Closed

Wrong compiler error for assignment in if conditonal #17283

anshin opened this issue Sep 15, 2014 · 6 comments

Comments

@anshin
Copy link

anshin commented Sep 15, 2014

I'm running a recent nightly (rustc 0.12.0-pre-nightly (0d3bd7720 2014-08-27 21:31:13 +0000)) on x86_64 GNU/Linux. I get this error:

assign.rs:6:18: 6:19 error: expected `:`, found `!`
assign.rs:6             print!("{}", i);
                             ^

with the following program:

fn main() {
    let n = 11u;

    for mut i in range(1u, 10) {
        if i = n {
            print!("{}", i);
        }
    }
}

I don't know whether assignments within if conditions are supposed to be allowed, but the compiler should probably recognize that case and report something more useful. I also have no idea what it wants with the colon.

@ftxqxd
Copy link
Contributor

ftxqxd commented Sep 15, 2014

Assignments in if conditions are not allowed, as the condition has to be a bool but assignments always return (). They are supposed to be allowed syntactically, though. Here you’re seeing the result of an ambiguity in the parser—when the parser reads i = n { ... }, it parses it as an assignment to a struct initialiser:

if i = (n {
    ...
})

instead of an assignment to a variable:

if i = (n) {
    ...
}

(Note that that latter example can be used to force the parser to parse it as expected.) I was under the impression that #14803 was supposed to fix this, making the parser resolve it as the latter instead of the former.

@CameronNemo
Copy link

One workaround to get the effect is this:

if { i = n; i } {
    print!("{}", i);
}

@bkoropoff
Copy link
Contributor

Taking a look at this one

@bkoropoff
Copy link
Contributor

It looks like propagating the struct literal restriction through to the RHS expression of an assignment yields a much better error message:

Code

fn main() {
    let x = 1u;
    if x = x {
        println!("{}", x);
    }
}

Before

test.rs:4:16: 4:17 error: expected `:`, found `!`
test.rs:4         println!("{}", x);
                         ^

After

test.rs:3:8: 3:13 error: mismatched types: expected `bool`, found `()` (expected bool, found ())
test.rs:3     if x = x {
                 ^~~~~

I'll see about getting a PR out for this.

@brson
Copy link
Contributor

brson commented Sep 16, 2014

cc @nick29581

bkoropoff added a commit to bkoropoff/rust that referenced this issue Sep 17, 2014
This prevents confusing errors when accidentally using an assignment
in an `if` expression.  For example:

```rust
fn main() {
    let x = 1u;
    if x = x {
        println!("{}", x);
    }
}
```

Previously, this yielded:

```
test.rs:4:16: 4:17 error: expected `:`, found `!`
test.rs:4         println!("{}", x);
                         ^
```

With this change, it now yields:

```
test.rs:3:8: 3:13 error: mismatched types: expected `bool`, found `()` (expected bool, found ())
test.rs:3     if x = x {
                 ^~~~~
```

Closes issue rust-lang#17283
bkoropoff added a commit to bkoropoff/rust that referenced this issue Sep 17, 2014
@steveklabnik
Copy link
Member

This now gives

hello.rs:5:28: 5:33 error: mismatched types:
 expected `bool`,
    found `()`
(expected bool,
    found ()) [E0308]
hello.rs:5                         if i = n {
                                      ^~~~~

which is much, much better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants