From 5c5b65ddd136f82252bb862e2a42a237204df6d9 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 2 Sep 2026 17:23:30 -0400 Subject: [PATCH 1/4] Document which union patterns are unsafe --- src/items/unions.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/items/unions.md b/src/items/unions.md index 7b3d836e08..2f87c8af6f 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -124,6 +124,15 @@ fn f(u: MyUnion) { } ``` +`unsafe` is only required if the union field is accessed, in whole or in part, by the pattern, including any of its sub-patterns. For the purpose of this requirement, the following patterns are considered to perform an access: + +- [Literal patterns](../patterns.md#literal-patterns) +- [Identifier patterns](../patterns.md#identifier-patterns) +- [Range patterns](../patterns.md#range-patterns) +- [Reference patterns](../patterns.md#reference-patterns) +- [Struct](../patterns.md#struct-patterns) and [tuple struct](../patterns.md#tuple-struct-patterns) patterns which correspond to an enum variant +- [Path patterns](../patterns.md#path-patterns), if the result of expanding the constant into a pattern contains one of the above. + > [!WARNING] > The order in which the subpatterns of a pattern are tested is not specified. A union field named in a pattern may be read even when the pattern as a whole does not match. Reading a union field is undefined behavior unless it holds a valid value of its type (see [items.union.fields.validity]). Nothing else in the pattern can be relied on to prevent the read. > From c903ed60625eb5e33d3ef9c843ea2832948366da Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Mon, 7 Sep 2026 14:02:01 -0400 Subject: [PATCH 2/4] Account for constants with private fields --- src/items/unions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/unions.md b/src/items/unions.md index 2f87c8af6f..6004fc2689 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -131,7 +131,7 @@ fn f(u: MyUnion) { - [Range patterns](../patterns.md#range-patterns) - [Reference patterns](../patterns.md#reference-patterns) - [Struct](../patterns.md#struct-patterns) and [tuple struct](../patterns.md#tuple-struct-patterns) patterns which correspond to an enum variant -- [Path patterns](../patterns.md#path-patterns), if the result of expanding the constant into a pattern contains one of the above. +- [Path patterns](../patterns.md#path-patterns), if the result of expanding the constant into a pattern contains one of the above, or if the expanded pattern could not have been written directly at the location where it is used due to field privacy or `#[non_exhaustive]`. > [!WARNING] > The order in which the subpatterns of a pattern are tested is not specified. A union field named in a pattern may be read even when the pattern as a whole does not match. Reading a union field is undefined behavior unless it holds a valid value of its type (see [items.union.fields.validity]). Nothing else in the pattern can be relied on to prevent the read. From 27d20692ab072cc73b558bf5c6874fba8bb11090 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Thu, 10 Sep 2026 00:26:54 -0400 Subject: [PATCH 3/4] Account for match ergonomics --- src/items/unions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/items/unions.md b/src/items/unions.md index 6004fc2689..285efe9774 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -130,6 +130,7 @@ fn f(u: MyUnion) { - [Identifier patterns](../patterns.md#identifier-patterns) - [Range patterns](../patterns.md#range-patterns) - [Reference patterns](../patterns.md#reference-patterns) +- [Non-reference patterns](../patterns.md#r-patterns.ident.binding.non-reference) matching reference values - [Struct](../patterns.md#struct-patterns) and [tuple struct](../patterns.md#tuple-struct-patterns) patterns which correspond to an enum variant - [Path patterns](../patterns.md#path-patterns), if the result of expanding the constant into a pattern contains one of the above, or if the expanded pattern could not have been written directly at the location where it is used due to field privacy or `#[non_exhaustive]`. From d663ce881a82dbbebfa96e1a089ebb7e0ab896c2 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Thu, 10 Sep 2026 00:45:25 -0400 Subject: [PATCH 4/4] Mention slice patterns --- src/items/unions.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/items/unions.md b/src/items/unions.md index 285efe9774..a3283f5602 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -134,6 +134,9 @@ fn f(u: MyUnion) { - [Struct](../patterns.md#struct-patterns) and [tuple struct](../patterns.md#tuple-struct-patterns) patterns which correspond to an enum variant - [Path patterns](../patterns.md#path-patterns), if the result of expanding the constant into a pattern contains one of the above, or if the expanded pattern could not have been written directly at the location where it is used due to field privacy or `#[non_exhaustive]`. +> [!NOTE] +> [Slice patterns](../patterns.md#slice-patterns) other than `[..]`, when matching against slices of dynamic size, could also be considered to access the union. However, union fields must implement `Sized`, so the rules regarding patterns matching reference values already account for this case. + > [!WARNING] > The order in which the subpatterns of a pattern are tested is not specified. A union field named in a pattern may be read even when the pattern as a whole does not match. Reading a union field is undefined behavior unless it holds a valid value of its type (see [items.union.fields.validity]). Nothing else in the pattern can be relied on to prevent the read. >