Skip to content

Commit 7523914

Browse files
author
Ulrik Sverdrup
committed
Implement .. syntax for RangeFull as expression
Allows the expression `..` (without either endpoint) in general, can be used in slicing syntax `&expr[..]` where we previously wrote `&expr[]`. The old syntax &expr[] is not yet removed or warned for.
1 parent 3b2ed14 commit 7523914

File tree

6 files changed

+28
-23
lines changed

6 files changed

+28
-23
lines changed

src/libsyntax/parse/parser.rs

+14-19
Original file line numberDiff line numberDiff line change
@@ -2524,16 +2524,7 @@ impl<'a> Parser<'a> {
25242524
let bracket_pos = self.span.lo;
25252525
self.bump();
25262526

2527-
let mut found_dotdot = false;
2528-
if self.token == token::DotDot &&
2529-
self.look_ahead(1, |t| t == &token::CloseDelim(token::Bracket)) {
2530-
// Using expr[..], which is a mistake, should be expr[]
2531-
self.bump();
2532-
self.bump();
2533-
found_dotdot = true;
2534-
}
2535-
2536-
if found_dotdot || self.eat(&token::CloseDelim(token::Bracket)) {
2527+
if self.eat(&token::CloseDelim(token::Bracket)) {
25372528
// No expression, expand to a RangeFull
25382529
// FIXME(#20516) It would be better to use a lang item or
25392530
// something for RangeFull.
@@ -2557,7 +2548,11 @@ impl<'a> Parser<'a> {
25572548
let range = ExprStruct(path, vec![], None);
25582549
let ix = self.mk_expr(bracket_pos, hi, range);
25592550
let index = self.mk_index(e, ix);
2560-
e = self.mk_expr(lo, hi, index)
2551+
e = self.mk_expr(lo, hi, index);
2552+
// Enable after snapshot.
2553+
// self.span_warn(e.span, "deprecated slicing syntax: `[]`");
2554+
// self.span_note(e.span,
2555+
// "use `&expr[..]` to construct a slice of the whole of expr");
25612556
} else {
25622557
let ix = self.parse_expr();
25632558
hi = self.span.hi;
@@ -2566,11 +2561,6 @@ impl<'a> Parser<'a> {
25662561
e = self.mk_expr(lo, hi, index)
25672562
}
25682563

2569-
if found_dotdot {
2570-
self.span_err(e.span, "incorrect slicing expression: `[..]`");
2571-
self.span_note(e.span,
2572-
"use `&expr[]` to construct a slice of the whole of expr");
2573-
}
25742564
}
25752565
_ => return e
25762566
}
@@ -2931,9 +2921,14 @@ impl<'a> Parser<'a> {
29312921
// with the postfix-form 'expr..'
29322922
let lo = self.span.lo;
29332923
self.bump();
2934-
let rhs = self.parse_binops();
2935-
let hi = rhs.span.hi;
2936-
let ex = self.mk_range(None, Some(rhs));
2924+
let opt_end = if self.is_at_start_of_range_notation_rhs() {
2925+
let end = self.parse_binops();
2926+
Some(end)
2927+
} else {
2928+
None
2929+
};
2930+
let hi = self.span.hi;
2931+
let ex = self.mk_range(None, opt_end);
29372932
self.mk_expr(lo, hi, ex)
29382933
}
29392934
_ => {

src/test/compile-fail/slice-1.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// Test slicing expr[..] is an error and gives a helpful error message.
11+
// Test slicing &expr[] is deprecated and gives a helpful error message.
12+
//
13+
// ignore-test
1214

1315
struct Foo;
1416

1517
fn main() {
1618
let x = Foo;
17-
&x[..]; //~ ERROR incorrect slicing expression: `[..]`
18-
//~^ NOTE use `&expr[]` to construct a slice of the whole of expr
19+
&x[]; //~ WARNING deprecated slicing syntax: `[]`
20+
//~^ NOTE use `&expr[..]` to construct a slice of the whole of expr
21+
//~^^ ERROR cannot index a value of type `Foo`
1922
}

src/test/compile-fail/slice-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct Foo;
1414

1515
fn main() {
1616
let x = Foo;
17-
&x[]; //~ ERROR cannot index a value of type `Foo`
17+
&x[..]; //~ ERROR cannot index a value of type `Foo`
1818
&x[Foo..]; //~ ERROR cannot index a value of type `Foo`
1919
&x[..Foo]; //~ ERROR cannot index a value of type `Foo`
2020
&x[Foo..Foo]; //~ ERROR cannot index a value of type `Foo`

src/test/run-pass/range.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn foo() -> int { 42 }
1414

1515
// Test that range syntax works in return statements
1616
fn return_range_to() -> ::std::ops::RangeTo<i32> { return ..1; }
17+
fn return_full_range() -> ::std::ops::RangeFull { return ..; }
1718

1819
pub fn main() {
1920
let mut count = 0;

src/test/run-pass/ranges-precedence.rs

+3
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,8 @@ fn main() {
5555

5656
let x = [1]..[2];
5757
assert!(x == (([1])..([2])));
58+
59+
let y = ..;
60+
assert!(y == (..));
5861
}
5962

src/test/run-pass/slice-2.rs

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn main() {
1414
let x: &[int] = &[1, 2, 3, 4, 5];
1515
let cmp: &[int] = &[1, 2, 3, 4, 5];
1616
assert!(&x[] == cmp);
17+
assert!(&x[..] == cmp);
1718
let cmp: &[int] = &[3, 4, 5];
1819
assert!(&x[2..] == cmp);
1920
let cmp: &[int] = &[1, 2, 3];
@@ -35,6 +36,7 @@ fn main() {
3536
{
3637
let cmp: &mut [int] = &mut [1, 2, 3, 4, 5];
3738
assert!(&mut x[] == cmp);
39+
assert!(&mut x[..] == cmp);
3840
}
3941
{
4042
let cmp: &mut [int] = &mut [3, 4, 5];
@@ -53,6 +55,7 @@ fn main() {
5355
{
5456
let cmp: &mut [int] = &mut [1, 2, 3, 4, 5];
5557
assert!(&mut x[] == cmp);
58+
assert!(&mut x[..] == cmp);
5659
}
5760
{
5861
let cmp: &mut [int] = &mut [3, 4, 5];

0 commit comments

Comments
 (0)