Skip to content

Commit 9574a86

Browse files
authored
Merge pull request #1925 from rust-lang/TC/tuple-struct-pattern-namespaces
Document (tuple) struct pattern namespace behavior
2 parents a5140b8 + a170307 commit 9574a86

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

src/patterns.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,9 @@ let Struct{a: x, b: y, c: z} = struct_value; // destructure all fields
801801
r[patterns.struct.refutable]
802802
A struct pattern is refutable if the [PathInExpression] resolves to a constructor of an enum with more than one variant, or one of its subpatterns is refutable.
803803

804+
r[patterns.struct.namespace]
805+
A struct pattern matches against the struct, union, or enum variant whose constructor is resolved from [PathInExpression] in the [type namespace]. See [patterns.tuple-struct.namespace] for more details.
806+
804807
r[patterns.tuple-struct]
805808
## Tuple struct patterns
806809

@@ -818,6 +821,46 @@ They are also used to [destructure](#destructuring) a tuple struct or enum value
818821
r[patterns.tuple-struct.refutable]
819822
A tuple struct pattern is refutable if the [PathInExpression] resolves to a constructor of an enum with more than one variant, or one of its subpatterns is refutable.
820823

824+
r[patterns.tuple-struct.namespace]
825+
A tuple struct pattern matches against the tuple struct or [tuple-like enum variant] whose constructor is resolved from [PathInExpression] in the [value namespace].
826+
827+
> [!NOTE]
828+
> Conversely, a struct pattern for a tuple struct or [tuple-like enum variant], e.g. `S { 0: _ }`, matches against the tuple struct or variant whose constructor is resolved in the [type namespace].
829+
>
830+
> ```rust,no_run
831+
> enum E1 { V(u16) }
832+
> enum E2 { V(u32) }
833+
>
834+
> // Import `E1::V` from the type namespace only.
835+
> mod _0 {
836+
> const V: () = (); // For namespace masking.
837+
> pub(super) use super::E1::*;
838+
> }
839+
> use _0::*;
840+
>
841+
> // Import `E2::V` from the value namespace only.
842+
> mod _1 {
843+
> struct V {} // For namespace masking.
844+
> pub(super) use super::E2::*;
845+
> }
846+
> use _1::*;
847+
>
848+
> fn f() {
849+
> // This struct pattern matches against the tuple-like
850+
> // enum variant whose constructor was found in the type
851+
> // namespace.
852+
> let V { 0: ..=u16::MAX } = (loop {}) else { loop {} };
853+
> // This tuple struct pattern matches against the tuple-like
854+
> // enum variant whose constructor was found in the value
855+
> // namespace.
856+
> let V(..=u32::MAX) = (loop {}) else { loop {} };
857+
> }
858+
> # // Required due to the odd behavior of `super` within functions.
859+
> # fn main() {}
860+
> ```
861+
>
862+
> The Lang team has made certain decisions, such as in [PR #138458], that raise questions about the desirability of using the value namespace in this way for patterns, as described in [PR #140593]. It might be prudent to not intentionally rely on this nuance in your code.
863+
821864
r[patterns.tuple]
822865
## Tuple patterns
823866
@@ -1035,6 +1078,8 @@ This allows us to reserve syntactic space for a possible future type ascription
10351078
For example, `x @ A(..) | B(..)` will result in an error that `x` is not bound in all patterns.
10361079
`&A(x) | B(x)` will result in a type mismatch between `x` in the different subpatterns.
10371080

1081+
[PR #138458]: https://github.com/rust-lang/rust/pull/138458
1082+
[PR #140593]: https://github.com/rust-lang/rust/pull/140593#issuecomment-2972338457
10381083
[`Copy`]: special-types-and-traits.md#copy
10391084
[constant]: items/constant-items.md
10401085
[enums]: items/enumerations.md
@@ -1048,5 +1093,7 @@ For example, `x @ A(..) | B(..)` will result in an error that `x` is not bound i
10481093
[structs]: items/structs.md
10491094
[tuples]: types/tuple.md
10501095
[scrutinee]: glossary.md#scrutinee
1096+
[tuple-like enum variant]: items.enum.tuple-expr
10511097
[type coercions]: type-coercions.md
1052-
[value namespace]: names/namespaces.md
1098+
[type namespace]: names.namespaces.kinds
1099+
[value namespace]: names.namespaces.kinds

0 commit comments

Comments
 (0)