From 9f899a66591c1a4bc68b51fc6d1f207d2d49a087 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Wed, 16 Mar 2016 21:35:36 -0400 Subject: error during parsing for malformed inclusive range Now it is impossible for `...` or `a...` to reach HIR lowering without a rogue syntax extension in play. --- src/libsyntax/parse/parser.rs | 67 ++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 29 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a1adc99055f..deda0c59051 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2072,8 +2072,15 @@ impl<'a> Parser<'a> { start: Option>, end: Option>, limits: RangeLimits) - -> ast::ExprKind { - ExprKind::Range(start, end, limits) + -> PResult<'a, ast::ExprKind> { + if end.is_none() && limits == RangeLimits::Closed { + Err(self.span_fatal_help(self.span, + "inclusive range with no end", + "currently, inclusive ranges must be bounded at the end \ + (`...b` or `a...b`) -- see tracking issue #28237")) + } else { + Ok(ExprKind::Range(start, end, limits)) + } } pub fn mk_field(&mut self, expr: P, ident: ast::SpannedIdent) -> ast::ExprKind { @@ -2961,12 +2968,12 @@ impl<'a> Parser<'a> { lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, ExprKind::Type(lhs, rhs), None); continue - } else if op == AssocOp::DotDot { - // If we didn’t have to handle `x..`, it would be pretty easy to generalise - // it to the Fixity::None code. + } else if op == AssocOp::DotDot || op == AssocOp::DotDotDot { + // If we didn’t have to handle `x..`/`x...`, it would be pretty easy to + // generalise it to the Fixity::None code. // - // We have 2 alternatives here: `x..y` and `x..` The other two variants are - // handled with `parse_prefix_range_expr` call above. + // We have 2 alternatives here: `x..y`/`x...y` and `x..`/`x...` The other + // two variants are handled with `parse_prefix_range_expr` call above. let rhs = if self.is_at_start_of_range_notation_rhs() { let rhs = self.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed); @@ -2985,7 +2992,13 @@ impl<'a> Parser<'a> { } else { cur_op_span }); - let r = self.mk_range(Some(lhs), rhs, RangeLimits::HalfOpen); + let limits = if op == AssocOp::DotDot { + RangeLimits::HalfOpen + } else { + RangeLimits::Closed + }; + + let r = try!(self.mk_range(Some(lhs), rhs, limits)); lhs = self.mk_expr(lhs_span.lo, rhs_span.hi, r, None); break } @@ -3003,8 +3016,7 @@ impl<'a> Parser<'a> { this.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed) }), - // the only operator handled here is `...` (the other non-associative operators are - // special-cased above) + // no operators are currently handled here Fixity::None => self.with_res( restrictions - Restrictions::RESTRICTION_STMT_EXPR, |this| { @@ -3045,13 +3057,8 @@ impl<'a> Parser<'a> { let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None) } - AssocOp::DotDotDot => { - let (lhs_span, rhs_span) = (lhs.span, rhs.span); - let r = self.mk_range(Some(lhs), Some(rhs), RangeLimits::Closed); - self.mk_expr(lhs_span.lo, rhs_span.hi, r, None) - } - AssocOp::As | AssocOp::Colon | AssocOp::DotDot => { - self.bug("As, Colon or DotDot branch reached") + AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotDot => { + self.bug("As, Colon, DotDot or DotDotDot branch reached") } }; @@ -3095,21 +3102,23 @@ impl<'a> Parser<'a> { // RHS must be parsed with more associativity than the dots. let next_prec = AssocOp::from_token(&tok).unwrap().precedence() + 1; Some(self.parse_assoc_expr_with(next_prec, - LhsExpr::NotYetParsed) - .map(|x|{ - hi = x.span.hi; - x - })?) + LhsExpr::NotYetParsed) + .map(|x|{ + hi = x.span.hi; + x + })?) } else { None }; - let r = self.mk_range(None, - opt_end, - if tok == token::DotDot { - RangeLimits::HalfOpen - } else { - RangeLimits::Closed - }); + let limits = if tok == token::DotDot { + RangeLimits::HalfOpen + } else { + RangeLimits::Closed + }; + + let r = try!(self.mk_range(None, + opt_end, + limits)); Ok(self.mk_expr(lo, hi, r, attrs)) } -- cgit 1.4.1-3-g733a5 From 861644f2af5421f5aa55d4e7fddfc8dba54bcb70 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Fri, 18 Mar 2016 19:04:43 -0400 Subject: address nits --- src/librustc_front/lowering.rs | 2 +- src/libsyntax/parse/parser.rs | 7 ++++--- src/test/compile-fail/impossible_range.rs | 4 ++-- src/test/parse-fail/range_inclusive.rs | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index a0466de999a..be184179451 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -142,7 +142,7 @@ impl<'a, 'hir> LoweringContext<'a> { } } - // panics if this LoweringContext's NodeIdAssigner is not a Session + // Panics if this LoweringContext's NodeIdAssigner is not able to emit diagnostics. fn diagnostic(&self) -> &Handler { self.id_assigner.diagnostic() } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index deda0c59051..4782d3fb3b9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2076,8 +2076,8 @@ impl<'a> Parser<'a> { if end.is_none() && limits == RangeLimits::Closed { Err(self.span_fatal_help(self.span, "inclusive range with no end", - "currently, inclusive ranges must be bounded at the end \ - (`...b` or `a...b`) -- see tracking issue #28237")) + "inclusive ranges must be bounded at the end \ + (`...b` or `a...b`)")) } else { Ok(ExprKind::Range(start, end, limits)) } @@ -3016,7 +3016,8 @@ impl<'a> Parser<'a> { this.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed) }), - // no operators are currently handled here + // We currently have no non-associative operators that are not handled above by + // the special cases. The code is here only for future convenience. Fixity::None => self.with_res( restrictions - Restrictions::RESTRICTION_STMT_EXPR, |this| { diff --git a/src/test/compile-fail/impossible_range.rs b/src/test/compile-fail/impossible_range.rs index 169ba442240..94e048fed65 100644 --- a/src/test/compile-fail/impossible_range.rs +++ b/src/test/compile-fail/impossible_range.rs @@ -19,9 +19,9 @@ pub fn main() { 0..1; ...; //~ERROR inclusive range with no end - //~^HELP 28237 + //~^HELP bounded at the end 0...; //~ERROR inclusive range with no end - //~^HELP 28237 + //~^HELP bounded at the end ...1; 0...1; } diff --git a/src/test/parse-fail/range_inclusive.rs b/src/test/parse-fail/range_inclusive.rs index be2a63a07bb..ce97372c668 100644 --- a/src/test/parse-fail/range_inclusive.rs +++ b/src/test/parse-fail/range_inclusive.rs @@ -14,6 +14,6 @@ pub fn main() { for _ in 1... {} //~ERROR inclusive range with no end - //~^HELP 28237 + //~^HELP bounded at the end } -- cgit 1.4.1-3-g733a5