You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We had not documented what namespaces were used when matching struct
and tuple struct patterns. As it turns out, this is a bit nuanced.
Let's document the current behavior, describe the nature of this
nuance with an example, and note the possible uncertainly about the
desirability of this behavior long-term.
Copy file name to clipboardExpand all lines: src/patterns.md
+50-1Lines changed: 50 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -801,6 +801,9 @@ let Struct{a: x, b: y, c: z} = struct_value; // destructure all fields
801
801
r[patterns.struct.refutable]
802
802
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.
803
803
804
+
r[patterns.struct.namespace]
805
+
A struct pattern matches against the struct whose constructor is resolved from [PathInExpression] in the [type namespace]. See [patterns.tuple-struct.namespace] for more details.
806
+
804
807
r[patterns.tuple-struct]
805
808
## Tuple struct patterns
806
809
@@ -818,6 +821,49 @@ They are also used to [destructure](#destructuring) a tuple struct or enum value
818
821
r[patterns.tuple-struct.refutable]
819
822
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.
820
823
824
+
r[patterns.tuple-struct.namespace]
825
+
A tuple struct pattern matches against the tuple struct whose constructor is resolved from [PathInExpression] in the [value namespace].
826
+
827
+
> [!NOTE]
828
+
> Conversely, a struct pattern for a tuple struct (e.g. `S { 0: _ }`) matches against the tuple struct whose constructor is resolved in the [type namespace].
829
+
>
830
+
> ```rust,no_run
831
+
> # #![allow(unused)]
832
+
> enum E1 { V(u16) }
833
+
> enum E2 { V(u32) }
834
+
>
835
+
> // Import `E1::V` from type namespace only.
836
+
> mod _from_type_namespace {
837
+
> const V: () = (); // For namespace masking.
838
+
> pub(super) use super::E1::*;
839
+
> }
840
+
> use _from_type_namespace::*;
841
+
>
842
+
> // Import `E2::V` from value namespace only.
843
+
> mod _from_value_namespace {
844
+
> struct V {} // For namespace masking.
845
+
> pub(super) use super::E2::*;
846
+
> }
847
+
> use _from_value_namespace::*;
848
+
>
849
+
> fn f() {
850
+
> match loop {} {
851
+
> // This struct pattern matches against the struct whose
852
+
> // constructor was found in the type namespace.
853
+
> V { 0: ..=u16::MAX } => (),
854
+
> }
855
+
> match loop {} {
856
+
> // This tuple struct pattern matches against the struct
857
+
> // whose constructor was found in the value namespace.
858
+
> V(..=u32::MAX) => (),
859
+
> }
860
+
> }
861
+
> # // Required due to the odd behavior of `super` within functions.
862
+
> # fn main() {}
863
+
> ```
864
+
>
865
+
> The Lang team has made certain decisions, such as in [PR #138458], that raise questions about the desirability of using the value namespace for this, as described in [PR #140593]. It might be prudent to not intentionally rely on this nuance in your code.
866
+
821
867
r[patterns.tuple]
822
868
## Tuple patterns
823
869
@@ -1035,6 +1081,8 @@ This allows us to reserve syntactic space for a possible future type ascription
1035
1081
For example, `x @ A(..) | B(..)` will result in an error that `x` is not bound in all patterns.
1036
1082
`&A(x) | B(x)` will result in a type mismatch between `x` in the different subpatterns.
0 commit comments