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:
bors 2018-03-15 16:00:40 +00:00
commit 3926453944
39 changed files with 187 additions and 256 deletions

View File

@ -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);
}
}
```

View File

@ -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))]

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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> {

View File

@ -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)]

View File

@ -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")]

View File

@ -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));

View File

@ -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];

View File

@ -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]

View File

@ -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;

View File

@ -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) => {

View File

@ -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"]

View File

@ -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;

View File

@ -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]

View File

@ -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;

View File

@ -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)]

View File

@ -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!

View File

@ -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");

View File

@ -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))
}

View File

@ -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
}

View File

@ -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)]

View File

@ -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

View File

@ -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::*;

View File

@ -23,7 +23,6 @@
#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]
#![feature(inclusive_range_syntax)]
// Change simple index ---------------------------------------------------------
#[cfg(cfail1)]

View File

@ -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

View File

@ -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> {

View File

@ -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
}

View File

@ -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 });

View File

@ -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!(); }
}
}

View File

@ -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};

View File

@ -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;

View File

@ -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
_ => {}
}
}

View File

@ -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`.

View File

@ -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..;

View File

@ -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
| ^

View File

@ -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) => {}
_ => {}
}
}

View File

@ -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