From b5913f2e7695ad247078619bf4c6a6d3dc4dece5 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 28 Jan 2018 03:09:36 +0800 Subject: [PATCH 1/5] Stabilize `inclusive_range` library feature. Stabilize std::ops::RangeInclusive and std::ops::RangeInclusiveTo. --- src/liballoc/lib.rs | 1 - src/liballoc/range.rs | 4 ++-- src/liballoc/string.rs | 8 +++---- src/libcore/iter/range.rs | 12 ++++------ src/libcore/ops/mod.rs | 2 +- src/libcore/ops/range.rs | 24 +++++++------------ src/libcore/slice/mod.rs | 4 ++-- src/libcore/str/mod.rs | 24 +++++-------------- src/libcore/tests/lib.rs | 1 - src/librustc/lib.rs | 1 - src/librustc_mir/lib.rs | 1 - src/librustc_trans/lib.rs | 1 - src/libstd/lib.rs | 1 - src/test/compile-fail/range_inclusive_gate.rs | 21 ---------------- src/test/compile-fail/range_traits-1.rs | 2 -- src/test/compile-fail/range_traits-6.rs | 2 -- src/test/compile-fail/range_traits-7.rs | 2 +- src/test/parse-fail/range_inclusive.rs | 2 +- .../parse-fail/range_inclusive_dotdotdot.rs | 2 +- src/test/parse-fail/range_inclusive_gate.rs | 2 +- src/test/run-pass/range_inclusive.rs | 2 +- 21 files changed, 33 insertions(+), 86 deletions(-) delete mode 100644 src/test/compile-fail/range_inclusive_gate.rs diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3f3067845588a..cbfec5546049c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -98,7 +98,6 @@ #![feature(fundamental)] #![feature(generic_param_attrs)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(iter_rfold)] #![feature(lang_items)] #![feature(needs_allocator)] diff --git a/src/liballoc/range.rs b/src/liballoc/range.rs index f862da0d61e01..b03abc8518087 100644 --- a/src/liballoc/range.rs +++ b/src/liballoc/range.rs @@ -103,7 +103,7 @@ impl RangeArgument for Range { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl RangeArgument for RangeInclusive { fn start(&self) -> Bound<&T> { Included(&self.start) @@ -113,7 +113,7 @@ impl RangeArgument for RangeInclusive { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl RangeArgument for RangeToInclusive { fn start(&self) -> Bound<&T> { Unbounded diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 370fb6b4e890f..185fb61ae9e14 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1876,7 +1876,7 @@ impl ops::Index for String { unsafe { str::from_utf8_unchecked(&self.vec) } } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for String { type Output = str; @@ -1885,7 +1885,7 @@ impl ops::Index> for String { Index::index(&**self, index) } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for String { type Output = str; @@ -1923,14 +1923,14 @@ impl ops::IndexMut for String { unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) } } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for String { #[inline] fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut str { IndexMut::index_mut(&mut **self, index) } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for String { #[inline] fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut str { diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 9a3fd215dcfeb..8d1080bb876ef 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -186,9 +186,7 @@ macro_rules! range_exact_iter_impl { macro_rules! range_incl_exact_iter_impl { ($($t:ty)*) => ($( - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ExactSizeIterator for ops::RangeInclusive<$t> { } )*) } @@ -202,9 +200,7 @@ macro_rules! range_trusted_len_impl { macro_rules! range_incl_trusted_len_impl { ($($t:ty)*) => ($( - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] unsafe impl TrustedLen for ops::RangeInclusive<$t> { } )*) } @@ -328,7 +324,7 @@ impl FusedIterator for ops::RangeFrom {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for ops::RangeFrom {} -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl Iterator for ops::RangeInclusive { type Item = A; @@ -422,7 +418,7 @@ impl Iterator for ops::RangeInclusive { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl DoubleEndedIterator for ops::RangeInclusive { #[inline] fn next_back(&mut self) -> Option { diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs index 70ef4487334c9..234970a81faf7 100644 --- a/src/libcore/ops/mod.rs +++ b/src/libcore/ops/mod.rs @@ -191,7 +191,7 @@ pub use self::index::{Index, IndexMut}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::range::{Range, RangeFrom, RangeFull, RangeTo}; -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] pub use self::range::{RangeInclusive, RangeToInclusive}; #[unstable(feature = "try_trait", issue = "42327")] diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 1d9c0f873b34a..9bdd8094f6189 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -283,7 +283,7 @@ impl> RangeTo { /// # Examples /// /// ``` -/// #![feature(inclusive_range,inclusive_range_syntax)] +/// #![feature(inclusive_range_syntax)] /// /// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); @@ -293,21 +293,17 @@ impl> RangeTo { /// assert_eq!(arr[1..=2], [ 1,2 ]); // RangeInclusive /// ``` #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { /// The lower bound of the range (inclusive). - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] pub start: Idx, /// The upper bound of the range (inclusive). - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] pub end: Idx, } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl fmt::Debug for RangeInclusive { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..={:?}", self.start, self.end) @@ -385,7 +381,7 @@ impl> RangeInclusive { /// The `..=end` syntax is a `RangeToInclusive`: /// /// ``` -/// #![feature(inclusive_range,inclusive_range_syntax)] +/// #![feature(inclusive_range_syntax)] /// assert_eq!((..=5), std::ops::RangeToInclusive{ end: 5 }); /// ``` /// @@ -417,16 +413,14 @@ impl> RangeInclusive { /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[derive(Copy, Clone, PartialEq, Eq, Hash)] -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeToInclusive { /// The upper bound of the range (inclusive) - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] pub end: Idx, } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl fmt::Debug for RangeToInclusive { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "..={:?}", self.end) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 19fe4dd36b683..0f1b7cb8fcc00 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1039,7 +1039,7 @@ impl SliceIndex<[T]> for ops::RangeFull { } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; @@ -1080,7 +1080,7 @@ impl SliceIndex<[T]> for ops::RangeInclusive { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<[T]> for ops::RangeToInclusive { type Output = [T]; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index e225c9522bc06..9cf862bd93625 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1779,9 +1779,7 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for str { type Output = str; @@ -1791,9 +1789,7 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for str { type Output = str; @@ -1803,18 +1799,14 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for str { #[inline] fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut str { index.index_mut(self) } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for str { #[inline] fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut str { @@ -1997,9 +1989,7 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex for ops::RangeInclusive { type Output = str; #[inline] @@ -2042,9 +2032,7 @@ mod traits { - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex for ops::RangeToInclusive { type Output = str; #[inline] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 5bd5bca19c4e5..8f01fbeb30e48 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -23,7 +23,6 @@ #![feature(fmt_internals)] #![feature(iterator_step_by)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![feature(iterator_try_fold)] #![feature(iterator_flatten)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 51882385b2ef2..149ea96b636ce 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -54,7 +54,6 @@ #![feature(fs_read_write)] #![feature(i128)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![cfg_attr(windows, feature(libc))] #![feature(match_default_bindings)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 5510e21978060..31eb203eefe3f 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -29,7 +29,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(fs_read_write)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] -#![feature(inclusive_range)] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 39eb38658fee9..a9334461825c4 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -26,7 +26,6 @@ #![allow(unused_attributes)] #![feature(i128_type)] #![feature(i128)] -#![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![feature(libc)] #![feature(quote)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index eea0e6b675279..c71a562b0d157 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -271,7 +271,6 @@ #![feature(heap_api)] #![feature(i128)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(int_error_internals)] #![feature(integer_atomics)] #![feature(into_cow)] diff --git a/src/test/compile-fail/range_inclusive_gate.rs b/src/test/compile-fail/range_inclusive_gate.rs deleted file mode 100644 index 5b063dc1137c0..0000000000000 --- a/src/test/compile-fail/range_inclusive_gate.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016 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. - -// Make sure that #![feature(inclusive_range)] is required. - -#![feature(inclusive_range_syntax)] -// #![feature(inclusive_range)] - -pub fn main() { - let _: std::ops::RangeInclusive<_> = { use std::intrinsics; 1 } ..= { use std::intrinsics; 2 }; - //~^ ERROR use of unstable library feature 'inclusive_range' - //~| ERROR core_intrinsics - //~| ERROR core_intrinsics -} diff --git a/src/test/compile-fail/range_traits-1.rs b/src/test/compile-fail/range_traits-1.rs index f1ea8b04e5ace..7645dbb1a6dee 100644 --- a/src/test/compile-fail/range_traits-1.rs +++ b/src/test/compile-fail/range_traits-1.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(inclusive_range)] - use std::ops::*; #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] diff --git a/src/test/compile-fail/range_traits-6.rs b/src/test/compile-fail/range_traits-6.rs index 7c62711feaee1..f9510b5061cae 100644 --- a/src/test/compile-fail/range_traits-6.rs +++ b/src/test/compile-fail/range_traits-6.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(inclusive_range)] - use std::ops::*; #[derive(Copy, Clone)] //~ ERROR Copy diff --git a/src/test/compile-fail/range_traits-7.rs b/src/test/compile-fail/range_traits-7.rs index b6fec773a7773..871b55b85cf88 100644 --- a/src/test/compile-fail/range_traits-7.rs +++ b/src/test/compile-fail/range_traits-7.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(rustc_attrs, inclusive_range)] +#![feature(rustc_attrs)] use std::ops::*; diff --git a/src/test/parse-fail/range_inclusive.rs b/src/test/parse-fail/range_inclusive.rs index cc32b9903b5ac..6c6caa1e64975 100644 --- a/src/test/parse-fail/range_inclusive.rs +++ b/src/test/parse-fail/range_inclusive.rs @@ -10,7 +10,7 @@ // Make sure that inclusive ranges with no end point don't parse. -#![feature(inclusive_range_syntax, inclusive_range)] +#![feature(inclusive_range_syntax)] pub fn main() { for _ in 1..= {} //~ERROR inclusive range with no end diff --git a/src/test/parse-fail/range_inclusive_dotdotdot.rs b/src/test/parse-fail/range_inclusive_dotdotdot.rs index a4c36a2f0ba8d..8a24038638b38 100644 --- a/src/test/parse-fail/range_inclusive_dotdotdot.rs +++ b/src/test/parse-fail/range_inclusive_dotdotdot.rs @@ -12,7 +12,7 @@ // Make sure that inclusive ranges with `...` syntax don't parse. -#![feature(inclusive_range_syntax, inclusive_range)] +#![feature(inclusive_range_syntax)] use std::ops::RangeToInclusive; diff --git a/src/test/parse-fail/range_inclusive_gate.rs b/src/test/parse-fail/range_inclusive_gate.rs index 6b6afc504e150..c8c84000e41ef 100644 --- a/src/test/parse-fail/range_inclusive_gate.rs +++ b/src/test/parse-fail/range_inclusive_gate.rs @@ -12,7 +12,7 @@ // Make sure that #![feature(inclusive_range_syntax)] is required. -// #![feature(inclusive_range_syntax, inclusive_range)] +// #![feature(inclusive_range_syntax)] macro_rules! m { () => { for _ in 1..=10 {} } //~ ERROR inclusive range syntax is experimental diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs index 71e11804052db..29947860ff6ae 100644 --- a/src/test/run-pass/range_inclusive.rs +++ b/src/test/run-pass/range_inclusive.rs @@ -10,7 +10,7 @@ // Test inclusive range syntax. -#![feature(inclusive_range_syntax, inclusive_range, iterator_step_by)] +#![feature(inclusive_range_syntax, iterator_step_by)] use std::ops::{RangeInclusive, RangeToInclusive}; From 92d1f8d8e4be62e6f4dc32bc57f9d44f53117ec9 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 28 Jan 2018 03:19:29 +0800 Subject: [PATCH 2/5] Stabilize `inclusive_range_syntax` language feature. Stabilize the syntax `a..=b` and `..=b`. --- .../inclusive-range-syntax.md | 20 ----- src/liballoc/tests/lib.rs | 2 +- src/libcore/lib.rs | 2 +- src/libcore/ops/range.rs | 19 ++--- src/libcore/tests/lib.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc_incremental/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_trans/lib.rs | 2 +- src/libsyntax/diagnostic_list.rs | 4 - src/libsyntax/feature_gate.rs | 10 +-- .../hashes/indexing_expressions.rs | 1 - src/test/parse-fail/range_inclusive.rs | 2 - .../parse-fail/range_inclusive_dotdotdot.rs | 2 - src/test/parse-fail/range_inclusive_gate.rs | 74 ------------------- src/test/run-pass/range_inclusive.rs | 2 +- src/test/run-pass/range_inclusive_gate.rs | 3 +- src/test/ui/impossible_range.rs | 2 - src/test/ui/impossible_range.stderr | 4 +- 19 files changed, 19 insertions(+), 138 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/inclusive-range-syntax.md delete mode 100644 src/test/parse-fail/range_inclusive_gate.rs diff --git a/src/doc/unstable-book/src/language-features/inclusive-range-syntax.md b/src/doc/unstable-book/src/language-features/inclusive-range-syntax.md deleted file mode 100644 index 56f58803150ca..0000000000000 --- a/src/doc/unstable-book/src/language-features/inclusive-range-syntax.md +++ /dev/null @@ -1,20 +0,0 @@ -# `inclusive_range_syntax` - -The tracking issue for this feature is: [#28237] - -[#28237]: https://github.com/rust-lang/rust/issues/28237 - ------------------------- - -To get a range that goes from 0 to 10 and includes the value 10, you -can write `0..=10`: - -```rust -#![feature(inclusive_range_syntax)] - -fn main() { - for i in 0..=10 { - println!("{}", i); - } -} -``` diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 168dbb2ce9b1f..f5deecd47e8e4 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -14,7 +14,7 @@ #![feature(alloc_system)] #![feature(attr_literals)] #![feature(box_syntax)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(collection_placement)] #![feature(const_fn)] #![feature(drain_filter)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a947c9f0b7c13..9aebe2e4ee4b4 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -79,7 +79,7 @@ #![feature(fn_must_use)] #![feature(fundamental)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(intrinsics)] #![feature(iterator_flatten)] #![feature(iterator_repeat_with)] diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 9bdd8094f6189..32aa6508805b0 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -128,7 +128,7 @@ impl> Range { /// The range is empty if either side is incomparable: /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// use std::f32::NAN; /// assert!(!(3.0..5.0).is_empty()); @@ -283,8 +283,6 @@ impl> RangeTo { /// # Examples /// /// ``` -/// #![feature(inclusive_range_syntax)] -/// /// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); /// @@ -316,7 +314,7 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains,inclusive_range_syntax)] + /// #![feature(range_contains)] /// /// assert!(!(3..=5).contains(2)); /// assert!( (3..=5).contains(3)); @@ -337,7 +335,7 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// assert!(!(3..=5).is_empty()); /// assert!(!(3..=3).is_empty()); @@ -347,7 +345,7 @@ impl> RangeInclusive { /// The range is empty if either side is incomparable: /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// use std::f32::NAN; /// assert!(!(3.0..=5.0).is_empty()); @@ -358,7 +356,7 @@ impl> RangeInclusive { /// This method returns `true` after iteration has finished: /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// let mut r = 3..=5; /// for _ in r.by_ref() {} @@ -381,7 +379,6 @@ impl> RangeInclusive { /// The `..=end` syntax is a `RangeToInclusive`: /// /// ``` -/// #![feature(inclusive_range_syntax)] /// assert_eq!((..=5), std::ops::RangeToInclusive{ end: 5 }); /// ``` /// @@ -389,8 +386,6 @@ impl> RangeInclusive { /// `for` loop directly. This won't compile: /// /// ```compile_fail,E0277 -/// #![feature(inclusive_range_syntax)] -/// /// // error[E0277]: the trait bound `std::ops::RangeToInclusive<{integer}>: /// // std::iter::Iterator` is not satisfied /// for i in ..=5 { @@ -402,8 +397,6 @@ impl> RangeInclusive { /// array elements up to and including the index indicated by `end`. /// /// ``` -/// #![feature(inclusive_range_syntax)] -/// /// let arr = [0, 1, 2, 3]; /// assert_eq!(arr[ ..=2], [0,1,2 ]); // RangeToInclusive /// assert_eq!(arr[1..=2], [ 1,2 ]); @@ -434,7 +427,7 @@ impl> RangeToInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains,inclusive_range_syntax)] + /// #![feature(range_contains)] /// /// assert!( (..=5).contains(-1_000_000_000)); /// assert!( (..=5).contains(5)); diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8f01fbeb30e48..85787f38f0605 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -23,7 +23,7 @@ #![feature(fmt_internals)] #![feature(iterator_step_by)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(iterator_try_fold)] #![feature(iterator_flatten)] #![feature(conservative_impl_trait)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 149ea96b636ce..ff2e8ea79d3be 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -54,7 +54,7 @@ #![feature(fs_read_write)] #![feature(i128)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![cfg_attr(windows, feature(libc))] #![feature(match_default_bindings)] #![feature(macro_lifetime_matcher)] diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 65fbd9d0bf8f1..d7ccf9d5562e6 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -18,7 +18,7 @@ #![feature(conservative_impl_trait)] #![feature(fs_read_write)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(specialization)] extern crate graphviz; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 31eb203eefe3f..ad7a5c94022fe 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -28,7 +28,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(dyn_trait)] #![feature(fs_read_write)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index a9334461825c4..f2b76eb57d662 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -26,7 +26,7 @@ #![allow(unused_attributes)] #![feature(i128_type)] #![feature(i128)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(libc)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 549ef88afcc63..1f87c1b94c50d 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -218,8 +218,6 @@ An inclusive range was used with no end. Erroneous code example: ```compile_fail,E0586 -#![feature(inclusive_range_syntax)] - fn main() { let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1]; let x = &tmp[1..=]; // error: inclusive range was used with no end @@ -239,8 +237,6 @@ fn main() { Or put an end to your inclusive range: ``` -#![feature(inclusive_range_syntax)] - fn main() { let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1]; let x = &tmp[1..=3]; // ok! diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 91364fe6ed48e..a415117b599be 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -268,9 +268,6 @@ declare_features! ( // rustc internal (active, abi_vectorcall, "1.7.0", None, None), - // a..=b and ..=b - (active, inclusive_range_syntax, "1.7.0", Some(28237), None), - // X..Y patterns (active, exclusive_range_pattern, "1.11.0", Some(37854), None), @@ -554,6 +551,8 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), + // a..=b and ..=b + (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1592,11 +1591,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, type_ascription, e.span, "type ascription is experimental"); } - ast::ExprKind::Range(_, _, ast::RangeLimits::Closed) => { - gate_feature_post!(&self, inclusive_range_syntax, - e.span, - "inclusive range syntax is experimental"); - } ast::ExprKind::InPlace(..) => { gate_feature_post!(&self, placement_in_syntax, e.span, EXPLAIN_PLACEMENT_IN); } diff --git a/src/test/incremental/hashes/indexing_expressions.rs b/src/test/incremental/hashes/indexing_expressions.rs index e66e239b33c95..fb63aa857aa32 100644 --- a/src/test/incremental/hashes/indexing_expressions.rs +++ b/src/test/incremental/hashes/indexing_expressions.rs @@ -23,7 +23,6 @@ #![allow(warnings)] #![feature(rustc_attrs)] #![crate_type="rlib"] -#![feature(inclusive_range_syntax)] // Change simple index --------------------------------------------------------- #[cfg(cfail1)] diff --git a/src/test/parse-fail/range_inclusive.rs b/src/test/parse-fail/range_inclusive.rs index 6c6caa1e64975..2aa7d6d6cd793 100644 --- a/src/test/parse-fail/range_inclusive.rs +++ b/src/test/parse-fail/range_inclusive.rs @@ -10,8 +10,6 @@ // Make sure that inclusive ranges with no end point don't parse. -#![feature(inclusive_range_syntax)] - pub fn main() { for _ in 1..= {} //~ERROR inclusive range with no end //~^HELP bounded at the end diff --git a/src/test/parse-fail/range_inclusive_dotdotdot.rs b/src/test/parse-fail/range_inclusive_dotdotdot.rs index 8a24038638b38..fa6474717d3f0 100644 --- a/src/test/parse-fail/range_inclusive_dotdotdot.rs +++ b/src/test/parse-fail/range_inclusive_dotdotdot.rs @@ -12,8 +12,6 @@ // Make sure that inclusive ranges with `...` syntax don't parse. -#![feature(inclusive_range_syntax)] - use std::ops::RangeToInclusive; fn return_range_to() -> RangeToInclusive { diff --git a/src/test/parse-fail/range_inclusive_gate.rs b/src/test/parse-fail/range_inclusive_gate.rs deleted file mode 100644 index c8c84000e41ef..0000000000000 --- a/src/test/parse-fail/range_inclusive_gate.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2016 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. - -// gate-test-inclusive_range_syntax - -// Make sure that #![feature(inclusive_range_syntax)] is required. - -// #![feature(inclusive_range_syntax)] - -macro_rules! m { - () => { for _ in 1..=10 {} } //~ ERROR inclusive range syntax is experimental -} - -#[cfg(nope)] -fn f() {} -#[cfg(not(nope))] -fn f() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental -} - -#[cfg(nope)] -macro_rules! n { () => {} } -#[cfg(not(nope))] -macro_rules! n { - () => { for _ in 1..=10 {} } //~ ERROR inclusive range syntax is experimental -} - -macro_rules! o { - () => {{ - #[cfg(nope)] - fn g() {} - #[cfg(not(nope))] - fn g() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental - } - - g(); - }} -} - -#[cfg(nope)] -macro_rules! p { () => {} } -#[cfg(not(nope))] -macro_rules! p { - () => {{ - #[cfg(nope)] - fn h() {} - #[cfg(not(nope))] - fn h() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental - } - - h(); - }} -} - -pub fn main() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental - for _ in ..=10 {} //~ ERROR inclusive range syntax is experimental - - f(); // not allowed in cfg'ed functions - - m!(); // not allowed in macros - n!(); // not allowed in cfg'ed macros - o!(); // not allowed in macros that output cfgs - p!(); // not allowed in cfg'ed macros that output cfgs -} diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs index 29947860ff6ae..5d46bfab8878e 100644 --- a/src/test/run-pass/range_inclusive.rs +++ b/src/test/run-pass/range_inclusive.rs @@ -10,7 +10,7 @@ // Test inclusive range syntax. -#![feature(inclusive_range_syntax, iterator_step_by)] +#![feature(iterator_step_by)] use std::ops::{RangeInclusive, RangeToInclusive}; diff --git a/src/test/run-pass/range_inclusive_gate.rs b/src/test/run-pass/range_inclusive_gate.rs index 570087aedbbaa..6c2731fa5a9bb 100644 --- a/src/test/run-pass/range_inclusive_gate.rs +++ b/src/test/run-pass/range_inclusive_gate.rs @@ -9,8 +9,7 @@ // except according to those terms. // Test that you only need the syntax gate if you don't mention the structs. - -#![feature(inclusive_range_syntax)] +// (Obsoleted since both features are stabilized) fn main() { let mut count = 0; diff --git a/src/test/ui/impossible_range.rs b/src/test/ui/impossible_range.rs index 5c72c506e6bf0..073ed867bdb84 100644 --- a/src/test/ui/impossible_range.rs +++ b/src/test/ui/impossible_range.rs @@ -10,8 +10,6 @@ // Make sure that invalid ranges generate an error during HIR lowering, not an ICE -#![feature(inclusive_range_syntax)] - pub fn main() { ..; 0..; diff --git a/src/test/ui/impossible_range.stderr b/src/test/ui/impossible_range.stderr index d941b522defe8..cfeaa53a6bb18 100644 --- a/src/test/ui/impossible_range.stderr +++ b/src/test/ui/impossible_range.stderr @@ -1,5 +1,5 @@ error[E0586]: inclusive range with no end - --> $DIR/impossible_range.rs:20:8 + --> $DIR/impossible_range.rs:18:8 | LL | ..=; //~ERROR inclusive range with no end | ^ @@ -7,7 +7,7 @@ LL | ..=; //~ERROR inclusive range with no end = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/impossible_range.rs:27:9 + --> $DIR/impossible_range.rs:25:9 | LL | 0..=; //~ERROR inclusive range with no end | ^ From a4d80336c96d7f47b0ef025fa141a9c96abcafbd Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 28 Jan 2018 03:29:00 +0800 Subject: [PATCH 3/5] Stabilize `dotdoteq_in_patterns` language feature. Stabilize `match 2 { 1..=3 => {} }`. --- src/libsyntax/feature_gate.rs | 11 +++-------- src/test/run-pass/inc-range-pat.rs | 2 -- src/test/ui/feature-gate-dotdoteq_in_patterns.rs | 16 ---------------- .../ui/feature-gate-dotdoteq_in_patterns.stderr | 11 ----------- 4 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 src/test/ui/feature-gate-dotdoteq_in_patterns.rs delete mode 100644 src/test/ui/feature-gate-dotdoteq_in_patterns.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a415117b599be..51fa14895993d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -26,7 +26,7 @@ use self::AttributeType::*; use self::AttributeGate::*; use abi::Abi; -use ast::{self, NodeId, PatKind, RangeEnd, RangeSyntax}; +use ast::{self, NodeId, PatKind, RangeEnd}; use attr; use epoch::Epoch; use codemap::Spanned; @@ -399,9 +399,6 @@ declare_features! ( // allow `'_` placeholder lifetimes (active, underscore_lifetimes, "1.22.0", Some(44524), None), - // allow `..=` in patterns (RFC 1192) - (active, dotdoteq_in_patterns, "1.22.0", Some(28237), None), - // Default match binding modes (RFC 2005) (active, match_default_bindings, "1.22.0", Some(42640), None), @@ -553,6 +550,8 @@ declare_features! ( (accepted, use_nested_groups, "1.25.0", Some(44494), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), + // allow `..=` in patterns (RFC 1192) + (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1652,10 +1651,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, exclusive_range_pattern, pattern.span, "exclusive range pattern syntax is experimental"); } - PatKind::Range(_, _, RangeEnd::Included(RangeSyntax::DotDotEq)) => { - gate_feature_post!(&self, dotdoteq_in_patterns, pattern.span, - "`..=` syntax in patterns is experimental"); - } PatKind::Paren(..) => { gate_feature_post!(&self, pattern_parentheses, pattern.span, "parentheses in patterns are unstable"); diff --git a/src/test/run-pass/inc-range-pat.rs b/src/test/run-pass/inc-range-pat.rs index 5faf36eddaf06..237b41b6128cf 100644 --- a/src/test/run-pass/inc-range-pat.rs +++ b/src/test/run-pass/inc-range-pat.rs @@ -9,8 +9,6 @@ // except according to those terms. // Test old and new syntax for inclusive range patterns. -#![feature(dotdoteq_in_patterns)] - fn main() { assert!(match 42 { 0 ... 100 => true, _ => false }); diff --git a/src/test/ui/feature-gate-dotdoteq_in_patterns.rs b/src/test/ui/feature-gate-dotdoteq_in_patterns.rs deleted file mode 100644 index 1fb139bf07f41..0000000000000 --- a/src/test/ui/feature-gate-dotdoteq_in_patterns.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2014 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. - -pub fn main() { - match 22 { - 0 ..= 3 => {} //~ ERROR `..=` syntax in patterns is experimental - _ => {} - } -} diff --git a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr b/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr deleted file mode 100644 index 67f15be9d0846..0000000000000 --- a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: `..=` syntax in patterns is experimental (see issue #28237) - --> $DIR/feature-gate-dotdoteq_in_patterns.rs:13:9 - | -LL | 0 ..= 3 => {} //~ ERROR `..=` syntax in patterns is experimental - | ^^^^^^^ - | - = help: add #![feature(dotdoteq_in_patterns)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. From 6399d16cfde37b06f6b82cdafa623e36385d7252 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 3 Mar 2018 06:05:54 +0800 Subject: [PATCH 4/5] Disallow &a..=b and box a..=b in pattern. They are disallowed because they have different precedence than expressions. I assume parenthesis in pattern will be soon stabilized and thus write that as suggestion directly. --- src/librustc/hir/print.rs | 20 ++++++++++ src/libsyntax/parse/parser.rs | 29 +++++++++++++- .../range-inclusive-pattern-precedence.rs | 32 ++++++++++++++++ .../ui/range-inclusive-pattern-precedence.rs | 38 +++++++++++++++++++ .../range-inclusive-pattern-precedence.stderr | 14 +++++++ 5 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/range-inclusive-pattern-precedence.rs create mode 100644 src/test/ui/range-inclusive-pattern-precedence.rs create mode 100644 src/test/ui/range-inclusive-pattern-precedence.stderr diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index d91aa3a385193..9e755f366a7de 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1810,15 +1810,35 @@ impl<'a> State<'a> { self.pclose()?; } PatKind::Box(ref inner) => { + let is_range_inner = match inner.node { + PatKind::Range(..) => true, + _ => false, + }; self.s.word("box ")?; + if is_range_inner { + self.popen()?; + } self.print_pat(&inner)?; + if is_range_inner { + self.pclose()?; + } } PatKind::Ref(ref inner, mutbl) => { + let is_range_inner = match inner.node { + PatKind::Range(..) => true, + _ => false, + }; self.s.word("&")?; if mutbl == hir::MutMutable { self.s.word("mut ")?; } + if is_range_inner { + self.popen()?; + } self.print_pat(&inner)?; + if is_range_inner { + self.pclose()?; + } } PatKind::Lit(ref e) => self.print_expr(&e)?, PatKind::Range(ref begin, ref end, ref end_kind) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bd0ca0e670487..e3812ce159a9a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3804,6 +3804,12 @@ impl<'a> Parser<'a> { /// Parse a pattern. pub fn parse_pat(&mut self) -> PResult<'a, P> { + self.parse_pat_with_range_pat(true) + } + + /// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are + /// allowed. + fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P> { maybe_whole!(self, NtPat, |x| x); let lo = self.span; @@ -3824,7 +3830,7 @@ impl<'a> Parser<'a> { err.span_label(self.span, "unexpected lifetime"); return Err(err); } - let subpat = self.parse_pat()?; + let subpat = self.parse_pat_with_range_pat(false)?; pat = PatKind::Ref(subpat, mutbl); } token::OpenDelim(token::Paren) => { @@ -3863,7 +3869,7 @@ impl<'a> Parser<'a> { pat = self.parse_pat_ident(BindingMode::ByRef(mutbl))?; } else if self.eat_keyword(keywords::Box) { // Parse box pat - let subpat = self.parse_pat()?; + let subpat = self.parse_pat_with_range_pat(false)?; pat = PatKind::Box(subpat); } else if self.token.is_ident() && !self.token.is_reserved_ident() && self.parse_as_ident() { @@ -3968,6 +3974,25 @@ impl<'a> Parser<'a> { let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID }; let pat = self.maybe_recover_from_bad_qpath(pat, true)?; + if !allow_range_pat { + match pat.node { + PatKind::Range(_, _, RangeEnd::Included(RangeSyntax::DotDotDot)) => {} + PatKind::Range(..) => { + let mut err = self.struct_span_err( + pat.span, + "the range pattern here has ambiguous interpretation", + ); + err.span_suggestion( + pat.span, + "add parentheses to clarify the precedence", + format!("({})", pprust::pat_to_string(&pat)), + ); + return Err(err); + } + _ => {} + } + } + Ok(P(pat)) } diff --git a/src/test/run-pass/range-inclusive-pattern-precedence.rs b/src/test/run-pass/range-inclusive-pattern-precedence.rs new file mode 100644 index 0000000000000..5e491d48bcf46 --- /dev/null +++ b/src/test/run-pass/range-inclusive-pattern-precedence.rs @@ -0,0 +1,32 @@ +// Copyright 2018 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. + +#![feature(box_patterns, pattern_parentheses)] + +const VALUE: usize = 21; + +pub fn main() { + match &18 { + &(18..=18) => {} + _ => { unreachable!(); } + } + match &21 { + &(VALUE..=VALUE) => {} + _ => { unreachable!(); } + } + match Box::new(18) { + box (18..=18) => {} + _ => { unreachable!(); } + } + match Box::new(21) { + box (VALUE..=VALUE) => {} + _ => { unreachable!(); } + } +} diff --git a/src/test/ui/range-inclusive-pattern-precedence.rs b/src/test/ui/range-inclusive-pattern-precedence.rs new file mode 100644 index 0000000000000..67a0f79ca6b82 --- /dev/null +++ b/src/test/ui/range-inclusive-pattern-precedence.rs @@ -0,0 +1,38 @@ +// Copyright 2018 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. + +// In expression, `&a..=b` is treated as `(&a)..=(b)` and `box a..=b` is +// `(box a)..=(b)`. In a pattern, however, `&a..=b` means `&(a..=b)`. This may +// lead to confusion. +// +// We are going to disallow `&a..=b` and `box a..=b` in a pattern. However, the +// older ... syntax is still allowed as a stability guarantee. + +#![feature(box_patterns)] + +pub fn main() { + match &12 { + &0...9 => {} + &10..=15 => {} + //~^ ERROR the range pattern here has ambiguous interpretation + //~^^ HELP add parentheses to clarify the precedence + &(16..=20) => {} + _ => {} + } + + match Box::new(12) { + box 0...9 => {} + box 10..=15 => {} + //~^ ERROR the range pattern here has ambiguous interpretation + //~^^ HELP add parentheses to clarify the precedence + box (16..=20) => {} + _ => {} + } +} diff --git a/src/test/ui/range-inclusive-pattern-precedence.stderr b/src/test/ui/range-inclusive-pattern-precedence.stderr new file mode 100644 index 0000000000000..99e0d739036b0 --- /dev/null +++ b/src/test/ui/range-inclusive-pattern-precedence.stderr @@ -0,0 +1,14 @@ +error: the range pattern here has ambiguous interpretation + --> $DIR/range-inclusive-pattern-precedence.rs:23:10 + | +LL | &10..=15 => {} + | ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)` + +error: the range pattern here has ambiguous interpretation + --> $DIR/range-inclusive-pattern-precedence.rs:32:13 + | +LL | box 10..=15 => {} + | ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)` + +error: aborting due to 2 previous errors + From 939cfa251aeb34b4b1a11396af1a3396792c708d Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 15 Mar 2018 02:50:55 +0800 Subject: [PATCH 5/5] Keep the fields of RangeInclusive unstable. --- src/liballoc/lib.rs | 1 + src/liballoc/tests/lib.rs | 1 + src/libcore/ops/range.rs | 6 ++++-- src/libcore/tests/lib.rs | 1 + src/librustc/lib.rs | 1 + src/librustc_mir/lib.rs | 1 + src/librustc_trans/lib.rs | 1 + 7 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index cbfec5546049c..fb7f114ba1a47 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -123,6 +123,7 @@ #![feature(on_unimplemented)] #![feature(exact_chunks)] #![feature(pointer_methods)] +#![feature(inclusive_range_fields)] #![cfg_attr(not(test), feature(fn_traits, placement_new_protocol, swap_with_slice, i128))] #![cfg_attr(test, feature(test, box_heap))] diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index f5deecd47e8e4..4fea2375558d6 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -29,6 +29,7 @@ #![feature(unboxed_closures)] #![feature(unicode)] #![feature(exact_chunks)] +#![feature(inclusive_range_fields)] extern crate alloc_system; extern crate std_unicode; diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 32aa6508805b0..be51f5239b0c6 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -283,6 +283,8 @@ impl> RangeTo { /// # Examples /// /// ``` +/// #![feature(inclusive_range_fields)] +/// /// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); /// @@ -294,10 +296,10 @@ impl> RangeTo { #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { /// The lower bound of the range (inclusive). - #[stable(feature = "inclusive_range", since = "1.26.0")] + #[unstable(feature = "inclusive_range_fields", issue = "49022")] pub start: Idx, /// The upper bound of the range (inclusive). - #[stable(feature = "inclusive_range", since = "1.26.0")] + #[unstable(feature = "inclusive_range_fields", issue = "49022")] pub end: Idx, } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 85787f38f0605..e53964b5769bd 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -47,6 +47,7 @@ #![feature(exact_chunks)] #![feature(atomic_nand)] #![feature(reverse_bits)] +#![feature(inclusive_range_fields)] extern crate core; extern crate test; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index ff2e8ea79d3be..77259f156e5e2 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -75,6 +75,7 @@ #![feature(trusted_len)] #![feature(catch_expr)] #![feature(test)] +#![feature(inclusive_range_fields)] #![recursion_limit="512"] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index ad7a5c94022fe..ff35412ea5bab 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -39,6 +39,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(nonzero)] #![feature(underscore_lifetimes)] #![cfg_attr(stage0, feature(never_type))] +#![feature(inclusive_range_fields)] extern crate arena; #[macro_use] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index f2b76eb57d662..9b09dbf52761a 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -33,6 +33,7 @@ #![feature(slice_patterns)] #![feature(conservative_impl_trait)] #![feature(optin_builtin_traits)] +#![feature(inclusive_range_fields)] use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol;