diff --git a/src/patterns.md b/src/patterns.md
index 88940641c..b9c1b9690 100644
--- a/src/patterns.md
+++ b/src/patterns.md
@@ -2,10 +2,15 @@
> **Syntax**\
> _Pattern_ :\
+> _PatternWithoutRange_\
+> | [_RangePattern_]
+>
+> _PatternWithoutRange_ :\
> [_LiteralPattern_]\
> | [_IdentifierPattern_]\
> | [_WildcardPattern_]\
-> | [_RangePattern_]\
+> | [_RestPattern_]\
+> | [_ObsoleteRangePattern_]\
> | [_ReferencePattern_]\
> | [_StructPattern_]\
> | [_TupleStructPattern_]\
@@ -248,6 +253,9 @@ copying or moving what was matched.
[Path patterns](#path-patterns) take precedence over identifier patterns. It is an error
if `ref` or `ref mut` is specified and the identifier shadows a constant.
+Identifier patterns are irrefutable if the `@` subpattern is irrefutable or
+the subpattern is not specified.
+
### Binding modes
To service better ergonomics, patterns operate in different *binding modes* in
@@ -317,12 +325,67 @@ if let Some(_) = x {}
The wildcard pattern is always irrefutable.
+## Rest patterns
+
+> **Syntax**\
+> _RestPattern_ :\
+> `..`
+
+The _rest pattern_ (the `..` token) acts as a variable-length pattern which
+matches zero or more elements that haven't been matched already before and
+after. It may only be used in [tuple](#tuple-patterns), [tuple
+struct](#tuple-struct-patterns), and [slice](#slice-patterns) patterns, and
+may only appear once as one of the elements in those patterns. It is also
+allowed in an [identifier pattern](#identifier-patterns) for [slice
+patterns](#slice-patterns) only.
+
+The rest pattern is always irrefutable.
+
+Examples:
+
+```rust
+# let words = vec!["a", "b", "c"];
+# let slice = &words[..];
+match slice {
+ [] => println!("slice is empty"),
+ [one] => println!("single element {}", one),
+ [head, tail @ ..] => println!("head={} tail={:?}", head, tail),
+}
+
+match slice {
+ // Ignore everything but the last element, which must be "!".
+ [.., "!"] => println!("!!!"),
+
+ // `start` is a slice of everything except the last element, which must be "z".
+ [start @ .., "z"] => println!("starts with: {:?}", start),
+
+ // `end` is a slice of everything but the first element, which must be "a".
+ ["a", end @ ..] => println!("ends with: {:?}", end),
+
+ rest => println!("{:?}", rest),
+}
+
+if let [.., penultimate, _] = slice {
+ println!("next to last is {}", penultimate);
+}
+
+# let tuple = (1, 2, 3, 4, 5);
+// Rest patterns may also be used in tuple and tuple struct patterns.
+match tuple {
+ (1, .., y, z) => println!("y={} z={}", y, z),
+ (.., 5) => println!("tail must be 5"),
+ (..) => println!("matches everything else"),
+}
+```
+
## Range patterns
> **Syntax**\
> _RangePattern_ :\
-> _RangePatternBound_ `..=` _RangePatternBound_\
-> | _RangePatternBound_ `...` _RangePatternBound_
+> _RangePatternBound_ `..=` _RangePatternBound_
+>
+> _ObsoleteRangePattern_ :\
+> _RangePatternBound_ `...` _RangePatternBound_
>
> _RangePatternBound_ :\
> [CHAR_LITERAL]\
@@ -429,7 +492,7 @@ ranges containing all Unicode Scalar Values: `'\u{0000}'..='\u{D7FF}'` and
> **Syntax**\
> _ReferencePattern_ :\
-> (`&`|`&&`) `mut`? _Pattern_
+> (`&`|`&&`) `mut`? [_PatternWithoutRange_]
Reference patterns dereference the pointers that are being matched
and, thus, borrow them.
@@ -559,8 +622,7 @@ A struct pattern is refutable when one of its subpatterns is refutable.
> [_PathInExpression_] `(` _TupleStructItems_? `)`
>
> _TupleStructItems_ :\
-> [_Pattern_] ( `,` [_Pattern_] )\* `,`?\
-> | ([_Pattern_] `,`)\* `..` (`,` [_Pattern_])* `,`?
+> [_Pattern_] ( `,` [_Pattern_] )\* `,`?
Tuple struct patterns match tuple struct and enum values that match all criteria defined
by its subpatterns. They are also used to [destructure](#destructuring) a tuple struct or
@@ -576,13 +638,16 @@ A tuple struct pattern is refutable when one of its subpatterns is refutable.
>
> _TuplePatternItems_ :\
> [_Pattern_] `,`\
-> | [_Pattern_] (`,` [_Pattern_])+ `,`?\
-> | ([_Pattern_] `,`)\* `..` (`,` [_Pattern_])* `,`?
+> | [_RestPattern_]\
+> | [_Pattern_] (`,` [_Pattern_])+ `,`?
Tuple patterns match tuple values that match all criteria defined by its subpatterns.
They are also used to [destructure](#destructuring) a tuple.
-This pattern is refutable when one of its subpatterns is refutable.
+The form `(..)` with a single [_RestPattern_] is a special form that does not
+require a comma, and matches a tuple of any size.
+
+The tuple pattern is refutable when one of its subpatterns is refutable.
## Grouped patterns
@@ -607,7 +672,10 @@ match int_reference {
> **Syntax**\
> _SlicePattern_ :\
-> `[` [_Pattern_] \(`,` [_Pattern_])\* `,`? `]`
+> `[` _SlicePatternItems_? `]`
+>
+> _SlicePatternItems_ :\
+> [_Pattern_] \(`,` [_Pattern_])\* `,`?
Slice patterns can match both arrays of fixed size and slices of dynamic size.
```rust
@@ -628,6 +696,11 @@ 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.
+
## Path patterns
> **Syntax**\
@@ -658,12 +731,15 @@ refer to refutable constants or enum variants for enums with multiple variants.
[_IdentifierPattern_]: #identifier-patterns
[_LiteralPattern_]: #literal-patterns
[_MacroInvocation_]: macros.md#macro-invocation
+[_ObsoleteRangePattern_]: #range-patterns
[_PathInExpression_]: paths.md#paths-in-expressions
[_PathPattern_]: #path-patterns
[_Pattern_]: #patterns
+[_PatternWithoutRange_]: #patterns
[_QualifiedPathInExpression_]: paths.md#qualified-paths
[_RangePattern_]: #range-patterns
[_ReferencePattern_]: #reference-patterns
+[_RestPattern_]: #rest-patterns
[_SlicePattern_]: #slice-patterns
[_StructPattern_]: #struct-patterns
[_TuplePattern_]: #tuple-patterns