about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/parse/parser.rs142
-rw-r--r--src/libsyntax/util/parser.rs9
2 files changed, 77 insertions, 74 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f4e14a6ee36..6845b92dac0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2602,53 +2602,50 @@ impl<'a> Parser<'a> {
     pub fn parse_prefix_expr(&mut self) -> PResult<P<Expr>> {
         let lo = self.span.lo;
         let hi;
-
         // Note: when adding new unary operators, don't forget to adjust Token::can_begin_expr()
-        let ex;
-        match self.token {
-          token::Not => {
-            try!(self.bump());
-            let e = try!(self.parse_prefix_expr());
-            hi = e.span.hi;
-            ex = self.mk_unary(UnNot, e);
-          }
-          token::BinOp(token::Minus) => {
-            try!(self.bump());
-            let e = try!(self.parse_prefix_expr());
-            hi = e.span.hi;
-            ex = self.mk_unary(UnNeg, e);
-          }
-          token::BinOp(token::Star) => {
-            try!(self.bump());
-            let e = try!(self.parse_prefix_expr());
-            hi = e.span.hi;
-            ex = self.mk_unary(UnDeref, e);
-          }
-          token::BinOp(token::And) | token::AndAnd => {
-            try!(self.expect_and());
-            let m = try!(self.parse_mutability());
-            let e = try!(self.parse_prefix_expr());
-            hi = e.span.hi;
-            ex = ExprAddrOf(m, e);
-          }
-          token::Ident(..) if self.token.is_keyword(keywords::In) => {
-              try!(self.bump());
-              let place = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
-              let blk = try!(self.parse_block());
-              let span = blk.span;
-              hi = span.hi;
-              let blk_expr = self.mk_expr(span.lo, span.hi, ExprBlock(blk));
-              self.span_warn(span, "in PLACE BLOCK syntax is deprecated and will be removed soon");
-              ex = ExprInPlace(place, blk_expr);
-          }
-          token::Ident(..) if self.token.is_keyword(keywords::Box) => {
-              try!(self.bump());
-              let subexpression = try!(self.parse_prefix_expr());
-              hi = subexpression.span.hi;
-              ex = ExprBox(subexpression);
-          }
-          _ => return self.parse_dot_or_call_expr()
-        }
+        let ex = match self.token {
+            token::Not => {
+                try!(self.bump());
+                let e = try!(self.parse_prefix_expr());
+                hi = e.span.hi;
+                self.mk_unary(UnNot, e)
+            }
+            token::BinOp(token::Minus) => {
+                try!(self.bump());
+                let e = try!(self.parse_prefix_expr());
+                hi = e.span.hi;
+                self.mk_unary(UnNeg, e)
+            }
+            token::BinOp(token::Star) => {
+                try!(self.bump());
+                let e = try!(self.parse_prefix_expr());
+                hi = e.span.hi;
+                self.mk_unary(UnDeref, e)
+            }
+            token::BinOp(token::And) | token::AndAnd => {
+                try!(self.expect_and());
+                let m = try!(self.parse_mutability());
+                let e = try!(self.parse_prefix_expr());
+                hi = e.span.hi;
+                ExprAddrOf(m, e)
+            }
+            token::Ident(..) if self.token.is_keyword(keywords::In) => {
+                try!(self.bump());
+                let place = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
+                let blk = try!(self.parse_block());
+                let span = blk.span;
+                hi = span.hi;
+                let blk_expr = self.mk_expr(span.lo, span.hi, ExprBlock(blk));
+                ExprInPlace(place, blk_expr)
+            }
+            token::Ident(..) if self.token.is_keyword(keywords::Box) => {
+                try!(self.bump());
+                let subexpression = try!(self.parse_prefix_expr());
+                hi = subexpression.span.hi;
+                ExprBox(subexpression)
+            }
+            _ => return self.parse_dot_or_call_expr()
+        };
         return Ok(self.mk_expr(lo, hi, ex));
     }
 
@@ -2657,35 +2654,15 @@ impl<'a> Parser<'a> {
     /// This parses an expression accounting for associativity and precedence of the operators in
     /// the expression.
     pub fn parse_assoc_expr(&mut self) -> PResult<P<Expr>> {
-        if self.token == token::DotDot {
-            // prefix-form of range notation `..expr` and `..`
-            // This has the precedence just higher than assignment expressions (much lower than
-            // other prefix expressions) to be consistent with the postfix-form `expr..`
-            // If it isn’t clear yet, this is a hack of the worst kind (one that also probably
-            // can’t be fixed anymore because stability guarantees).
-            let lo = self.span.lo;
-            let mut hi = self.span.hi;
-            try!(self.bump());
-            let opt_end = if self.is_at_start_of_range_notation_rhs() {
-                // RHS must be parsed with more associativity than DotDot.
-                let next_prec = AssocOp::from_token(&token::DotDot).unwrap().precedence() + 1;
-                let end = try!(self.parse_assoc_expr_with(next_prec, None));
-                hi = end.span.hi;
-                Some(end)
-            } else {
-                None
-            };
-            let r = self.mk_range(None, opt_end);
-            Ok(self.mk_expr(lo, hi, r))
-        } else {
-            self.parse_assoc_expr_with(0, None)
-        }
+        self.parse_assoc_expr_with(0, None)
     }
 
     /// Parse an associative expression with operators of at least `min_prec` precedence
     pub fn parse_assoc_expr_with(&mut self, min_prec: usize, lhs: Option<P<Expr>>) -> PResult<P<Expr>> {
         let mut lhs = if lhs.is_some() {
             lhs.unwrap()
+        } else if self.token == token::DotDot {
+            return self.parse_prefix_range_expr();
         } else {
             try!(self.parse_prefix_expr())
         };
@@ -2710,13 +2687,10 @@ impl<'a> Parser<'a> {
                 continue
             } else if op == AssocOp::DotDot {
                     // If we didn’t have to handle `x..`, it would be pretty easy to generalise
-                    // here by simply doing something along the lines of
-                    //
-                    //     break_from_this_loop_after_setting_lhs = true;
-                    //     rhs = self.parse_assoc_expr_with(op.precedence() + 1, None);
+                    // it to the Fixity::None code.
                     //
                     // We have 2 alternatives here: `x..y` and `x..` The other two variants are
-                    // handled in `parse_assoc_expr`
+                    // handled with `parse_prefix_range_expr` call above.
                     let rhs = if self.is_at_start_of_range_notation_rhs() {
                         self.parse_assoc_expr_with(op.precedence() + 1, None).ok()
                     } else {
@@ -2800,6 +2774,26 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Parse prefix-forms of range notation: `..expr` and `..`
+    fn parse_prefix_range_expr(&mut self) -> PResult<P<Expr>> {
+        debug_assert!(self.token == token::DotDot);
+        let lo = self.span.lo;
+        let mut hi = self.span.hi;
+        try!(self.bump());
+        let opt_end = if self.is_at_start_of_range_notation_rhs() {
+            // RHS must be parsed with more associativity than DotDot.
+            let next_prec = AssocOp::from_token(&token::DotDot).unwrap().precedence() + 1;
+            Some(try!(self.parse_assoc_expr_with(next_prec, None).map(|x|{
+                hi = x.span.hi;
+                x
+            })))
+         } else {
+            None
+        };
+        let r = self.mk_range(None, opt_end);
+        Ok(self.mk_expr(lo, hi, r))
+    }
+
     fn is_at_start_of_range_notation_rhs(&self) -> bool {
         if self.token.can_begin_expr() {
             // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs
index c12cd8e89db..d09a23c12f1 100644
--- a/src/libsyntax/util/parser.rs
+++ b/src/libsyntax/util/parser.rs
@@ -1,3 +1,12 @@
+// 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.
 use parse::token::{Token, BinOpToken, keywords};
 use ast;