@@ -2072,8 +2072,15 @@ impl<'a> Parser<'a> {
2072
2072
start : Option < P < Expr > > ,
2073
2073
end : Option < P < Expr > > ,
2074
2074
limits : RangeLimits )
2075
- -> ast:: ExprKind {
2076
- ExprKind :: Range ( start, end, limits)
2075
+ -> PResult < ' a , ast:: ExprKind > {
2076
+ if end. is_none ( ) && limits == RangeLimits :: Closed {
2077
+ Err ( self . span_fatal_help ( self . span ,
2078
+ "inclusive range with no end" ,
2079
+ "currently, inclusive ranges must be bounded at the end \
2080
+ (`...b` or `a...b`) -- see tracking issue #28237") )
2081
+ } else {
2082
+ Ok ( ExprKind :: Range ( start, end, limits) )
2083
+ }
2077
2084
}
2078
2085
2079
2086
pub fn mk_field ( & mut self , expr : P < Expr > , ident : ast:: SpannedIdent ) -> ast:: ExprKind {
@@ -2961,12 +2968,12 @@ impl<'a> Parser<'a> {
2961
2968
lhs = self . mk_expr ( lhs_span. lo , rhs. span . hi ,
2962
2969
ExprKind :: Type ( lhs, rhs) , None ) ;
2963
2970
continue
2964
- } else if op == AssocOp :: DotDot {
2965
- // If we didn’t have to handle `x..`, it would be pretty easy to generalise
2966
- // it to the Fixity::None code.
2971
+ } else if op == AssocOp :: DotDot || op == AssocOp :: DotDotDot {
2972
+ // If we didn’t have to handle `x..`/`x...` , it would be pretty easy to
2973
+ // generalise it to the Fixity::None code.
2967
2974
//
2968
- // We have 2 alternatives here: `x..y` and `x..` The other two variants are
2969
- // handled with `parse_prefix_range_expr` call above.
2975
+ // We have 2 alternatives here: `x..y`/`x...y` and `x..`/`x...` The other
2976
+ // two variants are handled with `parse_prefix_range_expr` call above.
2970
2977
let rhs = if self . is_at_start_of_range_notation_rhs ( ) {
2971
2978
let rhs = self . parse_assoc_expr_with ( op. precedence ( ) + 1 ,
2972
2979
LhsExpr :: NotYetParsed ) ;
@@ -2985,7 +2992,13 @@ impl<'a> Parser<'a> {
2985
2992
} else {
2986
2993
cur_op_span
2987
2994
} ) ;
2988
- let r = self . mk_range ( Some ( lhs) , rhs, RangeLimits :: HalfOpen ) ;
2995
+ let limits = if op == AssocOp :: DotDot {
2996
+ RangeLimits :: HalfOpen
2997
+ } else {
2998
+ RangeLimits :: Closed
2999
+ } ;
3000
+
3001
+ let r = try!( self . mk_range ( Some ( lhs) , rhs, limits) ) ;
2989
3002
lhs = self . mk_expr ( lhs_span. lo , rhs_span. hi , r, None ) ;
2990
3003
break
2991
3004
}
@@ -3003,8 +3016,7 @@ impl<'a> Parser<'a> {
3003
3016
this. parse_assoc_expr_with ( op. precedence ( ) + 1 ,
3004
3017
LhsExpr :: NotYetParsed )
3005
3018
} ) ,
3006
- // the only operator handled here is `...` (the other non-associative operators are
3007
- // special-cased above)
3019
+ // no operators are currently handled here
3008
3020
Fixity :: None => self . with_res (
3009
3021
restrictions - Restrictions :: RESTRICTION_STMT_EXPR ,
3010
3022
|this| {
@@ -3045,13 +3057,8 @@ impl<'a> Parser<'a> {
3045
3057
let aopexpr = self . mk_assign_op ( codemap:: respan ( cur_op_span, aop) , lhs, rhs) ;
3046
3058
self . mk_expr ( lhs_span. lo , rhs_span. hi , aopexpr, None )
3047
3059
}
3048
- AssocOp :: DotDotDot => {
3049
- let ( lhs_span, rhs_span) = ( lhs. span , rhs. span ) ;
3050
- let r = self . mk_range ( Some ( lhs) , Some ( rhs) , RangeLimits :: Closed ) ;
3051
- self . mk_expr ( lhs_span. lo , rhs_span. hi , r, None )
3052
- }
3053
- AssocOp :: As | AssocOp :: Colon | AssocOp :: DotDot => {
3054
- self . bug ( "As, Colon or DotDot branch reached" )
3060
+ AssocOp :: As | AssocOp :: Colon | AssocOp :: DotDot | AssocOp :: DotDotDot => {
3061
+ self . bug ( "As, Colon, DotDot or DotDotDot branch reached" )
3055
3062
}
3056
3063
} ;
3057
3064
@@ -3095,21 +3102,23 @@ impl<'a> Parser<'a> {
3095
3102
// RHS must be parsed with more associativity than the dots.
3096
3103
let next_prec = AssocOp :: from_token ( & tok) . unwrap ( ) . precedence ( ) + 1 ;
3097
3104
Some ( self . parse_assoc_expr_with ( next_prec,
3098
- LhsExpr :: NotYetParsed )
3099
- . map ( |x|{
3100
- hi = x. span . hi ;
3101
- x
3102
- } ) ?)
3105
+ LhsExpr :: NotYetParsed )
3106
+ . map ( |x|{
3107
+ hi = x. span . hi ;
3108
+ x
3109
+ } ) ?)
3103
3110
} else {
3104
3111
None
3105
3112
} ;
3106
- let r = self . mk_range ( None ,
3107
- opt_end,
3108
- if tok == token:: DotDot {
3109
- RangeLimits :: HalfOpen
3110
- } else {
3111
- RangeLimits :: Closed
3112
- } ) ;
3113
+ let limits = if tok == token:: DotDot {
3114
+ RangeLimits :: HalfOpen
3115
+ } else {
3116
+ RangeLimits :: Closed
3117
+ } ;
3118
+
3119
+ let r = try!( self . mk_range ( None ,
3120
+ opt_end,
3121
+ limits) ) ;
3113
3122
Ok ( self . mk_expr ( lo, hi, r, attrs) )
3114
3123
}
3115
3124
0 commit comments