@@ -696,6 +696,10 @@ pub enum Constructor<Cx: PatCx> {
696696 F128Range ( IeeeFloat < QuadS > , IeeeFloat < QuadS > , RangeEnd ) ,
697697 /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
698698 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 ) ,
699703 /// Constants that must not be matched structurally. They are treated as black boxes for the
700704 /// purposes of exhaustiveness: we must not inspect them, and they don't count towards making a
701705 /// match exhaustive.
@@ -740,6 +744,7 @@ impl<Cx: PatCx> Clone for Constructor<Cx> {
740744 Constructor :: F64Range ( lo, hi, end) => Constructor :: F64Range ( * lo, * hi, * end) ,
741745 Constructor :: F128Range ( lo, hi, end) => Constructor :: F128Range ( * lo, * hi, * end) ,
742746 Constructor :: Str ( value) => Constructor :: Str ( value. clone ( ) ) ,
747+ Constructor :: DerefPattern ( ty) => Constructor :: DerefPattern ( ty. clone ( ) ) ,
743748 Constructor :: Opaque ( inner) => Constructor :: Opaque ( inner. clone ( ) ) ,
744749 Constructor :: Or => Constructor :: Or ,
745750 Constructor :: Never => Constructor :: Never ,
@@ -856,6 +861,10 @@ impl<Cx: PatCx> Constructor<Cx> {
856861 }
857862 ( Slice ( self_slice) , Slice ( other_slice) ) => self_slice. is_covered_by ( * other_slice) ,
858863
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+
859868 // Opaque constructors don't interact with anything unless they come from the
860869 // syntactically identical pattern.
861870 ( Opaque ( self_id) , Opaque ( other_id) ) => self_id == other_id,
@@ -932,6 +941,7 @@ impl<Cx: PatCx> Constructor<Cx> {
932941 F64Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ?,
933942 F128Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ?,
934943 Str ( value) => write ! ( f, "{value:?}" ) ?,
944+ DerefPattern ( _) => write ! ( f, "deref!({:?})" , fields. next( ) . unwrap( ) ) ?,
935945 Opaque ( ..) => write ! ( f, "<constant pattern>" ) ?,
936946 Or => {
937947 for pat in fields {
@@ -1039,15 +1049,27 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
10391049 let mut missing = Vec :: new ( ) ;
10401050 // Constructors in `ctors`, except wildcards and opaques.
10411051 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 ;
10421055 for ctor in ctors. cloned ( ) {
10431056 match ctor {
1057+ DerefPattern ( ..) => {
1058+ if !deref_pat_present {
1059+ deref_pat_present = true ;
1060+ present. push ( ctor) ;
1061+ }
1062+ }
10441063 Opaque ( ..) => present. push ( ctor) ,
10451064 Wildcard => { } // discard wildcards
10461065 _ => seen. push ( ctor) ,
10471066 }
10481067 }
10491068
10501069 match self {
1070+ _ if deref_pat_present => {
1071+ // Deref patterns are the only constructor; nothing is missing.
1072+ }
10511073 ConstructorSet :: Struct { empty } => {
10521074 if !seen. is_empty ( ) {
10531075 present. push ( Struct ) ;
0 commit comments