@@ -696,6 +696,10 @@ pub enum Constructor<Cx: PatCx> {
696
696
F128Range ( IeeeFloat < QuadS > , IeeeFloat < QuadS > , RangeEnd ) ,
697
697
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
698
698
Str ( Cx :: StrLit ) ,
699
+ /// Deref patterns (enabled by the `deref_patterns` feature) provide a way of matching on a
700
+ /// smart pointer ADT through its pointee. They don't directly correspond to ADT constructors,
701
+ /// and currently are not supported alongside them. Carries the type of the pointee.
702
+ DerefPattern ( Cx :: Ty ) ,
699
703
/// Constants that must not be matched structurally. They are treated as black boxes for the
700
704
/// purposes of exhaustiveness: we must not inspect them, and they don't count towards making a
701
705
/// match exhaustive.
@@ -740,6 +744,7 @@ impl<Cx: PatCx> Clone for Constructor<Cx> {
740
744
Constructor :: F64Range ( lo, hi, end) => Constructor :: F64Range ( * lo, * hi, * end) ,
741
745
Constructor :: F128Range ( lo, hi, end) => Constructor :: F128Range ( * lo, * hi, * end) ,
742
746
Constructor :: Str ( value) => Constructor :: Str ( value. clone ( ) ) ,
747
+ Constructor :: DerefPattern ( ty) => Constructor :: DerefPattern ( ty. clone ( ) ) ,
743
748
Constructor :: Opaque ( inner) => Constructor :: Opaque ( inner. clone ( ) ) ,
744
749
Constructor :: Or => Constructor :: Or ,
745
750
Constructor :: Never => Constructor :: Never ,
@@ -856,6 +861,10 @@ impl<Cx: PatCx> Constructor<Cx> {
856
861
}
857
862
( Slice ( self_slice) , Slice ( other_slice) ) => self_slice. is_covered_by ( * other_slice) ,
858
863
864
+ // Deref patterns only interact with other deref patterns. Prior to usefulness analysis,
865
+ // we ensure they don't appear alongside any other non-wild non-opaque constructors.
866
+ ( DerefPattern ( _) , DerefPattern ( _) ) => true ,
867
+
859
868
// Opaque constructors don't interact with anything unless they come from the
860
869
// syntactically identical pattern.
861
870
( Opaque ( self_id) , Opaque ( other_id) ) => self_id == other_id,
@@ -932,6 +941,7 @@ impl<Cx: PatCx> Constructor<Cx> {
932
941
F64Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ?,
933
942
F128Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ?,
934
943
Str ( value) => write ! ( f, "{value:?}" ) ?,
944
+ DerefPattern ( _) => write ! ( f, "deref!({:?})" , fields. next( ) . unwrap( ) ) ?,
935
945
Opaque ( ..) => write ! ( f, "<constant pattern>" ) ?,
936
946
Or => {
937
947
for pat in fields {
@@ -1039,15 +1049,27 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
1039
1049
let mut missing = Vec :: new ( ) ;
1040
1050
// Constructors in `ctors`, except wildcards and opaques.
1041
1051
let mut seen = Vec :: new ( ) ;
1052
+ // If we see a deref pattern, it must be the only non-wildcard non-opaque constructor; we
1053
+ // ensure this prior to analysis.
1054
+ let mut deref_pat_present = false ;
1042
1055
for ctor in ctors. cloned ( ) {
1043
1056
match ctor {
1057
+ DerefPattern ( ..) => {
1058
+ if !deref_pat_present {
1059
+ deref_pat_present = true ;
1060
+ present. push ( ctor) ;
1061
+ }
1062
+ }
1044
1063
Opaque ( ..) => present. push ( ctor) ,
1045
1064
Wildcard => { } // discard wildcards
1046
1065
_ => seen. push ( ctor) ,
1047
1066
}
1048
1067
}
1049
1068
1050
1069
match self {
1070
+ _ if deref_pat_present => {
1071
+ // Deref patterns are the only constructor; nothing is missing.
1072
+ }
1051
1073
ConstructorSet :: Struct { empty } => {
1052
1074
if !seen. is_empty ( ) {
1053
1075
present. push ( Struct ) ;
0 commit comments