@@ -62,7 +62,7 @@ use ast::{UnnamedField, UnsafeBlock};
6262use ast:: { ViewPath , ViewPathGlob , ViewPathList , ViewPathSimple } ;
6363use ast:: { Visibility , WhereClause } ;
6464use ast;
65- use ast_util:: { self , as_prec , ident_to_path, operator_prec} ;
65+ use ast_util:: { self , AS_PREC , ident_to_path, operator_prec} ;
6666use codemap:: { self , Span , BytePos , Spanned , spanned, mk_sp} ;
6767use diagnostic;
6868use ext:: tt:: macro_parser;
@@ -93,7 +93,6 @@ bitflags! {
9393 const RESTRICTION_STMT_EXPR = 0b0001 ,
9494 const RESTRICTION_NO_BAR_OP = 0b0010 ,
9595 const RESTRICTION_NO_STRUCT_LITERAL = 0b0100 ,
96- const RESTRICTION_NO_DOTS = 0b1000 ,
9796 }
9897}
9998
@@ -2775,13 +2774,6 @@ impl<'a> Parser<'a> {
27752774 hi = e. span . hi ;
27762775 ex = ExprAddrOf ( m, e) ;
27772776 }
2778- token:: DotDot if !self . restrictions . contains ( RESTRICTION_NO_DOTS ) => {
2779- // A range, closed above: `..expr`.
2780- self . bump ( ) ;
2781- let e = self . parse_expr ( ) ;
2782- hi = e. span . hi ;
2783- ex = self . mk_range ( None , Some ( e) ) ;
2784- }
27852777 token:: Ident ( _, _) => {
27862778 if !self . token . is_keyword ( keywords:: Box ) {
27872779 return self . parse_dot_or_call_expr ( ) ;
@@ -2855,10 +2847,10 @@ impl<'a> Parser<'a> {
28552847 self . check_no_chained_comparison ( & * lhs, cur_op)
28562848 }
28572849 let cur_prec = operator_prec ( cur_op) ;
2858- if cur_prec > min_prec {
2850+ if cur_prec >= min_prec {
28592851 self . bump ( ) ;
28602852 let expr = self . parse_prefix_expr ( ) ;
2861- let rhs = self . parse_more_binops ( expr, cur_prec) ;
2853+ let rhs = self . parse_more_binops ( expr, cur_prec + 1 ) ;
28622854 let lhs_span = lhs. span ;
28632855 let rhs_span = rhs. span ;
28642856 let binary = self . mk_binary ( cur_op, lhs, rhs) ;
@@ -2869,7 +2861,7 @@ impl<'a> Parser<'a> {
28692861 }
28702862 }
28712863 None => {
2872- if as_prec > min_prec && self . eat_keyword ( keywords:: As ) {
2864+ if AS_PREC >= min_prec && self . eat_keyword ( keywords:: As ) {
28732865 let rhs = self . parse_ty ( ) ;
28742866 let _as = self . mk_expr ( lhs. span . lo ,
28752867 rhs. span . hi ,
@@ -2905,8 +2897,24 @@ impl<'a> Parser<'a> {
29052897 /// actually, this seems to be the main entry point for
29062898 /// parsing an arbitrary expression.
29072899 pub fn parse_assign_expr ( & mut self ) -> P < Expr > {
2908- let lhs = self . parse_binops ( ) ;
2909- self . parse_assign_expr_with ( lhs)
2900+ match self . token {
2901+ token:: DotDot => {
2902+ // prefix-form of range notation '..expr'
2903+ // This has the same precedence as assignment expressions
2904+ // (much lower than other prefix expressions) to be consistent
2905+ // with the postfix-form 'expr..'
2906+ let lo = self . span . lo ;
2907+ self . bump ( ) ;
2908+ let rhs = self . parse_binops ( ) ;
2909+ let hi = rhs. span . hi ;
2910+ let ex = self . mk_range ( None , Some ( rhs) ) ;
2911+ self . mk_expr ( lo, hi, ex)
2912+ }
2913+ _ => {
2914+ let lhs = self . parse_binops ( ) ;
2915+ self . parse_assign_expr_with ( lhs)
2916+ }
2917+ }
29102918 }
29112919
29122920 pub fn parse_assign_expr_with ( & mut self , lhs : P < Expr > ) -> P < Expr > {
@@ -2938,11 +2946,11 @@ impl<'a> Parser<'a> {
29382946 self . mk_expr ( span. lo , rhs_span. hi , assign_op)
29392947 }
29402948 // A range expression, either `expr..expr` or `expr..`.
2941- token:: DotDot if ! self . restrictions . contains ( RESTRICTION_NO_DOTS ) => {
2949+ token:: DotDot => {
29422950 self . bump ( ) ;
29432951
2944- let opt_end = if self . token . can_begin_expr ( ) {
2945- let end = self . parse_expr_res ( RESTRICTION_NO_DOTS ) ;
2952+ let opt_end = if self . is_at_start_of_range_notation_rhs ( ) {
2953+ let end = self . parse_binops ( ) ;
29462954 Some ( end)
29472955 } else {
29482956 None
@@ -2960,6 +2968,18 @@ impl<'a> Parser<'a> {
29602968 }
29612969 }
29622970
2971+ fn is_at_start_of_range_notation_rhs ( & self ) -> bool {
2972+ if self . token . can_begin_expr ( ) {
2973+ // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
2974+ if self . token == token:: OpenDelim ( token:: Brace ) {
2975+ return !self . restrictions . contains ( RESTRICTION_NO_STRUCT_LITERAL ) ;
2976+ }
2977+ true
2978+ } else {
2979+ false
2980+ }
2981+ }
2982+
29632983 /// Parse an 'if' or 'if let' expression ('if' token already eaten)
29642984 pub fn parse_if_expr ( & mut self ) -> P < Expr > {
29652985 if self . token . is_keyword ( keywords:: Let ) {
0 commit comments