Auto merge of #47813 - kennytm:stable-incl-range, r=nrc
Stabilize inclusive range (`..=`) Stabilize the followings: * `inclusive_range` — The `std::ops::RangeInclusive` and `std::ops::RangeInclusiveTo` types, except its fields (tracked by #49022 separately). * `inclusive_range_syntax` — The `a..=b` and `..=b` expression syntax * `dotdoteq_in_patterns` — Using `a..=b` in a pattern cc #28237 r? @rust-lang/lang
This commit is contained in:
commit
3926453944
|
@ -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);
|
||||
}
|
||||
}
|
||||
```
|
|
@ -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)]
|
||||
|
@ -125,6 +124,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))]
|
||||
|
|
|
@ -103,7 +103,7 @@ impl<T> RangeArgument<T> for Range<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
impl<T> RangeArgument<T> for RangeInclusive<T> {
|
||||
fn start(&self) -> Bound<&T> {
|
||||
Included(&self.start)
|
||||
|
@ -113,7 +113,7 @@ impl<T> RangeArgument<T> for RangeInclusive<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
impl<T> RangeArgument<T> for RangeToInclusive<T> {
|
||||
fn start(&self) -> Bound<&T> {
|
||||
Unbounded
|
||||
|
|
|
@ -1950,7 +1950,7 @@ impl ops::Index<ops::RangeFull> 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<ops::RangeInclusive<usize>> for String {
|
||||
type Output = str;
|
||||
|
||||
|
@ -1959,7 +1959,7 @@ impl ops::Index<ops::RangeInclusive<usize>> 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<ops::RangeToInclusive<usize>> for String {
|
||||
type Output = str;
|
||||
|
||||
|
@ -1997,14 +1997,14 @@ impl ops::IndexMut<ops::RangeFull> 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<ops::RangeInclusive<usize>> for String {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &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<ops::RangeToInclusive<usize>> for String {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
|
||||
|
|
|
@ -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)]
|
||||
|
@ -30,6 +30,7 @@
|
|||
#![feature(unboxed_closures)]
|
||||
#![feature(unicode)]
|
||||
#![feature(exact_chunks)]
|
||||
#![feature(inclusive_range_fields)]
|
||||
|
||||
extern crate alloc_system;
|
||||
extern crate std_unicode;
|
||||
|
|
|
@ -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<A: Step> FusedIterator for ops::RangeFrom<A> {}
|
|||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<A: Step> TrustedLen for ops::RangeFrom<A> {}
|
||||
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
impl<A: Step> Iterator for ops::RangeInclusive<A> {
|
||||
type Item = A;
|
||||
|
||||
|
@ -422,7 +418,7 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -128,7 +128,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
|
|||
/// 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,7 +283,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inclusive_range,inclusive_range_syntax)]
|
||||
/// #![feature(inclusive_range_fields)]
|
||||
///
|
||||
/// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 });
|
||||
/// assert_eq!(3 + 4 + 5, (3..=5).sum());
|
||||
|
@ -293,21 +293,17 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
|
|||
/// 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<Idx> {
|
||||
/// The lower bound of the range (inclusive).
|
||||
#[unstable(feature = "inclusive_range",
|
||||
reason = "recently added, follows RFC",
|
||||
issue = "28237")]
|
||||
#[unstable(feature = "inclusive_range_fields", issue = "49022")]
|
||||
pub start: Idx,
|
||||
/// The upper bound of the range (inclusive).
|
||||
#[unstable(feature = "inclusive_range",
|
||||
reason = "recently added, follows RFC",
|
||||
issue = "28237")]
|
||||
#[unstable(feature = "inclusive_range_fields", issue = "49022")]
|
||||
pub end: Idx,
|
||||
}
|
||||
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{:?}..={:?}", self.start, self.end)
|
||||
|
@ -320,7 +316,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains,inclusive_range_syntax)]
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// assert!(!(3..=5).contains(2));
|
||||
/// assert!( (3..=5).contains(3));
|
||||
|
@ -341,7 +337,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_is_empty,inclusive_range_syntax)]
|
||||
/// #![feature(range_is_empty)]
|
||||
///
|
||||
/// assert!(!(3..=5).is_empty());
|
||||
/// assert!(!(3..=3).is_empty());
|
||||
|
@ -351,7 +347,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// 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());
|
||||
|
@ -362,7 +358,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// 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() {}
|
||||
|
@ -385,7 +381,6 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// The `..=end` syntax is a `RangeToInclusive`:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inclusive_range,inclusive_range_syntax)]
|
||||
/// assert_eq!((..=5), std::ops::RangeToInclusive{ end: 5 });
|
||||
/// ```
|
||||
///
|
||||
|
@ -393,8 +388,6 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// `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 {
|
||||
|
@ -406,8 +399,6 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// 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 ]);
|
||||
|
@ -417,16 +408,14 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
/// [`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<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<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "..={:?}", self.end)
|
||||
|
@ -440,7 +429,7 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains,inclusive_range_syntax)]
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// assert!( (..=5).contains(-1_000_000_000));
|
||||
/// assert!( (..=5).contains(5));
|
||||
|
|
|
@ -1039,7 +1039,7 @@ impl<T> 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<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
|
||||
type Output = [T];
|
||||
|
||||
|
@ -1080,7 +1080,7 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
|
||||
type Output = [T];
|
||||
|
||||
|
|
|
@ -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<ops::RangeInclusive<usize>> 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<ops::RangeToInclusive<usize>> 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<ops::RangeInclusive<usize>> for str {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &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<ops::RangeToInclusive<usize>> for str {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &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<str> for ops::RangeInclusive<usize> {
|
||||
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<str> for ops::RangeToInclusive<usize> {
|
||||
type Output = str;
|
||||
#[inline]
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
#![feature(fmt_internals)]
|
||||
#![feature(iterator_step_by)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(inclusive_range)]
|
||||
#![feature(inclusive_range_syntax)]
|
||||
#![cfg_attr(stage0, feature(inclusive_range_syntax))]
|
||||
#![feature(iterator_try_fold)]
|
||||
#![feature(iterator_flatten)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
|
@ -48,6 +47,7 @@
|
|||
#![feature(exact_chunks)]
|
||||
#![feature(atomic_nand)]
|
||||
#![feature(reverse_bits)]
|
||||
#![feature(inclusive_range_fields)]
|
||||
|
||||
extern crate core;
|
||||
extern crate test;
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -54,8 +54,7 @@
|
|||
#![feature(fs_read_write)]
|
||||
#![feature(i128)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(inclusive_range)]
|
||||
#![feature(inclusive_range_syntax)]
|
||||
#![cfg_attr(stage0, feature(inclusive_range_syntax))]
|
||||
#![cfg_attr(windows, feature(libc))]
|
||||
#![feature(match_default_bindings)]
|
||||
#![feature(macro_lifetime_matcher)]
|
||||
|
@ -76,6 +75,7 @@
|
|||
#![feature(trusted_len)]
|
||||
#![feature(catch_expr)]
|
||||
#![feature(test)]
|
||||
#![feature(inclusive_range_fields)]
|
||||
|
||||
#![recursion_limit="512"]
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -28,8 +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)]
|
||||
#![feature(inclusive_range)]
|
||||
#![cfg_attr(stage0, feature(inclusive_range_syntax))]
|
||||
#![feature(macro_vis_matcher)]
|
||||
#![feature(match_default_bindings)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
@ -40,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]
|
||||
|
|
|
@ -26,14 +26,14 @@
|
|||
#![allow(unused_attributes)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(i128)]
|
||||
#![feature(inclusive_range)]
|
||||
#![feature(inclusive_range_syntax)]
|
||||
#![cfg_attr(stage0, feature(inclusive_range_syntax))]
|
||||
#![feature(libc)]
|
||||
#![feature(quote)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![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;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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;
|
||||
|
@ -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),
|
||||
|
||||
|
@ -402,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),
|
||||
|
||||
|
@ -554,6 +548,10 @@ 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),
|
||||
// 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
|
||||
|
@ -1592,11 +1590,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);
|
||||
}
|
||||
|
@ -1658,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");
|
||||
|
|
|
@ -3804,6 +3804,12 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parse a pattern.
|
||||
pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||
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<Pat>> {
|
||||
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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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
|
||||
}
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![crate_type="rlib"]
|
||||
#![feature(inclusive_range_syntax)]
|
||||
|
||||
// Change simple index ---------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
// Make sure that inclusive ranges with no end point don't parse.
|
||||
|
||||
#![feature(inclusive_range_syntax, inclusive_range)]
|
||||
|
||||
pub fn main() {
|
||||
for _ in 1..= {} //~ERROR inclusive range with no end
|
||||
//~^HELP bounded at the end
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
// 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<i32> {
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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, inclusive_range)]
|
||||
|
||||
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
|
||||
}
|
|
@ -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 });
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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!(); }
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// Test inclusive range syntax.
|
||||
|
||||
#![feature(inclusive_range_syntax, inclusive_range, iterator_step_by)]
|
||||
#![feature(iterator_step_by)]
|
||||
|
||||
use std::ops::{RangeInclusive, RangeToInclusive};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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
|
||||
_ => {}
|
||||
}
|
||||
}
|
|
@ -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`.
|
|
@ -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..;
|
||||
|
|
|
@ -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
|
||||
| ^
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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) => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue