about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-08-05 22:59:24 -0400
committerNiko Matsakis <niko@alum.mit.edu>2014-08-07 07:23:59 -0400
commitfcab98038c3b466d9ecd00b0f27e9c748e7acbde (patch)
tree345deba110cec778935c4d2fa1b7f9150c90f7c3 /src/libsyntax/parse
parent1a53c001170f8084ce850498d5e8f22b5e7da72c (diff)
downloadrust-fcab98038c3b466d9ecd00b0f27e9c748e7acbde.tar.gz
rust-fcab98038c3b466d9ecd00b0f27e9c748e7acbde.zip
Temporary bootstrapping hack: introduce syntax for r egion bounds like `'b:'a`,
meaning `'b outlives 'a`. Syntax currently does nothing but is needed for full
fix to #5763. To use this syntax, the issue_5763_bootstrap feature guard is
required.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs91
1 files changed, 62 insertions, 29 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index c9fba355c4d..7ea000d3aac 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1053,10 +1053,10 @@ impl<'a> Parser<'a> {
 
         */
 
-        let lifetimes = if self.eat(&token::LT) {
-            let lifetimes = self.parse_lifetimes();
+        let lifetime_defs = if self.eat(&token::LT) {
+            let lifetime_defs = self.parse_lifetime_defs();
             self.expect_gt();
-            lifetimes
+            lifetime_defs
         } else {
             Vec::new()
         };
@@ -1082,7 +1082,7 @@ impl<'a> Parser<'a> {
             onceness: Once,
             bounds: bounds,
             decl: decl,
-            lifetimes: lifetimes,
+            lifetimes: lifetime_defs,
         })
     }
 
@@ -1096,7 +1096,7 @@ impl<'a> Parser<'a> {
           |        |      |    |      |      Return type
           |        |      |    |  Closure bounds
           |        |      |  Argument types
-          |        |    Lifetimes
+          |        |    Lifetime defs
           |     Once-ness (a.k.a., affine)
         Function Style
 
@@ -1105,11 +1105,11 @@ impl<'a> Parser<'a> {
         let fn_style = self.parse_unsafety();
         let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many};
 
-        let lifetimes = if self.eat(&token::LT) {
-            let lifetimes = self.parse_lifetimes();
+        let lifetime_defs = if self.eat(&token::LT) {
+            let lifetime_defs = self.parse_lifetime_defs();
             self.expect_gt();
 
-            lifetimes
+            lifetime_defs
         } else {
             Vec::new()
         };
@@ -1164,7 +1164,7 @@ impl<'a> Parser<'a> {
                 onceness: onceness,
                 bounds: bounds,
                 decl: decl,
-                lifetimes: lifetimes,
+                lifetimes: lifetime_defs,
             }, region)
         }
     }
@@ -1179,7 +1179,7 @@ impl<'a> Parser<'a> {
 
     /// Parse a function type (following the 'fn')
     pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
-                            -> (P<FnDecl>, Vec<ast::Lifetime>) {
+                            -> (P<FnDecl>, Vec<ast::LifetimeDef>) {
         /*
 
         (fn) <'lt> (S) -> T
@@ -1187,13 +1187,13 @@ impl<'a> Parser<'a> {
                |    |     |
                |    |   Return type
                |  Argument types
-           Lifetimes
+           Lifetime_defs
 
         */
-        let lifetimes = if self.eat(&token::LT) {
-            let lifetimes = self.parse_lifetimes();
+        let lifetime_defs = if self.eat(&token::LT) {
+            let lifetime_defs = self.parse_lifetime_defs();
             self.expect_gt();
-            lifetimes
+            lifetime_defs
         } else {
             Vec::new()
         };
@@ -1206,7 +1206,7 @@ impl<'a> Parser<'a> {
             cf: ret_style,
             variadic: variadic
         });
-        (decl, lifetimes)
+        (decl, lifetime_defs)
     }
 
     /// Parse the methods in a trait declaration
@@ -1770,31 +1770,34 @@ impl<'a> Parser<'a> {
         }
     }
 
-    // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
-    // actually, it matches the empty one too, but putting that in there
-    // messes up the grammar....
-    pub fn parse_lifetimes(&mut self) -> Vec<ast::Lifetime> {
+    pub fn parse_lifetime_defs(&mut self) -> Vec<ast::LifetimeDef> {
         /*!
-         *
-         * Parses zero or more comma separated lifetimes.
-         * Expects each lifetime to be followed by either
-         * a comma or `>`.  Used when parsing type parameter
-         * lists, where we expect something like `<'a, 'b, T>`.
+         * Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]`
+         * where `lifetime_def  = lifetime [':' lifetimes]`
          */
 
         let mut res = Vec::new();
         loop {
             match self.token {
                 token::LIFETIME(_) => {
-                    res.push(self.parse_lifetime());
+                    let lifetime = self.parse_lifetime();
+                    let bounds =
+                        if self.eat(&token::COLON) {
+                            self.parse_lifetimes(token::BINOP(token::PLUS))
+                        } else {
+                            Vec::new()
+                        };
+                    res.push(ast::LifetimeDef { lifetime: lifetime,
+                                                bounds: bounds });
                 }
+
                 _ => {
                     return res;
                 }
             }
 
             match self.token {
-                token::COMMA => { self.bump();}
+                token::COMMA => { self.bump(); }
                 token::GT => { return res; }
                 token::BINOP(token::SHR) => { return res; }
                 _ => {
@@ -1807,6 +1810,36 @@ impl<'a> Parser<'a> {
         }
     }
 
+    // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
+    // actually, it matches the empty one too, but putting that in there
+    // messes up the grammar....
+    pub fn parse_lifetimes(&mut self, sep: token::Token) -> Vec<ast::Lifetime> {
+        /*!
+         * Parses zero or more comma separated lifetimes.
+         * Expects each lifetime to be followed by either
+         * a comma or `>`.  Used when parsing type parameter
+         * lists, where we expect something like `<'a, 'b, T>`.
+         */
+
+        let mut res = Vec::new();
+        loop {
+            match self.token {
+                token::LIFETIME(_) => {
+                    res.push(self.parse_lifetime());
+                }
+                _ => {
+                    return res;
+                }
+            }
+
+            if self.token != sep {
+                return res;
+            }
+
+            self.bump();
+        }
+    }
+
     pub fn token_is_mutability(tok: &token::Token) -> bool {
         token::is_keyword(keywords::Mut, tok) ||
         token::is_keyword(keywords::Const, tok)
@@ -3664,7 +3697,7 @@ impl<'a> Parser<'a> {
     /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
     pub fn parse_generics(&mut self) -> ast::Generics {
         if self.eat(&token::LT) {
-            let lifetimes = self.parse_lifetimes();
+            let lifetime_defs = self.parse_lifetime_defs();
             let mut seen_default = false;
             let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| {
                 p.forbid_lifetime();
@@ -3678,14 +3711,14 @@ impl<'a> Parser<'a> {
                 }
                 ty_param
             });
-            ast::Generics { lifetimes: lifetimes, ty_params: ty_params }
+            ast::Generics { lifetimes: lifetime_defs, ty_params: ty_params }
         } else {
             ast_util::empty_generics()
         }
     }
 
     fn parse_generic_values_after_lt(&mut self) -> (Vec<ast::Lifetime>, Vec<P<Ty>> ) {
-        let lifetimes = self.parse_lifetimes();
+        let lifetimes = self.parse_lifetimes(token::COMMA);
         let result = self.parse_seq_to_gt(
             Some(token::COMMA),
             |p| {