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

Point out missing if conditional #43854

Merged
merged 3 commits into from
Aug 22, 2017
Merged

Point out missing if conditional #43854

merged 3 commits into from
Aug 22, 2017

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Aug 13, 2017

On a case where an else conditional is missing, point this out
instead of the token immediately after the (incorrect) else block:

error: missing condition for `if` statemementt push fork -f

  --> $DIR/issue-13483.rs:16:5
   |
13 |    } else if {
   |             ^ expected if condition here

instead of

error: expected `{`, found `else`
  --> ../../src/test/ui/issue-13483.rs:14:7
   |
14 |     } else {
   |       ^^^^

Fix #13483.

@rust-highfive
Copy link
Collaborator

r? @nikomatsakis

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

@Mark-Simulacrum
Copy link
Member

I feel like it'd be better if the span for the missing conditional pointed at one character, probably either the { or after the if instead of the whole block. Might just be me though. Also, it'd be good to have a test for the if { return; } case (i.e., with no else block).

@carols10cents carols10cents added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 14, 2017
@estebank estebank force-pushed the missing-cond branch 2 times, most recently from f543e5b to 45bffde Compare August 15, 2017 00:12
error: missing conditional
--> $DIR/issue-13483.rs:13:15
|
13 | } else if { //ERROR: MISSING CONDITIONAL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @Mark-Simulacrum that the span here is not ideal -- also, the term "conditional" doesn't quite feel right. I feel like I would prefer:

error: missing condition for `if` statemement
  --> $DIR/issue-13483.rs:20:15
   |
20 |       } else if {
   |               ^ expected if condition here
21 | |     };

@estebank estebank force-pushed the missing-cond branch 2 times, most recently from 59ff234 to 005dcc9 Compare August 17, 2017 05:43
err.cancel();
let sp = lo.next_point();
let mut err = self.diagnostic()
.struct_span_err(ps, "missing condition for `if` statemement");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean sp here?

[00:04:00] error[E0425]: cannot find value `ps` in this scope
[00:04:00]     --> /checkout/src/libsyntax/parse/parser.rs:2977:38
[00:04:00]      |
[00:04:00] 2977 |                     .struct_span_err(ps, "missing condition for `if` statemement");
[00:04:00]      |                                      ^^ not found in this scope
[00:04:00] 
[00:04:07] error: aborting due to previous error
[00:04:07] 
[00:04:07] error: Could not compile `syntax`.

On a case where an else conditional is missing, point this out
instead of the token immediately after the (incorrect) else block:

```
error: missing condition for `if` statemementt push fork -f

  --> $DIR/issue-13483.rs:16:5
   |
13 |    } else if {
   |             ^ expected if condition here
```

instead of

```
error: expected `{`, found `else`
  --> ../../src/test/ui/issue-13483.rs:14:7
   |
14 |     } else {
   |       ^^^^
```
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.

What do you think?

if self.check_keyword(keywords::Let) {
return self.parse_if_let_expr(attrs);
}
let lo = self.prev_span;
let cond = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL, None)?;
let thn = self.parse_block()?;
let thn = self.parse_block().map_err(|mut err| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mildly worried that this error might trigger on cases where it shouldn't -- this will trigger whenever parsing the block failed, right? Even if there was a condition, potentially?

For example, something like this if true else { ... } will signal that there is a missing condition, which isn't quite right, no?

Maybe we should check whether we see the keyword else, instead of invoking parse_block()?

Copy link
Contributor Author

@estebank estebank Aug 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed, but that won't catch the following case:

fn foo() {
     if true {
     } else if {
     }
 }


fn foo() {
if true {
} else if { //ERROR: MISSING CONDITIONAL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, so I guess my change means we no longer catch this case? That does seem unfortunate -- I hadn't quite thought that far ahead. :) We could handle this by expanding the set of things we check for, I guess -- e.g., including ; and } and a few other such tokens. Not sure if that's worth it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By then we wouldn't catch, for example:

fn foo() {
    if true {
    } else if {
    }
    bar();
 }

Alternatively, I could expand this PR to check if cond.node is Block and the last stmts is StmtKind::Expr(_) or StmtKind::Semi(Expr{node: ExprKind::Ret(Some(_)),..}). If false, present the proposed suggestion.

After this, if we don't check that the next token is {, the output for:

fn main() {
    if true {
    } else if {
        true
    }
}

would be the same as it is now, which is in my eyes reasonable:

error: expected `{`, found `}`
 --> file.rs:7:1
  |
7 | }
  | ^

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikomatsakis changed. It doesn't catch the following case, but I feel it is an acceptable tradeoff, given the alternatives:

if true {
} else if {
    true
}

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.

nice :)

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Aug 21, 2017

📌 Commit f063233 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Aug 22, 2017

⌛ Testing commit f063233 with merge 6722996...

bors added a commit that referenced this pull request Aug 22, 2017
Point out missing if conditional

On a case where an else conditional is missing, point this out
instead of the token immediately after the (incorrect) else block:

```
error: missing condition for `if` statemementt push fork -f

  --> $DIR/issue-13483.rs:16:5
   |
13 |    } else if {
   |             ^ expected if condition here
```

instead of

```
error: expected `{`, found `else`
  --> ../../src/test/ui/issue-13483.rs:14:7
   |
14 |     } else {
   |       ^^^^
```

Fix #13483.
@bors
Copy link
Contributor

bors commented Aug 22, 2017

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

@bors bors merged commit f063233 into rust-lang:master Aug 22, 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