about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2017-09-10 14:03:22 +0200
committerGitHub <noreply@github.com>2017-09-10 14:03:22 +0200
commit62659ebf6650fd72c7cb242aa19915eb2dfc866d (patch)
tree3d08d194b80b7ec439c7c8760c50d1aa9d917286
parent078e1c546cbc5d37479ccd5f9023d6fffdaa4e35 (diff)
parent258ec30116b1a80f4a9fb4b14aa22dd88eb8bf31 (diff)
Rollup merge of #44332 - tirr-c:issue-44021, r=petrochenkov
Expect pipe symbol after closure parameter list

Fixes #44021.

---

Originally, the parser just called `bump` to discard following token after parsing closure parameter list, because it assumes `|` is following. However, the following code breaks the assumption:

```rust
struct MyStruct;
impl MyStruct {
   fn f() {|x, y}
}
```

Here, the parameter list is `x, y` and the following token is `}`. The parser discards `}`, and then we have a curly bracket mismatch.

Indeed, this code has a syntax error. On current nightly, the compiler emits an syntax error, but with incorrect message and span, followed by an ICE.

```
error: expected expression, found `}`
 --> 44021.rs:4:1
  |
4 | }
  | ^

error: internal compiler error: unexpected panic
```

Even worse, on current stable(1.20.0), the compiler falls into an infinite loop.

This pull request fixes this problem. Now the compiler emits correct error message and span, and does not ICE.

```
error: expected one of `:`, `@`, or `|`, found `}`
 --> 44021.rs:3:20
  |
3 |     fn foo() {|x, y}
  |                    ^ expected one of `:`, `@`, or `|` here
```
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/test/compile-fail/issue-44021.rs16
2 files changed, 17 insertions, 1 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1f033b25fe4..a52d0488307 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4699,7 +4699,7 @@ impl<'a> Parser<'a> {
                     SeqSep::trailing_allowed(token::Comma),
                     |p| p.parse_fn_block_arg()
                 );
-                self.bump();
+                self.expect(&token::BinOp(token::Or))?;
                 args
             }
         };
diff --git a/src/test/compile-fail/issue-44021.rs b/src/test/compile-fail/issue-44021.rs
new file mode 100644
index 00000000000..b6ec21b94c7
--- /dev/null
+++ b/src/test/compile-fail/issue-44021.rs
@@ -0,0 +1,16 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct MyStruct;
+impl MyStruct {
+    fn f() {|x, y} //~ ERROR expected one of `:`, `@`, or `|`, found `}`
+}
+
+fn main() {}