From 4bd6be9dc6055d0cf0d36b1d6bcd8bfef545698f Mon Sep 17 00:00:00 2001 From: Badel2 <2badel2@gmail.com> Date: Fri, 3 Nov 2017 18:17:44 +0100 Subject: [PATCH 1/3] Inclusive range updated to `..=` syntax --- src/libcore/slice/mod.rs | 15 ++++++--------- src/librustc/ty/maps/on_disk_cache.rs | 2 +- src/libsyntax/print/pprust.rs | 2 +- src/test/run-pass-fulldeps/issue-35829.rs | 4 ++-- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 57e5ae28664..25d7d0e3b0c 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -16,9 +16,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -// FIXME: after next stage0, change RangeInclusive { ... } back to ..= -use ops::RangeInclusive; - // How this module is organized. // // The library infrastructure for slices is fairly messy. There's @@ -1047,32 +1044,32 @@ impl SliceIndex<[T]> for ops::RangeToInclusive { #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { - (RangeInclusive { start: 0, end: self.end }).get(slice) + (0..=self.end).get(slice) } #[inline] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { - (RangeInclusive { start: 0, end: self.end }).get_mut(slice) + (0..=self.end).get_mut(slice) } #[inline] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { - (RangeInclusive { start: 0, end: self.end }).get_unchecked(slice) + (0..=self.end).get_unchecked(slice) } #[inline] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { - (RangeInclusive { start: 0, end: self.end }).get_unchecked_mut(slice) + (0..=self.end).get_unchecked_mut(slice) } #[inline] fn index(self, slice: &[T]) -> &[T] { - (RangeInclusive { start: 0, end: self.end }).index(slice) + (0..=self.end).index(slice) } #[inline] fn index_mut(self, slice: &mut [T]) -> &mut [T] { - (RangeInclusive { start: 0, end: self.end }).index_mut(slice) + (0..=self.end).index_mut(slice) } } diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 26581501234..24ce8fb2995 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -165,7 +165,7 @@ impl<'a> CacheDecoder<'a> { fn find_filemap_prev_bytepos(&self, prev_bytepos: BytePos) -> Option<(BytePos, StableFilemapId)> { - for (start, id) in self.prev_filemap_starts.range(BytePos(0) ... prev_bytepos).rev() { + for (start, id) in self.prev_filemap_starts.range(BytePos(0) ..= prev_bytepos).rev() { return Some((*start, *id)) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 8a970fd4098..f0243967421 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2203,7 +2203,7 @@ impl<'a> State<'a> { if limits == ast::RangeLimits::HalfOpen { self.s.word("..")?; } else { - self.s.word("...")?; + self.s.word("..=")?; } if let Some(ref e) = *end { self.print_expr_maybe_paren(e, fake_prec)?; diff --git a/src/test/run-pass-fulldeps/issue-35829.rs b/src/test/run-pass-fulldeps/issue-35829.rs index 0a4c15a9236..f17a0494a69 100644 --- a/src/test/run-pass-fulldeps/issue-35829.rs +++ b/src/test/run-pass-fulldeps/issue-35829.rs @@ -41,8 +41,8 @@ fn main() { let raw_byte_string_lit_kind = LitKind::ByteStr(Rc::new(b"#\"two\"#".to_vec())); assert_eq!(raw_byte_string.node, ExprKind::Lit(P(dummy_spanned(raw_byte_string_lit_kind)))); - // check dotdotdot - let closed_range = quote_expr!(&cx, 0 ... 1); + // check dotdoteq + let closed_range = quote_expr!(&cx, 0 ..= 1); assert_eq!(closed_range.node, ExprKind::Range( Some(quote_expr!(&cx, 0)), Some(quote_expr!(&cx, 1)), From 3c41c28f48b4793097bcce83748d90a30b117e12 Mon Sep 17 00:00:00 2001 From: Badel2 <2badel2@gmail.com> Date: Sun, 5 Nov 2017 00:46:41 +0100 Subject: [PATCH 2/3] Using `...` in expressions is now an error --- src/libsyntax/parse/parser.rs | 32 ++++++++++++++++++-------------- src/libsyntax/parse/token.rs | 2 +- src/libsyntax/util/parser.rs | 3 ++- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a3a265450ab..65d1e34be8a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2784,10 +2784,11 @@ impl<'a> Parser<'a> { if op.precedence() < min_prec { break; } - // Warn about deprecated ... syntax (until SNAP) - if self.token == token::DotDotDot { - self.warn_dotdoteq(self.span); + // Check for deprecated `...` syntax + if self.token == token::DotDotDot && op == AssocOp::DotDotEq { + self.err_dotdotdot_syntax(self.span); } + self.bump(); if op.is_comparison() { self.check_no_chained_comparison(&lhs, &op); @@ -2820,7 +2821,6 @@ impl<'a> Parser<'a> { // // 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. - // (and `x...y`/`x...` until SNAP) let rhs = if self.is_at_start_of_range_notation_rhs() { Some(self.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed)?) @@ -3008,22 +3008,22 @@ impl<'a> Parser<'a> { } } - /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr` (and `...expr` until SNAP) + /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr` fn parse_prefix_range_expr(&mut self, already_parsed_attrs: Option>) -> PResult<'a, P> { - // SNAP remove DotDotDot + // Check for deprecated `...` syntax + if self.token == token::DotDotDot { + self.err_dotdotdot_syntax(self.span); + } + debug_assert!([token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token), - "parse_prefix_range_expr: token {:?} is not DotDot/DotDotDot/DotDotEq", + "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq", self.token); let tok = self.token.clone(); let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?; let lo = self.span; let mut hi = self.span; - // Warn about deprecated ... syntax (until SNAP) - if tok == token::DotDotDot { - self.warn_dotdoteq(self.span); - } self.bump(); let opt_end = if self.is_at_start_of_range_notation_rhs() { // RHS must be parsed with more associativity than the dots. @@ -4271,9 +4271,13 @@ impl<'a> Parser<'a> { }).emit(); } - fn warn_dotdoteq(&self, span: Span) { - self.diagnostic().struct_span_warn(span, { - "`...` is being replaced by `..=`" + fn err_dotdotdot_syntax(&self, span: Span) { + self.diagnostic().struct_span_err(span, { + "`...` syntax cannot be used in expressions" + }).help({ + "Use `..` if you need an exclusive range (a < b)" + }).help({ + "or `..=` if you need an inclusive range (a <= b)" }).emit(); } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 09dc05a4167..f83343bf9af 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -222,8 +222,8 @@ impl Token { BinOp(Or) | OrOr | // closure BinOp(And) | // reference AndAnd | // double reference + // DotDotDot is no longer supported, but we need some way to display the error DotDot | DotDotDot | DotDotEq | // range notation - // SNAP remove DotDotDot Lt | BinOp(Shl) | // associated path ModSep | // global path Pound => true, // expression attributes diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index 590874806d7..6014ec5aa92 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -106,7 +106,8 @@ impl AssocOp { Token::OrOr => Some(LOr), Token::DotDot => Some(DotDot), Token::DotDotEq => Some(DotDotEq), - Token::DotDotDot => Some(DotDotEq), // remove this after SNAP + // DotDotDot is no longer supported, but we need some way to display the error + Token::DotDotDot => Some(DotDotEq), Token::Colon => Some(Colon), _ if t.is_keyword(keywords::As) => Some(As), _ => None From b81a7b333abce1d5de85406947db5007d19730c4 Mon Sep 17 00:00:00 2001 From: Badel2 <2badel2@gmail.com> Date: Mon, 6 Nov 2017 13:04:54 +0100 Subject: [PATCH 3/3] Test error for `...` in expressions --- .../parse-fail/range_inclusive_dotdotdot.rs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/parse-fail/range_inclusive_dotdotdot.rs diff --git a/src/test/parse-fail/range_inclusive_dotdotdot.rs b/src/test/parse-fail/range_inclusive_dotdotdot.rs new file mode 100644 index 00000000000..a4c36a2f0ba --- /dev/null +++ b/src/test/parse-fail/range_inclusive_dotdotdot.rs @@ -0,0 +1,38 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only -Z continue-parse-after-error + +// Make sure that inclusive ranges with `...` syntax don't parse. + +#![feature(inclusive_range_syntax, inclusive_range)] + +use std::ops::RangeToInclusive; + +fn return_range_to() -> RangeToInclusive { + return ...1; //~ERROR `...` syntax cannot be used in expressions + //~^HELP Use `..` if you need an exclusive range (a < b) + //~^^HELP or `..=` if you need an inclusive range (a <= b) +} + +pub fn main() { + let x = ...0; //~ERROR `...` syntax cannot be used in expressions + //~^HELP Use `..` if you need an exclusive range (a < b) + //~^^HELP or `..=` if you need an inclusive range (a <= b) + + let x = 5...5; //~ERROR `...` syntax cannot be used in expressions + //~^HELP Use `..` if you need an exclusive range (a < b) + //~^^HELP or `..=` if you need an inclusive range (a <= b) + + for _ in 0...1 {} //~ERROR `...` syntax cannot be used in expressions + //~^HELP Use `..` if you need an exclusive range (a < b) + //~^^HELP or `..=` if you need an inclusive range (a <= b) +} +