Skip to content

Commit d5ff0e6

Browse files
committed
Auto merge of #45773 - Badel2:dotdoteq, r=petrochenkov
Add error for `...` in expressions Follow-up to #44709 Tracking issue: #28237 * Using `...` in expressions was a warning, now it's an error * The error message suggests using `..` or `..=` instead, and explains the difference * Updated remaining occurrences of `...` to `..=` r? petrochenkov
2 parents aa1b0b2 + b81a7b3 commit d5ff0e6

File tree

8 files changed

+69
-29
lines changed

8 files changed

+69
-29
lines changed

Diff for: src/libcore/slice/mod.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
1717
#![stable(feature = "rust1", since = "1.0.0")]
1818

19-
// FIXME: after next stage0, change RangeInclusive { ... } back to ..=
20-
use ops::RangeInclusive;
21-
2219
// How this module is organized.
2320
//
2421
// The library infrastructure for slices is fairly messy. There's
@@ -1047,32 +1044,32 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
10471044

10481045
#[inline]
10491046
fn get(self, slice: &[T]) -> Option<&[T]> {
1050-
(RangeInclusive { start: 0, end: self.end }).get(slice)
1047+
(0..=self.end).get(slice)
10511048
}
10521049

10531050
#[inline]
10541051
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
1055-
(RangeInclusive { start: 0, end: self.end }).get_mut(slice)
1052+
(0..=self.end).get_mut(slice)
10561053
}
10571054

10581055
#[inline]
10591056
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
1060-
(RangeInclusive { start: 0, end: self.end }).get_unchecked(slice)
1057+
(0..=self.end).get_unchecked(slice)
10611058
}
10621059

10631060
#[inline]
10641061
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
1065-
(RangeInclusive { start: 0, end: self.end }).get_unchecked_mut(slice)
1062+
(0..=self.end).get_unchecked_mut(slice)
10661063
}
10671064

10681065
#[inline]
10691066
fn index(self, slice: &[T]) -> &[T] {
1070-
(RangeInclusive { start: 0, end: self.end }).index(slice)
1067+
(0..=self.end).index(slice)
10711068
}
10721069

10731070
#[inline]
10741071
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
1075-
(RangeInclusive { start: 0, end: self.end }).index_mut(slice)
1072+
(0..=self.end).index_mut(slice)
10761073
}
10771074
}
10781075

Diff for: src/librustc/ty/maps/on_disk_cache.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ impl<'a> CacheDecoder<'a> {
165165
fn find_filemap_prev_bytepos(&self,
166166
prev_bytepos: BytePos)
167167
-> Option<(BytePos, StableFilemapId)> {
168-
for (start, id) in self.prev_filemap_starts.range(BytePos(0) ... prev_bytepos).rev() {
168+
for (start, id) in self.prev_filemap_starts.range(BytePos(0) ..= prev_bytepos).rev() {
169169
return Some((*start, *id))
170170
}
171171

Diff for: src/libsyntax/parse/parser.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -2783,10 +2783,11 @@ impl<'a> Parser<'a> {
27832783
if op.precedence() < min_prec {
27842784
break;
27852785
}
2786-
// Warn about deprecated ... syntax (until SNAP)
2787-
if self.token == token::DotDotDot {
2788-
self.warn_dotdoteq(self.span);
2786+
// Check for deprecated `...` syntax
2787+
if self.token == token::DotDotDot && op == AssocOp::DotDotEq {
2788+
self.err_dotdotdot_syntax(self.span);
27892789
}
2790+
27902791
self.bump();
27912792
if op.is_comparison() {
27922793
self.check_no_chained_comparison(&lhs, &op);
@@ -2819,7 +2820,6 @@ impl<'a> Parser<'a> {
28192820
//
28202821
// We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
28212822
// two variants are handled with `parse_prefix_range_expr` call above.
2822-
// (and `x...y`/`x...` until SNAP)
28232823
let rhs = if self.is_at_start_of_range_notation_rhs() {
28242824
Some(self.parse_assoc_expr_with(op.precedence() + 1,
28252825
LhsExpr::NotYetParsed)?)
@@ -3007,22 +3007,22 @@ impl<'a> Parser<'a> {
30073007
}
30083008
}
30093009

3010-
/// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr` (and `...expr` until SNAP)
3010+
/// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr`
30113011
fn parse_prefix_range_expr(&mut self,
30123012
already_parsed_attrs: Option<ThinVec<Attribute>>)
30133013
-> PResult<'a, P<Expr>> {
3014-
// SNAP remove DotDotDot
3014+
// Check for deprecated `...` syntax
3015+
if self.token == token::DotDotDot {
3016+
self.err_dotdotdot_syntax(self.span);
3017+
}
3018+
30153019
debug_assert!([token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token),
3016-
"parse_prefix_range_expr: token {:?} is not DotDot/DotDotDot/DotDotEq",
3020+
"parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
30173021
self.token);
30183022
let tok = self.token.clone();
30193023
let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
30203024
let lo = self.span;
30213025
let mut hi = self.span;
3022-
// Warn about deprecated ... syntax (until SNAP)
3023-
if tok == token::DotDotDot {
3024-
self.warn_dotdoteq(self.span);
3025-
}
30263026
self.bump();
30273027
let opt_end = if self.is_at_start_of_range_notation_rhs() {
30283028
// RHS must be parsed with more associativity than the dots.
@@ -4332,9 +4332,13 @@ impl<'a> Parser<'a> {
43324332
}).emit();
43334333
}
43344334

4335-
fn warn_dotdoteq(&self, span: Span) {
4336-
self.diagnostic().struct_span_warn(span, {
4337-
"`...` is being replaced by `..=`"
4335+
fn err_dotdotdot_syntax(&self, span: Span) {
4336+
self.diagnostic().struct_span_err(span, {
4337+
"`...` syntax cannot be used in expressions"
4338+
}).help({
4339+
"Use `..` if you need an exclusive range (a < b)"
4340+
}).help({
4341+
"or `..=` if you need an inclusive range (a <= b)"
43384342
}).emit();
43394343
}
43404344

Diff for: src/libsyntax/parse/token.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ impl Token {
222222
BinOp(Or) | OrOr | // closure
223223
BinOp(And) | // reference
224224
AndAnd | // double reference
225+
// DotDotDot is no longer supported, but we need some way to display the error
225226
DotDot | DotDotDot | DotDotEq | // range notation
226-
// SNAP remove DotDotDot
227227
Lt | BinOp(Shl) | // associated path
228228
ModSep | // global path
229229
Pound => true, // expression attributes

Diff for: src/libsyntax/print/pprust.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2213,7 +2213,7 @@ impl<'a> State<'a> {
22132213
if limits == ast::RangeLimits::HalfOpen {
22142214
self.s.word("..")?;
22152215
} else {
2216-
self.s.word("...")?;
2216+
self.s.word("..=")?;
22172217
}
22182218
if let Some(ref e) = *end {
22192219
self.print_expr_maybe_paren(e, fake_prec)?;

Diff for: src/libsyntax/util/parser.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ impl AssocOp {
106106
Token::OrOr => Some(LOr),
107107
Token::DotDot => Some(DotDot),
108108
Token::DotDotEq => Some(DotDotEq),
109-
Token::DotDotDot => Some(DotDotEq), // remove this after SNAP
109+
// DotDotDot is no longer supported, but we need some way to display the error
110+
Token::DotDotDot => Some(DotDotEq),
110111
Token::Colon => Some(Colon),
111112
_ if t.is_keyword(keywords::As) => Some(As),
112113
_ => None

Diff for: src/test/parse-fail/range_inclusive_dotdotdot.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z parse-only -Z continue-parse-after-error
12+
13+
// Make sure that inclusive ranges with `...` syntax don't parse.
14+
15+
#![feature(inclusive_range_syntax, inclusive_range)]
16+
17+
use std::ops::RangeToInclusive;
18+
19+
fn return_range_to() -> RangeToInclusive<i32> {
20+
return ...1; //~ERROR `...` syntax cannot be used in expressions
21+
//~^HELP Use `..` if you need an exclusive range (a < b)
22+
//~^^HELP or `..=` if you need an inclusive range (a <= b)
23+
}
24+
25+
pub fn main() {
26+
let x = ...0; //~ERROR `...` syntax cannot be used in expressions
27+
//~^HELP Use `..` if you need an exclusive range (a < b)
28+
//~^^HELP or `..=` if you need an inclusive range (a <= b)
29+
30+
let x = 5...5; //~ERROR `...` syntax cannot be used in expressions
31+
//~^HELP Use `..` if you need an exclusive range (a < b)
32+
//~^^HELP or `..=` if you need an inclusive range (a <= b)
33+
34+
for _ in 0...1 {} //~ERROR `...` syntax cannot be used in expressions
35+
//~^HELP Use `..` if you need an exclusive range (a < b)
36+
//~^^HELP or `..=` if you need an inclusive range (a <= b)
37+
}
38+

Diff for: src/test/run-pass-fulldeps/issue-35829.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ fn main() {
4141
let raw_byte_string_lit_kind = LitKind::ByteStr(Rc::new(b"#\"two\"#".to_vec()));
4242
assert_eq!(raw_byte_string.node, ExprKind::Lit(P(dummy_spanned(raw_byte_string_lit_kind))));
4343

44-
// check dotdotdot
45-
let closed_range = quote_expr!(&cx, 0 ... 1);
44+
// check dotdoteq
45+
let closed_range = quote_expr!(&cx, 0 ..= 1);
4646
assert_eq!(closed_range.node, ExprKind::Range(
4747
Some(quote_expr!(&cx, 0)),
4848
Some(quote_expr!(&cx, 1)),

0 commit comments

Comments
 (0)