@@ -62,7 +62,7 @@ use ast::{UnnamedField, UnsafeBlock};
62
62
use ast:: { ViewPath , ViewPathGlob , ViewPathList , ViewPathSimple } ;
63
63
use ast:: { Visibility , WhereClause } ;
64
64
use 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} ;
66
66
use codemap:: { self , Span , BytePos , Spanned , spanned, mk_sp} ;
67
67
use diagnostic;
68
68
use ext:: tt:: macro_parser;
@@ -93,7 +93,6 @@ bitflags! {
93
93
const RESTRICTION_STMT_EXPR = 0b0001 ,
94
94
const RESTRICTION_NO_BAR_OP = 0b0010 ,
95
95
const RESTRICTION_NO_STRUCT_LITERAL = 0b0100 ,
96
- const RESTRICTION_NO_DOTS = 0b1000 ,
97
96
}
98
97
}
99
98
@@ -2775,13 +2774,6 @@ impl<'a> Parser<'a> {
2775
2774
hi = e. span . hi ;
2776
2775
ex = ExprAddrOf ( m, e) ;
2777
2776
}
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
- }
2785
2777
token:: Ident ( _, _) => {
2786
2778
if !self . token . is_keyword ( keywords:: Box ) {
2787
2779
return self . parse_dot_or_call_expr ( ) ;
@@ -2855,10 +2847,10 @@ impl<'a> Parser<'a> {
2855
2847
self . check_no_chained_comparison ( & * lhs, cur_op)
2856
2848
}
2857
2849
let cur_prec = operator_prec ( cur_op) ;
2858
- if cur_prec > min_prec {
2850
+ if cur_prec >= min_prec {
2859
2851
self . bump ( ) ;
2860
2852
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 ) ;
2862
2854
let lhs_span = lhs. span ;
2863
2855
let rhs_span = rhs. span ;
2864
2856
let binary = self . mk_binary ( cur_op, lhs, rhs) ;
@@ -2869,7 +2861,7 @@ impl<'a> Parser<'a> {
2869
2861
}
2870
2862
}
2871
2863
None => {
2872
- if as_prec > min_prec && self . eat_keyword ( keywords:: As ) {
2864
+ if AS_PREC >= min_prec && self . eat_keyword ( keywords:: As ) {
2873
2865
let rhs = self . parse_ty ( ) ;
2874
2866
let _as = self . mk_expr ( lhs. span . lo ,
2875
2867
rhs. span . hi ,
@@ -2905,8 +2897,24 @@ impl<'a> Parser<'a> {
2905
2897
/// actually, this seems to be the main entry point for
2906
2898
/// parsing an arbitrary expression.
2907
2899
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
+ }
2910
2918
}
2911
2919
2912
2920
pub fn parse_assign_expr_with ( & mut self , lhs : P < Expr > ) -> P < Expr > {
@@ -2938,11 +2946,11 @@ impl<'a> Parser<'a> {
2938
2946
self . mk_expr ( span. lo , rhs_span. hi , assign_op)
2939
2947
}
2940
2948
// A range expression, either `expr..expr` or `expr..`.
2941
- token:: DotDot if ! self . restrictions . contains ( RESTRICTION_NO_DOTS ) => {
2949
+ token:: DotDot => {
2942
2950
self . bump ( ) ;
2943
2951
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 ( ) ;
2946
2954
Some ( end)
2947
2955
} else {
2948
2956
None
@@ -2960,6 +2968,18 @@ impl<'a> Parser<'a> {
2960
2968
}
2961
2969
}
2962
2970
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
+
2963
2983
/// Parse an 'if' or 'if let' expression ('if' token already eaten)
2964
2984
pub fn parse_if_expr ( & mut self ) -> P < Expr > {
2965
2985
if self . token . is_keyword ( keywords:: Let ) {
0 commit comments