about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs391
1 files changed, 208 insertions, 183 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 0116518d537..878994369d0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1954,19 +1954,6 @@ impl<'a> Parser<'a> {
             token::BINOP(token::OR) |  token::OROR => {
                 return self.parse_lambda_expr();
             },
-            _ if self.eat_keyword(keywords::Proc) => {
-                let decl = self.parse_proc_decl();
-                let body = self.parse_expr();
-                let fakeblock = P(ast::Block {
-                        view_items: Vec::new(),
-                        stmts: Vec::new(),
-                        expr: Some(body),
-                        id: ast::DUMMY_NODE_ID,
-                        rules: DefaultBlock,
-                        span: body.span,
-                    });
-                return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
-            },
             // FIXME #13626: Should be able to stick in
             // token::SELF_KEYWORD_NAME
             token::IDENT(id @ ast::Ident{
@@ -1978,48 +1965,6 @@ impl<'a> Parser<'a> {
                 ex = ExprPath(path);
                 hi = self.last_span.hi;
             }
-            _ if self.eat_keyword(keywords::If) => {
-                return self.parse_if_expr();
-            },
-            _ if self.eat_keyword(keywords::For) => {
-                return self.parse_for_expr(None);
-            },
-            _ if self.eat_keyword(keywords::While) => {
-                return self.parse_while_expr();
-            },
-            _ if Parser::token_is_lifetime(&self.token) => {
-                let lifetime = self.get_lifetime();
-                self.bump();
-                self.expect(&token::COLON);
-                if self.eat_keyword(keywords::For) {
-                    return self.parse_for_expr(Some(lifetime))
-                } else if self.eat_keyword(keywords::Loop) {
-                    return self.parse_loop_expr(Some(lifetime))
-                } else {
-                    self.fatal("expected `for` or `loop` after a label")
-                }
-            },
-            _ if self.eat_keyword(keywords::Loop) => {
-                return self.parse_loop_expr(None);
-            },
-            _ if self.eat_keyword(keywords::Continue) => {
-                let lo = self.span.lo;
-                let ex = if Parser::token_is_lifetime(&self.token) {
-                    let lifetime = self.get_lifetime();
-                    self.bump();
-                    ExprAgain(Some(lifetime))
-                } else {
-                    ExprAgain(None)
-                };
-                let hi = self.span.hi;
-                return self.mk_expr(lo, hi, ex);
-            },
-            _ if self.eat_keyword(keywords::Match) => {
-                return self.parse_match_expr();
-            },
-            _ if self.eat_keyword(keywords::Unsafe) => {
-                return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
-            },
             token::LBRACKET => {
                 self.bump();
 
@@ -2057,88 +2002,158 @@ impl<'a> Parser<'a> {
                 }
                 hi = self.last_span.hi;
             },
-            _ if self.eat_keyword(keywords::Return) => {
-                // RETURN expression
-                if can_begin_expr(&self.token) {
-                    let e = self.parse_expr();
-                    hi = e.span.hi;
-                    ex = ExprRet(Some(e));
-                } else { ex = ExprRet(None); }
-            },
-            _ if self.eat_keyword(keywords::Break) => {
-                // BREAK expression
+            _ => {
+                if self.eat_keyword(keywords::Proc) {
+                    let decl = self.parse_proc_decl();
+                    let body = self.parse_expr();
+                    let fakeblock = P(ast::Block {
+                            view_items: Vec::new(),
+                            stmts: Vec::new(),
+                            expr: Some(body),
+                            id: ast::DUMMY_NODE_ID,
+                            rules: DefaultBlock,
+                            span: body.span,
+                        });
+                    return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
+                }
+                if self.eat_keyword(keywords::If) {
+                    return self.parse_if_expr();
+                }
+                if self.eat_keyword(keywords::For) {
+                    return self.parse_for_expr(None);
+                }
+                if self.eat_keyword(keywords::While) {
+                    return self.parse_while_expr();
+                }
                 if Parser::token_is_lifetime(&self.token) {
                     let lifetime = self.get_lifetime();
                     self.bump();
-                    ex = ExprBreak(Some(lifetime));
-                } else {
-                    ex = ExprBreak(None);
+                    self.expect(&token::COLON);
+                    if self.eat_keyword(keywords::For) {
+                        return self.parse_for_expr(Some(lifetime))
+                    }
+                    if self.eat_keyword(keywords::Loop) {
+                        return self.parse_loop_expr(Some(lifetime))
+                    }
+                    self.fatal("expected `for` or `loop` after a label")
                 }
-                hi = self.span.hi;
-            },
-            _ if self.token == token::MOD_SEP ||
-                is_ident(&self.token) && !self.is_keyword(keywords::True) &&
-                !self.is_keyword(keywords::False) => {
-                let pth = self.parse_path(LifetimeAndTypesWithColons).path;
-
-                // `!`, as an operator, is prefix, so we know this isn't that
-                if self.token == token::NOT {
-                    // MACRO INVOCATION expression
-                    self.bump();
-
-                    let ket = token::close_delimiter_for(&self.token)
-                        .unwrap_or_else(|| self.fatal("expected open delimiter"));
-                    self.bump();
-
-                    let tts = self.parse_seq_to_end(&ket,
-                                                    seq_sep_none(),
-                                                    |p| p.parse_token_tree());
+                if self.eat_keyword(keywords::Loop) {
+                    return self.parse_loop_expr(None);
+                }
+                if self.eat_keyword(keywords::Continue) {
+                    let lo = self.span.lo;
+                    let ex = if Parser::token_is_lifetime(&self.token) {
+                        let lifetime = self.get_lifetime();
+                        self.bump();
+                        ExprAgain(Some(lifetime))
+                    } else {
+                        ExprAgain(None)
+                    };
                     let hi = self.span.hi;
+                    return self.mk_expr(lo, hi, ex);
+                }
+                if self.eat_keyword(keywords::Match) {
+                    return self.parse_match_expr();
+                }
+                if self.eat_keyword(keywords::Unsafe) {
+                    return self.parse_block_expr(
+                        lo,
+                        UnsafeBlock(ast::UserProvided));
+                }
+                if self.eat_keyword(keywords::Return) {
+                    // RETURN expression
+                    if can_begin_expr(&self.token) {
+                        let e = self.parse_expr();
+                        hi = e.span.hi;
+                        ex = ExprRet(Some(e));
+                    } else {
+                        ex = ExprRet(None);
+                    }
+                } else if self.eat_keyword(keywords::Break) {
+                    // BREAK expression
+                    if Parser::token_is_lifetime(&self.token) {
+                        let lifetime = self.get_lifetime();
+                        self.bump();
+                        ex = ExprBreak(Some(lifetime));
+                    } else {
+                        ex = ExprBreak(None);
+                    }
+                    hi = self.span.hi;
+                } else if self.token == token::MOD_SEP ||
+                        is_ident(&self.token) &&
+                        !self.is_keyword(keywords::True) &&
+                        !self.is_keyword(keywords::False) {
+                    let pth =
+                        self.parse_path(LifetimeAndTypesWithColons).path;
+
+                    // `!`, as an operator, is prefix, so we know this isn't that
+                    if self.token == token::NOT {
+                        // MACRO INVOCATION expression
+                        self.bump();
 
-                    return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
-                } else if self.token == token::LBRACE {
-                    // This is a struct literal, unless we're prohibited from
-                    // parsing struct literals here.
-                    if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
-                        // It's a struct literal.
+                        let ket = token::close_delimiter_for(&self.token)
+                            .unwrap_or_else(|| {
+                                self.fatal("expected open delimiter")
+                            });
                         self.bump();
-                        let mut fields = Vec::new();
-                        let mut base = None;
 
-                        while self.token != token::RBRACE {
-                            if self.eat(&token::DOTDOT) {
-                                base = Some(self.parse_expr());
-                                break;
+                        let tts = self.parse_seq_to_end(
+                            &ket,
+                            seq_sep_none(),
+                            |p| p.parse_token_tree());
+                        let hi = self.span.hi;
+
+                        return self.mk_mac_expr(lo,
+                                                hi,
+                                                MacInvocTT(pth,
+                                                           tts,
+                                                           EMPTY_CTXT));
+                    }
+                    if self.token == token::LBRACE {
+                        // This is a struct literal, unless we're prohibited
+                        // from parsing struct literals here.
+                        if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
+                            // It's a struct literal.
+                            self.bump();
+                            let mut fields = Vec::new();
+                            let mut base = None;
+
+                            while self.token != token::RBRACE {
+                                if self.eat(&token::DOTDOT) {
+                                    base = Some(self.parse_expr());
+                                    break;
+                                }
+
+                                fields.push(self.parse_field());
+                                self.commit_expr(fields.last().unwrap().expr,
+                                                 &[token::COMMA],
+                                                 &[token::RBRACE]);
                             }
 
-                            fields.push(self.parse_field());
-                            self.commit_expr(fields.last().unwrap().expr,
-                                             &[token::COMMA], &[token::RBRACE]);
-                        }
+                            if fields.len() == 0 && base.is_none() {
+                                let last_span = self.last_span;
+                                self.span_err(last_span,
+                                              "structure literal must either \
+                                              have at least one field or use \
+                                              functional structure update \
+                                              syntax");
+                            }
 
-                        if fields.len() == 0 && base.is_none() {
-                            let last_span = self.last_span;
-                            self.span_err(last_span,
-                                          "structure literal must either have at \
-                                          least one field or use functional \
-                                          structure update syntax");
+                            hi = self.span.hi;
+                            self.expect(&token::RBRACE);
+                            ex = ExprStruct(pth, fields, base);
+                            return self.mk_expr(lo, hi, ex);
                         }
-
-                        hi = self.span.hi;
-                        self.expect(&token::RBRACE);
-                        ex = ExprStruct(pth, fields, base);
-                        return self.mk_expr(lo, hi, ex);
                     }
-                }
 
-            hi = pth.span.hi;
-            ex = ExprPath(pth);
-            },
-            _ => {
-                // other literal expression
-                let lit = self.parse_lit();
-                hi = lit.span.hi;
-                ex = ExprLit(box(GC) lit);
+                    hi = pth.span.hi;
+                    ex = ExprPath(pth);
+                } else {
+                    // other literal expression
+                    let lit = self.parse_lit();
+                    hi = lit.span.hi;
+                    ex = ExprLit(box(GC) lit);
+                }
             }
         }
 
@@ -2501,37 +2516,41 @@ impl<'a> Parser<'a> {
               }
             };
           }
-          token::IDENT(_, _) if self.is_keyword(keywords::Box) => {
-            self.bump();
+          token::IDENT(_, _) => {
+              if self.is_keyword(keywords::Box) {
+                self.bump();
 
-            // Check for a place: `box(PLACE) EXPR`.
-            if self.eat(&token::LPAREN) {
-                // Support `box() EXPR` as the default.
-                if !self.eat(&token::RPAREN) {
-                    let place = self.parse_expr();
-                    self.expect(&token::RPAREN);
-                    let subexpression = self.parse_prefix_expr();
-                    hi = subexpression.span.hi;
-                    ex = ExprBox(place, subexpression);
-                    return self.mk_expr(lo, hi, ex);
+                // Check for a place: `box(PLACE) EXPR`.
+                if self.eat(&token::LPAREN) {
+                    // Support `box() EXPR` as the default.
+                    if !self.eat(&token::RPAREN) {
+                        let place = self.parse_expr();
+                        self.expect(&token::RPAREN);
+                        let subexpression = self.parse_prefix_expr();
+                        hi = subexpression.span.hi;
+                        ex = ExprBox(place, subexpression);
+                        return self.mk_expr(lo, hi, ex);
+                    }
                 }
-            }
 
-            // Otherwise, we use the unique pointer default.
-            let subexpression = self.parse_prefix_expr();
-            hi = subexpression.span.hi;
-            // HACK: turn `box [...]` into a boxed-vec
-            ex = match subexpression.node {
-                ExprVec(..) | ExprRepeat(..) => {
-                    let last_span = self.last_span;
-                    self.obsolete(last_span, ObsoleteOwnedVector);
-                    ExprVstore(subexpression, ExprVstoreUniq)
-                }
-                ExprLit(lit) if lit_is_str(lit) => {
-                    ExprVstore(subexpression, ExprVstoreUniq)
-                }
-                _ => self.mk_unary(UnUniq, subexpression)
-            };
+                // Otherwise, we use the unique pointer default.
+                let subexpression = self.parse_prefix_expr();
+                hi = subexpression.span.hi;
+                // HACK: turn `box [...]` into a boxed-vec
+                ex = match subexpression.node {
+                    ExprVec(..) | ExprRepeat(..) => {
+                        let last_span = self.last_span;
+                        self.obsolete(last_span, ObsoleteOwnedVector);
+                        ExprVstore(subexpression, ExprVstoreUniq)
+                    }
+                    ExprLit(lit) if lit_is_str(lit) => {
+                        ExprVstore(subexpression, ExprVstoreUniq)
+                    }
+                    _ => self.mk_unary(UnUniq, subexpression)
+                };
+              } else {
+                return self.parse_dot_or_call_expr()
+              }
           }
           _ => return self.parse_dot_or_call_expr()
         }
@@ -3832,17 +3851,6 @@ impl<'a> Parser<'a> {
                 }
                 SelfStatic
             }
-            token::IDENT(..) if self.is_self_ident() => {
-                let self_ident = self.expect_self_ident();
-
-                // Determine whether this is the fully explicit form, `self:
-                // TYPE`.
-                if self.eat(&token::COLON) {
-                    SelfExplicit(self.parse_ty(false), self_ident)
-                } else {
-                    SelfValue(self_ident)
-                }
-            }
             token::BINOP(token::STAR) => {
                 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
                 // emitting cryptic "unexpected token" errors.
@@ -3860,30 +3868,47 @@ impl<'a> Parser<'a> {
                 // error case, making bogus self ident:
                 SelfValue(special_idents::self_)
             }
-            _ if Parser::token_is_mutability(&self.token) &&
-                    self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
-                mutbl_self = self.parse_mutability();
-                let self_ident = self.expect_self_ident();
-
-                // Determine whether this is the fully explicit form, `self:
-                // TYPE`.
-                if self.eat(&token::COLON) {
-                    SelfExplicit(self.parse_ty(false), self_ident)
+            token::IDENT(..) => {
+                if self.is_self_ident() {
+                    let self_ident = self.expect_self_ident();
+
+                    // Determine whether this is the fully explicit form, `self:
+                    // TYPE`.
+                    if self.eat(&token::COLON) {
+                        SelfExplicit(self.parse_ty(false), self_ident)
+                    } else {
+                        SelfValue(self_ident)
+                    }
+                } else if Parser::token_is_mutability(&self.token) &&
+                        self.look_ahead(1, |t| {
+                            token::is_keyword(keywords::Self, t)
+                        }) {
+                    mutbl_self = self.parse_mutability();
+                    let self_ident = self.expect_self_ident();
+
+                    // Determine whether this is the fully explicit form,
+                    // `self: TYPE`.
+                    if self.eat(&token::COLON) {
+                        SelfExplicit(self.parse_ty(false), self_ident)
+                    } else {
+                        SelfValue(self_ident)
+                    }
+                } else if Parser::token_is_mutability(&self.token) &&
+                        self.look_ahead(1, |t| *t == token::TILDE) &&
+                        self.look_ahead(2, |t| {
+                            token::is_keyword(keywords::Self, t)
+                        }) {
+                    mutbl_self = self.parse_mutability();
+                    self.bump();
+                    drop(self.expect_self_ident());
+                    let last_span = self.last_span;
+                    self.obsolete(last_span, ObsoleteOwnedSelf);
+                    SelfStatic
                 } else {
-                    SelfValue(self_ident)
+                    SelfStatic
                 }
             }
-            _ if Parser::token_is_mutability(&self.token) &&
-                    self.look_ahead(1, |t| *t == token::TILDE) &&
-                    self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
-                mutbl_self = self.parse_mutability();
-                self.bump();
-                drop(self.expect_self_ident());
-                let last_span = self.last_span;
-                self.obsolete(last_span, ObsoleteOwnedSelf);
-                SelfStatic
-            }
-            _ => SelfStatic
+            _ => SelfStatic,
         };
 
         let explicit_self_sp = mk_sp(lo, self.span.hi);