about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-01-08 07:11:47 +0000
committerbors <bors@rust-lang.org>2018-01-08 07:11:47 +0000
commit1b193de98af5b8c6e2b50908ea64323b9095a1a4 (patch)
treeb083dc1b0bb9d6314f5892129a0efe5200bfde56 /src/libsyntax/parse
parent795594cd8ce3272bd6b1ebf7e1b7f33a5a86e3ac (diff)
parent6aafdc3781c7adca6270b8e712152bed160b6071 (diff)
downloadrust-1b193de98af5b8c6e2b50908ea64323b9095a1a4.tar.gz
rust-1b193de98af5b8c6e2b50908ea64323b9095a1a4.zip
Auto merge of #47232 - keatinge:master, r=petrochenkov
Add help message for incorrect pattern syntax

When I was getting started with rust I often made the mistake of using `||` instead of `|` to match multiple patterns and spent a long time staring at my code wondering what was wrong.

for example:

```
fn main() {
    let x = 1;

    match x {
        1 || 2 => println!("1 or 2"),
        _ => println!("Something else"),
    }
}

```

If you compile this with current rustc you will see

```
error: expected one of `...`, `..=`, `..`, `=>`, `if`, or `|`, found `||`
 --> test.rs:5:11
  |
5 |         1 || 2 => println!("1 or 2"),
  |          -^^ unexpected token
  |          |
  |          expected one of `...`, `..=`, `..`, `=>`, `if`, or `|` here

error: aborting due to previous error
```

With my proposed change it will show:
```
error: unexpected token `||` after pattern
 --> test.rs:5:11
  |
5 |         1 || 2 => println!("1 or 2"),
  |           ^^
  |
  = help: did you mean to use `|` to specify multiple patterns instead?

error: aborting due to previous error
```
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index e7c648d5e37..b61c39d589b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3431,8 +3431,20 @@ impl<'a> Parser<'a> {
         let mut pats = Vec::new();
         loop {
             pats.push(self.parse_pat()?);
-            if self.check(&token::BinOp(token::Or)) { self.bump();}
-            else { return Ok(pats); }
+
+            if self.token == token::OrOr {
+                let mut err = self.struct_span_err(self.span,
+                                                   "unexpected token `||` after pattern");
+                err.span_suggestion(self.span,
+                                    "use a single `|` to specify multiple patterns",
+                                    "|".to_owned());
+                err.emit();
+                self.bump();
+            } else if self.check(&token::BinOp(token::Or)) {
+                self.bump();
+            } else {
+                return Ok(pats);
+            }
         };
     }