@@ -696,6 +696,10 @@ pub enum Constructor<Cx: PatCx> {
696696F128Range ( IeeeFloat < QuadS > , IeeeFloat < QuadS > , RangeEnd ) ,
697697/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
698698Str ( 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> {
740744Constructor :: F64Range ( lo, hi, end) => Constructor :: F64Range ( * lo, * hi, * end) ,
741745Constructor :: F128Range ( lo, hi, end) => Constructor :: F128Range ( * lo, * hi, * end) ,
742746Constructor :: Str ( value) => Constructor :: Str ( value. clone ( ) ) ,
747+ Constructor :: DerefPattern ( ty) => Constructor :: DerefPattern ( ty. clone ( ) ) ,
743748Constructor :: Opaque ( inner) => Constructor :: Opaque ( inner. clone ( ) ) ,
744749Constructor :: Or => Constructor :: Or ,
745750Constructor :: 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> {
932941F64Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ?,
933942F128Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ?,
934943Str ( value) => write ! ( f, "{value:?}" ) ?,
944+ DerefPattern ( _) => write ! ( f, "deref!({:?})" , fields. next( ) . unwrap( ) ) ?,
935945Opaque ( ..) => write ! ( f, "<constant pattern>" ) ?,
936946Or => {
937947for pat in fields {
@@ -1039,15 +1049,27 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
10391049let mut missing = Vec :: new ( ) ;
10401050// Constructors in `ctors`, except wildcards and opaques.
10411051let 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 ;
10421055for ctor in ctors. cloned ( ) {
10431056match ctor {
1057+ DerefPattern ( ..) => {
1058+ if !deref_pat_present {
1059+ deref_pat_present = true ;
1060+ present. push ( ctor) ;
1061+ }
1062+ }
10441063Opaque ( ..) => present. push ( ctor) ,
10451064Wildcard => { } // discard wildcards
10461065 _ => seen. push ( ctor) ,
10471066}
10481067}
10491068
10501069match self {
1070+ _ if deref_pat_present => {
1071+ // Deref patterns are the only constructor; nothing is missing.
1072+ }
10511073ConstructorSet :: Struct { empty } => {
10521074if !seen. is_empty ( ) {
10531075 present. push ( Struct ) ;
0 commit comments