@@ -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
+ "inclusive ranges must be bounded at the end \
2080
+ (`...b` or `a...b`)") )
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 {
@@ -2999,12 +3006,12 @@ impl<'a> Parser<'a> {
2999
3006
lhs = self . mk_expr ( lhs_span. lo , rhs. span . hi ,
3000
3007
ExprKind :: Type ( lhs, rhs) , None ) ;
3001
3008
continue
3002
- } else if op == AssocOp :: DotDot {
3003
- // If we didn’t have to handle `x..`, it would be pretty easy to generalise
3004
- // it to the Fixity::None code.
3009
+ } else if op == AssocOp :: DotDot || op == AssocOp :: DotDotDot {
3010
+ // If we didn’t have to handle `x..`/`x...` , it would be pretty easy to
3011
+ // generalise it to the Fixity::None code.
3005
3012
//
3006
- // We have 2 alternatives here: `x..y` and `x..` The other two variants are
3007
- // handled with `parse_prefix_range_expr` call above.
3013
+ // We have 2 alternatives here: `x..y`/`x...y` and `x..`/`x...` The other
3014
+ // two variants are handled with `parse_prefix_range_expr` call above.
3008
3015
let rhs = if self . is_at_start_of_range_notation_rhs ( ) {
3009
3016
let rhs = self . parse_assoc_expr_with ( op. precedence ( ) + 1 ,
3010
3017
LhsExpr :: NotYetParsed ) ;
@@ -3023,7 +3030,13 @@ impl<'a> Parser<'a> {
3023
3030
} else {
3024
3031
cur_op_span
3025
3032
} ) ;
3026
- let r = self . mk_range ( Some ( lhs) , rhs, RangeLimits :: HalfOpen ) ;
3033
+ let limits = if op == AssocOp :: DotDot {
3034
+ RangeLimits :: HalfOpen
3035
+ } else {
3036
+ RangeLimits :: Closed
3037
+ } ;
3038
+
3039
+ let r = try!( self . mk_range ( Some ( lhs) , rhs, limits) ) ;
3027
3040
lhs = self . mk_expr ( lhs_span. lo , rhs_span. hi , r, None ) ;
3028
3041
break
3029
3042
}
@@ -3041,8 +3054,8 @@ impl<'a> Parser<'a> {
3041
3054
this. parse_assoc_expr_with ( op. precedence ( ) + 1 ,
3042
3055
LhsExpr :: NotYetParsed )
3043
3056
} ) ,
3044
- // the only operator handled here is `...` (the other non-associative operators are
3045
- // special-cased above)
3057
+ // We currently have no non-associative operators that are not handled above by
3058
+ // the special cases. The code is here only for future convenience.
3046
3059
Fixity :: None => self . with_res (
3047
3060
restrictions - Restrictions :: RESTRICTION_STMT_EXPR ,
3048
3061
|this| {
@@ -3083,13 +3096,8 @@ impl<'a> Parser<'a> {
3083
3096
let aopexpr = self . mk_assign_op ( codemap:: respan ( cur_op_span, aop) , lhs, rhs) ;
3084
3097
self . mk_expr ( lhs_span. lo , rhs_span. hi , aopexpr, None )
3085
3098
}
3086
- AssocOp :: DotDotDot => {
3087
- let ( lhs_span, rhs_span) = ( lhs. span , rhs. span ) ;
3088
- let r = self . mk_range ( Some ( lhs) , Some ( rhs) , RangeLimits :: Closed ) ;
3089
- self . mk_expr ( lhs_span. lo , rhs_span. hi , r, None )
3090
- }
3091
- AssocOp :: As | AssocOp :: Colon | AssocOp :: DotDot => {
3092
- self . bug ( "As, Colon or DotDot branch reached" )
3099
+ AssocOp :: As | AssocOp :: Colon | AssocOp :: DotDot | AssocOp :: DotDotDot => {
3100
+ self . bug ( "As, Colon, DotDot or DotDotDot branch reached" )
3093
3101
}
3094
3102
} ;
3095
3103
@@ -3133,21 +3141,23 @@ impl<'a> Parser<'a> {
3133
3141
// RHS must be parsed with more associativity than the dots.
3134
3142
let next_prec = AssocOp :: from_token ( & tok) . unwrap ( ) . precedence ( ) + 1 ;
3135
3143
Some ( self . parse_assoc_expr_with ( next_prec,
3136
- LhsExpr :: NotYetParsed )
3137
- . map ( |x|{
3138
- hi = x. span . hi ;
3139
- x
3140
- } ) ?)
3144
+ LhsExpr :: NotYetParsed )
3145
+ . map ( |x|{
3146
+ hi = x. span . hi ;
3147
+ x
3148
+ } ) ?)
3141
3149
} else {
3142
3150
None
3143
3151
} ;
3144
- let r = self . mk_range ( None ,
3145
- opt_end,
3146
- if tok == token:: DotDot {
3147
- RangeLimits :: HalfOpen
3148
- } else {
3149
- RangeLimits :: Closed
3150
- } ) ;
3152
+ let limits = if tok == token:: DotDot {
3153
+ RangeLimits :: HalfOpen
3154
+ } else {
3155
+ RangeLimits :: Closed
3156
+ } ;
3157
+
3158
+ let r = try!( self . mk_range ( None ,
3159
+ opt_end,
3160
+ limits) ) ;
3151
3161
Ok ( self . mk_expr ( lo, hi, r, attrs) )
3152
3162
}
3153
3163
0 commit comments