diff --git a/src/glossary.rst b/src/glossary.rst index 9a66eb66..369e0d63 100644 --- a/src/glossary.rst +++ b/src/glossary.rst @@ -4713,6 +4713,19 @@ opt-out trait bound An :dt:`opt-out trait bound` is a :t:`trait bound` with :s:`Punctuation` ``?`` that nullifies an implicitly added :t:`trait bound`. + +.. _fls_LnPDQW3bnNUw: + +or-pattern +^^^^^^^^^^ + +:dp:`fls_LnPDQW3bnNUw` +An :dt:`or pattern` is a :t:`pattern` that matches on one of two or more +:t:`[pattern-without-alternation]s`. + +:dp:`fls_urIJ5JNHLhm6` +See :s:`Pattern`. + .. _fls_gllzixm9yt9w: outer attribute diff --git a/src/ownership-and-deconstruction.rst b/src/ownership-and-deconstruction.rst index f8351cf2..164b1449 100644 --- a/src/ownership-and-deconstruction.rst +++ b/src/ownership-and-deconstruction.rst @@ -695,7 +695,12 @@ When a :t:`drop scope` is left, all :t:`[value]s` associated with that :t:`drop scope` are :t:`dropped` as follows: * :dp:`fls_g07zq3n55094` - :t:`[Binding]s` are :t:`dropped` in reverse declaration order. + All other :t:`bindings` are :t:`dropped` in reverse declaration order. + +* :dp:`fls_W2S2FrkuedYC` + :t:`[Binding]s` introduced by an :t:`or-pattern` are dropped in reverse + declaration order, where the declaration order is defined by the first + :t:`subpattern`. * :dp:`fls_a5tmilqxdb6f` :t:`Temporaries ` are :t:`dropped` in reverse creation order. @@ -748,3 +753,38 @@ proceeds as follows: } let c = PrintOnDrop("2"); +:dp:`fls_THzA0QFdMMJB` +When an :t:`or pattern` is used, the drop order of :t:`[Binding]s` is +determined by the first :t:`pattern-without-alternation`, regardless of which +alternative matches at runtime. + +.. code-block:: rust + + // Drops `x` before `y`. + fn or_pattern_drop_order( + (Ok([x, y]) | Err([y, x])): Result<[T; 2], [T; 2]> + // ^^^^^^^^^^ ^^^^^^^^^^^ This is the second pattern-without-alternation. + // | + // This is the first pattern-without-alternation. + // + // In the first pattern-without-alternation, `x` is declared before `y`. + // Since it is the first pattern-without-alternation, that is the order + // used even if the second pattern-without-alternation, where the bindings + // are declared in the opposite order, is matched. + ) {} + + // Here we match the first pattern-without-alternation, and the drops happen + // according to the declaration order in the first pattern-without-alternation. + or_pattern_drop_order(Ok([ + PrintOnDrop("Declared first, dropped last"), + PrintOnDrop("Declared last, dropped first"), + ])); + + // Here we match the second pattern-without-alternation, and the drops still + // happen according to the declaration order in the first + // pattern-without-alternation. + or_pattern_drop_order(Err([ + PrintOnDrop("Declared last, dropped first"), + PrintOnDrop("Declared first, dropped last"), + ])); + diff --git a/src/patterns.rst b/src/patterns.rst index 57de8092..ec303d85 100644 --- a/src/patterns.rst +++ b/src/patterns.rst @@ -41,6 +41,10 @@ Patterns A :t:`pattern` is a :t:`construct` that matches a :t:`value` which satisfies all the criteria of the :t:`pattern`. +:dp:`fls_VQMmveZUfNTn` +An :t:`or-pattern` is a :t:`pattern` which or-s two or more :t:`[subpattern]s` using +character 0x7C (vertical line). + :dp:`fls_mp6i4blzexnu` A :t:`pattern-without-alternation` is a :t:`pattern` that cannot be alternated. @@ -65,18 +69,24 @@ of a :t:`pattern-without-range`, except for when the :t:`pattern` is ``&mut`` :s:`Identifier`. Such a :t:`pattern` is interpreted as a :t:`reference pattern` with :t:`keyword` ``mut`` containing an :t:`identifier pattern`. +:dp:`fls_72JHo343O7jp` +An or-pattern shall not appear in the :t:`pattern-without-alternation` of a +:t:`closure parameter`, a :t:`function parameter`, or a :t:`let statement`. + :dp:`fls_8luyomzppck` -Any two :t:`[pattern-without-alternation]s` that are or-ed using character 0x7C -(vertical line) are subject to the following restrictions: +Any two :t:`[subpattern]s` of an :t:`or-pattern` are subject to the following +restrictions: * :dp:`fls_rpvdfmy3n05a` - The :t:`[type]s` of the two :t:`[pattern-without-alternation]s` shall be + The :t:`[type]s` of the two :t:`[subpattern]s` shall be :t:`unifiable`. +* :dp:`fls_YDVgFaTQwcL8` + The set of :t:`[binding]s` introduced by the two :t:`[pattern]s` shall be distinct. + * :dp:`fls_kv533rntni1x` - The :t:`[binding]s` of the two :t:`[pattern-without-alternation]s` shall - be the same, shall have :t:`[unifiable type]s`, and shall have the same - :t:`[binding mode]s`. + Any two :t:`[binding]s` with the same name in the two :t:`[pattern]s` shall have + :t:`[unifiable type]s` and shall have the same :t:`[binding mode]s`. .. _fls_uh76pw6ykd57: @@ -1296,6 +1306,9 @@ Pattern Matching :t:`Pattern matching` that involves a :t:`pattern` and a context :t:`value` proceeds as follows: +#. :dp:`fls_tZJgZDWVChJV` + If the pattern is an :t:`or-pattern`, then perform or-pattern matching. + #. :dp:`fls_67ajub7d2b4c` For each :t:`pattern-without-alternation` of the :t:`pattern`: @@ -1350,6 +1363,25 @@ proceeds as follows: Only the :t:`[binding]s` of a matched :t:`pattern-without-alternation` are introduced into a :t:`binding scope`. + +.. _fls_VsBXBj4AqCj1: + +Or-pattern Matching +~~~~~~~~~~~~~~~~~~~ + + +:dp:`fls_njpiXkgi8Ryb` +Or-pattern matching of an :t:`or-pattern` of the form `constructor(or-pattern, rest)`, +where `constructor` is an arbitrary constructor, `or-pattern` is the :t:`or-pattern`, +and `rest` is optionally a remaining pattern, proceeds as follows: + +#. :dp:`fls_nE7qZpHy9TPu` + Perform pattern matching of the form `constructor(subpattern, rest)`, where + `subpattern` is a :t:`subpattern` of the :t:`or-pattern`, starting from the + first such :t:`subpattern` and proceeding in declarative order. +#. :dp:`fls_P8yB2b5enpw7` + Otherwise pattern matching fails. + .. _fls_vnai6ag4qrdb: Identifier Pattern Matching