From e844f9509b3b293af94fe39e3813565cceada86e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 7 Feb 2023 16:28:18 -0800 Subject: [PATCH] Eliminate 'half open' terminology from range pattern grammar As described in issue 1329, the Reference's current use of this terminology does not match rustc's use. Following the core::ops trait terminology (as is already done for RangeExpression) results in a clearer grammar. --- src/patterns.md | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/patterns.md b/src/patterns.md index d18f8d0ad..370e1990c 100644 --- a/src/patterns.md +++ b/src/patterns.md @@ -380,16 +380,19 @@ match tuple { > **Syntax**\ > _RangePattern_ :\ ->       _InclusiveRangePattern_\ ->    | _HalfOpenRangePattern_\ +>       _RangeInclusivePattern_\ +>    | _RangeFromPattern_\ +>    | _RangeToInclusivePattern_\ >    | _ObsoleteRangePattern_ > -> _InclusiveRangePattern_ :\ +> _RangeInclusivePattern_ :\ >       _RangePatternBound_ `..=` _RangePatternBound_ > -> _HalfOpenRangePattern_ :\ +> _RangeFromPattern_ :\ >       _RangePatternBound_ `..` ->    | `..=` _RangePatternBound_ +> +> _RangeToInclusivePattern_ :\ +>       `..=` _RangePatternBound_ > > _ObsoleteRangePattern_ :\ >    _RangePatternBound_ `...` _RangePatternBound_ @@ -402,16 +405,13 @@ match tuple { >    | [_PathExpression_] *Range patterns* match scalar values within the range defined by their bounds. -A bound on the left of its sigils is a *lower bound*. +They comprise a *sigil* (one of `..`, `..=`, or `...`) and a bound on one or both sides. +A bound on the left of the sigil is a *lower bound*. A bound on the right is an *upper bound*. -A range pattern may be closed or half-open. - -A range pattern is *closed* if it has both a lower and an upper bound. -The only closed ranged pattern is the inclusive range pattern. -*Inclusive range patterns* match all the values between and including both of its bounds. -It is written as its lower bounds, followed by `..=`, followed by its upper bounds. -The type of it is the type unification of its upper and lower bounds. +A range pattern with both a lower and upper bound will match all values between and including both of its bounds. +It is written as its lower bound, followed by `..=`, followed by its upper bound. +The type of the range pattern is the type unification of its upper and lower bounds. For example, a pattern `'m'..='p'` will match only the values `'m'`, `'n'`, `'o'`, and `'p'`. @@ -419,19 +419,15 @@ The lower bound cannot be greater than the upper bound. That is, in `a..=b`, a ≤ b must be the case. For example, it is an error to have a range pattern `10..=0`. -Range patterns are *half-open* if they have only an upper or lower bound. -They have the same type as their upper or lower bound. - -A half open range with only a lower bound is written as its lower bound followed by `..`. -These range patterns will match on any value greater than or equal to the lower bound. +A range pattern with only a lower bound will match any value greater than or equal to the lower bound. +It is written as its lower bound followed by `..`, and has the same type as its lower bound. For example, `1..` will match 1, 9, or 9001, or 9007199254740991 (if it is of an appropriate size), but not 0, and not negative numbers for signed integers. -The bounds can be literals or paths that point to constant values. -A half open range with only an upper bound is written as `..=` followed by its upper bound. -These range patterns will match on any value less than or equal to the upper bound. +A range pattern with only an upper bound matches any value less than or equal to the upper bound. +It is written as `..=` followed by its upper bound, and has the same type as its upper bound. For example, `..=10` will match 10, 1, 0, and for signed integer types, all negative values. -Half-open range patterns cannot be used as the top-level pattern for subpatterns in [slice patterns](#slice-patterns). +Range patterns with only one bound cannot be used as the top-level pattern for subpatterns in [slice patterns](#slice-patterns). The bounds is written as one of: @@ -529,7 +525,7 @@ The range of values for a `char` type are precisely those ranges containing all Floating point range patterns are deprecated and may be removed in a future Rust release. See [issue #41620](https://github.com/rust-lang/rust/issues/41620) for more information. -> **Edition Differences**: Before the 2021 edition, closed range patterns may also be written using `...` as an alternative to `..=`, with the same meaning. +> **Edition Differences**: Before the 2021 edition, range patterns with both a lower and upper bound may also be written using `...` in place of `..=`, with the same meaning. > **Note**: Although range patterns use the same syntax as [range expressions], there are no exclusive range patterns. > That is, neither `x .. y` nor `.. x` are valid range patterns. @@ -747,7 +743,8 @@ match v[..] { Slice patterns are irrefutable when matching an array as long as each element is irrefutable. When matching a slice, it is irrefutable only in the form with a single `..` [rest pattern](#rest-patterns) or [identifier pattern](#identifier-patterns) with the `..` rest pattern as a subpattern. -Within a slice, a half-open range pattern like `a..` must be enclosed in parentheses, as in `(a..)`, to clarify it is intended to match a single value. +Within a slice, a range pattern without both lower and upper bound must be enclosed in parentheses, as in `(a..)`, to clarify it is intended to match against a single slice element. +A range pattern with both lower and upper bound, like `a..=b`, is not required to be enclosed in parentheses. ## Path patterns