From 2dbb847968a5e5bb352b92b3b62bbfe44a1721ca Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Sun, 7 Dec 2025 07:57:44 +0900 Subject: [PATCH 1/9] feat: add first draft of drop order in or patterns clarification --- src/glossary.rst | 13 +++++++++ src/ownership-and-deconstruction.rst | 40 ++++++++++++++++++++++++++++ src/patterns.rst | 14 ++++++++-- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/glossary.rst b/src/glossary.rst index 9a66eb66..a912c165 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..c2b376aa 100644 --- a/src/ownership-and-deconstruction.rst +++ b/src/ownership-and-deconstruction.rst @@ -697,6 +697,11 @@ When a :t:`drop scope` is left, all :t:`[value]s` associated with that * :dp:`fls_g07zq3n55094` :t:`[Binding]s` are :t:`dropped` in reverse declaration order. +* :dp:`fls_W2S2FrkuedYC` + For the purpose of drop order, an :t:`[Or Pattern]` declares its + :t:`[Binding]s` in the order given by its first + :t:`[Pattern Without Alternation]`. + * :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..3bff96b1 100644 --- a/src/patterns.rst +++ b/src/patterns.rst @@ -65,9 +65,19 @@ 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 :t:`or pattern` is a :t:`pattern` that matches on one of two or more +:t:`[pattern-without-alternation]s`. An :t:`or pattern` can nest arbitrarily. +Syntactically, :t:`[or pattern]s` are allowed in any of the places where other +:t:`[pattern]s` are allowed, with the exception of :t:`[let statement]s`, +:t:`[function parameter]s`, and :t:`[closure parameter]s`. + +:dp:`fls_VQMmveZUfNTn` +An :t:`or pattern` uses character 0x7C (vertical line) between the +:t:`[pattern-without-alternation]s`. + :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: +An :t:`or pattern` is subject to the following restrictions: * :dp:`fls_rpvdfmy3n05a` The :t:`[type]s` of the two :t:`[pattern-without-alternation]s` shall be From 59e9df0ee3e675943f9c99a9de7d0728b65c6245 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Fri, 12 Dec 2025 21:12:08 +0900 Subject: [PATCH 2/9] fix: revise based on feedback --- src/glossary.rst | 2 +- src/ownership-and-deconstruction.rst | 8 ++--- src/patterns.rst | 50 ++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/glossary.rst b/src/glossary.rst index a912c165..369e0d63 100644 --- a/src/glossary.rst +++ b/src/glossary.rst @@ -4716,7 +4716,7 @@ that nullifies an implicitly added :t:`trait bound`. .. _fls_LnPDQW3bnNUw: -or pattern +or-pattern ^^^^^^^^^^ :dp:`fls_LnPDQW3bnNUw` diff --git a/src/ownership-and-deconstruction.rst b/src/ownership-and-deconstruction.rst index c2b376aa..164b1449 100644 --- a/src/ownership-and-deconstruction.rst +++ b/src/ownership-and-deconstruction.rst @@ -695,12 +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` - For the purpose of drop order, an :t:`[Or Pattern]` declares its - :t:`[Binding]s` in the order given by its first - :t:`[Pattern Without Alternation]`. + :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. diff --git a/src/patterns.rst b/src/patterns.rst index 3bff96b1..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. @@ -66,27 +70,23 @@ of a :t:`pattern-without-range`, except for when the :t:`pattern` is ``&mut`` with :t:`keyword` ``mut`` containing an :t:`identifier pattern`. :dp:`fls_72JHo343O7jp` -An :t:`or pattern` is a :t:`pattern` that matches on one of two or more -:t:`[pattern-without-alternation]s`. An :t:`or pattern` can nest arbitrarily. -Syntactically, :t:`[or pattern]s` are allowed in any of the places where other -:t:`[pattern]s` are allowed, with the exception of :t:`[let statement]s`, -:t:`[function parameter]s`, and :t:`[closure parameter]s`. - -:dp:`fls_VQMmveZUfNTn` -An :t:`or pattern` uses character 0x7C (vertical line) between the -:t:`[pattern-without-alternation]s`. +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` -An :t:`or pattern` is 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: @@ -1306,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`: @@ -1360,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 From c7f77177e37bd64a16374a5888fd9571f33ee972 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Wed, 17 Dec 2025 04:28:58 +0900 Subject: [PATCH 3/9] fix: move definition of or-pattern to glossary and then copy to patterns.rst --- src/glossary.rst | 3 +-- src/patterns.rst | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/glossary.rst b/src/glossary.rst index 369e0d63..50ea59a8 100644 --- a/src/glossary.rst +++ b/src/glossary.rst @@ -4720,8 +4720,7 @@ 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`. +An :dt:`or pattern` is a :t:`pattern` that matches on one of two or more :t:`[pattern-without-alternation]s` and or-s two or more :t:`[subpattern]s` using character 0x7C (vertical line). :dp:`fls_urIJ5JNHLhm6` See :s:`Pattern`. diff --git a/src/patterns.rst b/src/patterns.rst index ec303d85..62b6e70e 100644 --- a/src/patterns.rst +++ b/src/patterns.rst @@ -42,8 +42,7 @@ 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). +An :t:`or pattern` is a :t:`pattern` that matches on one of two or more :t:`[pattern-without-alternation]s` and 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. From 98f4d99457f724ee236c0c15a779634ed47f62cd Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Tue, 16 Dec 2025 14:32:02 -0500 Subject: [PATCH 4/9] fix: pattern => subpattern --- src/patterns.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/patterns.rst b/src/patterns.rst index 62b6e70e..940cdebe 100644 --- a/src/patterns.rst +++ b/src/patterns.rst @@ -84,7 +84,7 @@ restrictions: The set of :t:`[binding]s` introduced by the two :t:`[pattern]s` shall be distinct. * :dp:`fls_kv533rntni1x` - Any two :t:`[binding]s` with the same name in the two :t:`[pattern]s` shall have + Any two :t:`[binding]s` with the same name in the two :t:`[subpattern]s` shall have :t:`[unifiable type]s` and shall have the same :t:`[binding mode]s`. .. _fls_uh76pw6ykd57: From d72e16ec4b1a9415c91bd672349d664ab0bf2599 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Tue, 16 Dec 2025 14:32:12 -0500 Subject: [PATCH 5/9] fix: pattern => subpattern --- src/patterns.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/patterns.rst b/src/patterns.rst index 940cdebe..c566739e 100644 --- a/src/patterns.rst +++ b/src/patterns.rst @@ -81,7 +81,7 @@ restrictions: :t:`unifiable`. * :dp:`fls_YDVgFaTQwcL8` - The set of :t:`[binding]s` introduced by the two :t:`[pattern]s` shall be distinct. + The set of :t:`[binding]s` introduced by the two :t:`[subpattern]s` shall be the same. * :dp:`fls_kv533rntni1x` Any two :t:`[binding]s` with the same name in the two :t:`[subpattern]s` shall have From b7e026bb9a2aae4fd97bbde2e873b9c96d305360 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Tue, 16 Dec 2025 14:34:50 -0500 Subject: [PATCH 6/9] fix: let statement => let binding --- src/patterns.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/patterns.rst b/src/patterns.rst index c566739e..216a8987 100644 --- a/src/patterns.rst +++ b/src/patterns.rst @@ -70,7 +70,7 @@ 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`. +:t:`closure parameter`, a :t:`function parameter`, or a :t:`let binding`. :dp:`fls_8luyomzppck` Any two :t:`[subpattern]s` of an :t:`or-pattern` are subject to the following From 900088b9d7a408596157bfec2c2911b3a1fbc886 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Wed, 17 Dec 2025 04:55:15 +0900 Subject: [PATCH 7/9] docs: add definition of let binding --- src/glossary.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/glossary.rst b/src/glossary.rst index 50ea59a8..4c5efb31 100644 --- a/src/glossary.rst +++ b/src/glossary.rst @@ -3741,6 +3741,15 @@ tests for a less-than-or-equals relationship. :dp:`fls_ft5aeo4ilgwc` See :s:`LessThanOrEqualsExpression`. + +.. _fls_DdZ1ZwjLZTeG: + +let binding +^^^^^^^^^^^ + +:dp:`fls_sw6HrsxsnG2y` +A :dt:`let binding` is a :t:`construct` that introduces :t:`[binding]s` by matching a :t:`value` against a :t:`pattern` using the keyword ``let``. :t:`[let binding]s` appear in :t:`[let statement]s`, :t:`[if let expression]s`, :t:`[while let loop expression]s`, and :t:`[let initializer]s`. + .. _fls_hqj80jHcxEBB: let initializer From aba5ea58b9512f1991d3655613fdaad86e97d157 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Wed, 17 Dec 2025 06:11:04 +0900 Subject: [PATCH 8/9] fix: rework example to be more in line with FLS style --- src/ownership-and-deconstruction.rst | 49 +++++++++++----------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/ownership-and-deconstruction.rst b/src/ownership-and-deconstruction.rst index 164b1449..f1d5d7b7 100644 --- a/src/ownership-and-deconstruction.rst +++ b/src/ownership-and-deconstruction.rst @@ -754,37 +754,26 @@ 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. +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 matches at runtime. + +:dp:`fls_dhfIPP4yR3Tt` +In the following example, the drop order is ``b``, ``a`` for both calls. +Dropping proceeds as follows: + +#. :dp:`fls_zxFM7EoE2Xq8` + The first :t:`pattern-without-alternation` ``Ok([a, b])`` declares ``a`` before ``b``. + +#. :dp:`fls_zxFM7EoE2Xq8` + When the first call matches ``Ok([a, b])``, the :t:`[binding]s` are dropped in reverse declaration order: ``b`` then ``a``. + +#. :dp:`fls_gNWXh61ZXXt8` + When the second call matches ``Err([b, a])``, the drop order remains ``b`` then ``a``, determined by the first :t:`pattern-without-alternation`. .. 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"), - ])); + fn drop_order((Ok([a, b]) | Err([b, a])): Result<[T; 2], [T; 2]>) {} + + drop_order(Ok([PrintOnDrop("1"), PrintOnDrop("2")])); + + drop_order(Err([PrintOnDrop("2"), PrintOnDrop("1")])); From c236af6315804ee445b1f96eb3db2989ca2d57e2 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Wed, 17 Dec 2025 06:14:16 +0900 Subject: [PATCH 9/9] fix: duplicated FLS IDs --- src/ownership-and-deconstruction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ownership-and-deconstruction.rst b/src/ownership-and-deconstruction.rst index f1d5d7b7..33006002 100644 --- a/src/ownership-and-deconstruction.rst +++ b/src/ownership-and-deconstruction.rst @@ -763,7 +763,7 @@ Dropping proceeds as follows: #. :dp:`fls_zxFM7EoE2Xq8` The first :t:`pattern-without-alternation` ``Ok([a, b])`` declares ``a`` before ``b``. -#. :dp:`fls_zxFM7EoE2Xq8` +#. :dp:`fls_093YxG6YXQz2` When the first call matches ``Ok([a, b])``, the :t:`[binding]s` are dropped in reverse declaration order: ``b`` then ``a``. #. :dp:`fls_gNWXh61ZXXt8`