about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/method/suggest.rs2
-rw-r--r--src/libsyntax/parse/parser.rs33
-rw-r--r--src/libsyntax/parse/token.rs8
-rw-r--r--src/test/compile-fail/issue-20616-1.rs46
-rw-r--r--src/test/compile-fail/issue-20616-2.rs46
-rw-r--r--src/test/compile-fail/issue-20616-3.rs46
-rw-r--r--src/test/compile-fail/issue-20616-4.rs46
-rw-r--r--src/test/compile-fail/issue-20616-5.rs46
-rw-r--r--src/test/compile-fail/issue-20616-6.rs46
-rw-r--r--src/test/compile-fail/issue-20616-7.rs46
-rw-r--r--src/test/compile-fail/issue-20616-8.rs46
-rw-r--r--src/test/compile-fail/issue-20616-9.rs46
-rw-r--r--src/test/run-pass/issue-20616.rs52
13 files changed, 507 insertions, 2 deletions
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index a4175fe8325..17658675ee2 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -364,7 +364,7 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
 }
 
 pub struct AllTraits<'a> {
-    borrow: cell::Ref<'a Option<AllTraitsVec>>,
+    borrow: cell::Ref<'a, Option<AllTraitsVec>>,
     idx: usize
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 68006a8979a..47ea8d556fa 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -902,7 +902,9 @@ impl<'a> Parser<'a> {
     pub fn bump(&mut self) -> PResult<()> {
         self.last_span = self.span;
         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
-        self.last_token = if self.token.is_ident() || self.token.is_path() {
+        self.last_token = if self.token.is_ident() ||
+                          self.token.is_path() ||
+                          self.token == token::Comma {
             Some(Box::new(self.token.clone()))
         } else {
             None
@@ -3807,8 +3809,37 @@ impl<'a> Parser<'a> {
     fn parse_generic_values_after_lt(&mut self) -> PResult<(Vec<ast::Lifetime>,
                                                             Vec<P<Ty>>,
                                                             Vec<P<TypeBinding>>)> {
+        let span_lo = self.span.lo;
         let lifetimes = try!(self.parse_lifetimes(token::Comma));
 
+        let missing_comma = !lifetimes.is_empty() &&
+                            !self.token.is_like_gt() &&
+                            self.last_token
+                                .as_ref().map_or(true,
+                                                 |x| &**x != &token::Comma);
+
+        if missing_comma {
+
+            let msg = format!("expected `,` or `>` after lifetime \
+                              name, found `{}`",
+                              self.this_token_to_string());
+            self.span_err(self.span, &msg);
+
+            let span_hi = self.span.hi;
+            let span_hi = if self.parse_ty_nopanic().is_ok() {
+                self.span.hi
+            } else {
+                span_hi
+            };
+
+            let msg = format!("did you mean a single argument type &'a Type, \
+                              or did you mean the comma-separated arguments \
+                              'a, Type?");
+            self.span_note(mk_sp(span_lo, span_hi), &msg);
+
+            self.abort_if_errors()
+        }
+
         // First parse types.
         let (types, returned) = try!(self.parse_seq_to_gt_or_return(
             Some(token::Comma),
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 538aa384327..e33b1391a10 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -173,6 +173,14 @@ pub enum Token {
 }
 
 impl Token {
+    /// Returns `true` if the token starts with '>'.
+    pub fn is_like_gt(&self) -> bool {
+        match *self {
+            BinOp(Shr) | BinOpEq(Shr) | Gt | Ge => true,
+            _ => false,
+        }
+    }
+
     /// Returns `true` if the token can appear at the start of an expression.
     pub fn can_begin_expr(&self) -> bool {
         match *self {
diff --git a/src/test/compile-fail/issue-20616-1.rs b/src/test/compile-fail/issue-20616-1.rs
new file mode 100644
index 00000000000..5b4f9942d28
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-1.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+type Type_1<'a T> = &'a T; //~ error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-2.rs b/src/test/compile-fail/issue-20616-2.rs
new file mode 100644
index 00000000000..65305ff3ac8
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-2.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+type Type_2 = Type_1_<'static ()>; //~ error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-3.rs b/src/test/compile-fail/issue-20616-3.rs
new file mode 100644
index 00000000000..101f81019d9
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-3.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+type Type_3<T> = Box<T,,>; //~ error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-4.rs b/src/test/compile-fail/issue-20616-4.rs
new file mode 100644
index 00000000000..6450e9ed68c
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-4.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+type Type_4<T> = Type_1_<'static,, T>; //~ error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-5.rs b/src/test/compile-fail/issue-20616-5.rs
new file mode 100644
index 00000000000..d1840427ad8
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-5.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+type Type_5<'a> = Type_1_<'a, (),,>; //~ error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-6.rs b/src/test/compile-fail/issue-20616-6.rs
new file mode 100644
index 00000000000..b0b5bc653f6
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-6.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+type Type_6 = Type_5_<'a,,>; //~ error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-7.rs b/src/test/compile-fail/issue-20616-7.rs
new file mode 100644
index 00000000000..0958f8b4ed2
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-7.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+type Type_7 = Box<(),,>; //~ error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-8.rs b/src/test/compile-fail/issue-20616-8.rs
new file mode 100644
index 00000000000..07ced7a97ba
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-8.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+type Type_8<'a,,> = &'a (); //~ error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/compile-fail/issue-20616-9.rs b/src/test/compile-fail/issue-20616-9.rs
new file mode 100644
index 00000000000..7847dea69ef
--- /dev/null
+++ b/src/test/compile-fail/issue-20616-9.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// We need all these 9 issue-20616-N.rs files
+// becase we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+type Type_9<T,,> = Box<T>; //~ error: expected ident, found `,`
diff --git a/src/test/run-pass/issue-20616.rs b/src/test/run-pass/issue-20616.rs
new file mode 100644
index 00000000000..e6b256f7e84
--- /dev/null
+++ b/src/test/run-pass/issue-20616.rs
@@ -0,0 +1,52 @@
+// Copyright 2015 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.
+
+type MyType<'a, T> = &'a T;
+
+// combine lifetime bounds and type arguments in usual way
+type TypeA<'a> = MyType<'a, ()>;
+
+// ensure token `>>` works fine
+type TypeB = Box<TypeA<'static>>;
+type TypeB_ = Box<TypeA<'static,>>;
+
+// trailing comma when combine lifetime bounds and type arguments
+type TypeC<'a> = MyType<'a, (),>;
+
+// normal lifetime bounds
+type TypeD = TypeA<'static>;
+
+// trailing comma on lifetime bounds
+type TypeE = TypeA<'static,>;
+
+// normal type arugment
+type TypeF<T> = Box<T>;
+
+// type argument with trailing comma
+type TypeG<T> = Box<T,>;
+
+// trailing comma on liftime defs
+type TypeH<'a,> = &'a ();
+
+// trailing comma on type argument
+type TypeI<T,> = T;
+
+static STATIC: () = ();
+
+fn main() {
+
+    // ensure token `>=` works fine
+    let _: TypeA<'static>= &STATIC;
+    let _: TypeA<'static,>= &STATIC;
+
+    // ensure token `>>=` works fine
+    let _: Box<TypeA<'static>>= Box::new(&STATIC);
+    let _: Box<TypeA<'static,>>= Box::new(&STATIC);
+}