@@ -105,7 +105,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
105105 ) -> VariantIdx {
106106 match * ctor {
107107 Variant ( idx) => idx,
108- Single => {
108+ Struct | UnionField => {
109109 assert ! ( !adt. is_enum( ) ) ;
110110 FIRST_VARIANT
111111 }
@@ -123,9 +123,8 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
123123 ) -> & ' p [ DeconstructedPat < ' p , ' tcx > ] {
124124 let cx = self ;
125125 match ctor {
126- Single | Variant ( _) => match ty. kind ( ) {
126+ Struct | Variant ( _) | UnionField => match ty. kind ( ) {
127127 ty:: Tuple ( fs) => cx. alloc_wildcard_slice ( fs. iter ( ) ) ,
128- ty:: Ref ( _, rty, _) => cx. alloc_wildcard_slice ( once ( * rty) ) ,
129128 ty:: Adt ( adt, args) => {
130129 if adt. is_box ( ) {
131130 // The only legal patterns of type `Box` (outside `std`) are `_` and box
@@ -138,7 +137,11 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
138137 cx. alloc_wildcard_slice ( tys)
139138 }
140139 }
141- _ => bug ! ( "Unexpected type for `Single` constructor: {:?}" , ty) ,
140+ _ => bug ! ( "Unexpected type for constructor `{ctor:?}`: {ty:?}" ) ,
141+ } ,
142+ Ref => match ty. kind ( ) {
143+ ty:: Ref ( _, rty, _) => cx. alloc_wildcard_slice ( once ( * rty) ) ,
144+ _ => bug ! ( "Unexpected type for `Ref` constructor: {ty:?}" ) ,
142145 } ,
143146 Slice ( slice) => match * ty. kind ( ) {
144147 ty:: Slice ( ty) | ty:: Array ( ty, _) => {
@@ -167,9 +170,8 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
167170 /// `Fields::wildcards`.
168171 pub ( crate ) fn ctor_arity ( & self , ctor : & Constructor < ' tcx > , ty : Ty < ' tcx > ) -> usize {
169172 match ctor {
170- Single | Variant ( _) => match ty. kind ( ) {
173+ Struct | Variant ( _) | UnionField => match ty. kind ( ) {
171174 ty:: Tuple ( fs) => fs. len ( ) ,
172- ty:: Ref ( ..) => 1 ,
173175 ty:: Adt ( adt, ..) => {
174176 if adt. is_box ( ) {
175177 // The only legal patterns of type `Box` (outside `std`) are `_` and box
@@ -181,8 +183,9 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
181183 self . list_variant_nonhidden_fields ( ty, variant) . count ( )
182184 }
183185 }
184- _ => bug ! ( "Unexpected type for `Single` constructor : {:?}" , ty ) ,
186+ _ => bug ! ( "Unexpected type for constructor `{ctor:?}` : {ty :?}" ) ,
185187 } ,
188+ Ref => 1 ,
186189 Slice ( slice) => slice. arity ( ) ,
187190 Bool ( ..)
188191 | IntRange ( ..)
@@ -298,9 +301,9 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
298301 ConstructorSet :: Variants { variants, non_exhaustive : is_declared_nonexhaustive }
299302 }
300303 }
301- ty:: Adt ( .. ) | ty :: Tuple ( .. ) | ty :: Ref ( .. ) => {
302- ConstructorSet :: Single { empty : cx. is_uninhabited ( ty) }
303- }
304+ ty:: Adt ( def , _ ) if def . is_union ( ) => ConstructorSet :: Union ,
305+ ty :: Adt ( .. ) | ty :: Tuple ( .. ) => ConstructorSet :: Struct { empty : cx. is_uninhabited ( ty) } ,
306+ ty :: Ref ( .. ) => ConstructorSet :: Ref ,
304307 ty:: Never => ConstructorSet :: NoConstructors ,
305308 // This type is one for which we cannot list constructors, like `str` or `f64`.
306309 // FIXME(Nadrieril): which of these are actually allowed?
@@ -359,13 +362,18 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
359362 fields = & [ ] ;
360363 }
361364 PatKind :: Deref { subpattern } => {
362- ctor = Single ;
363365 fields = singleton ( self . lower_pat ( subpattern) ) ;
366+ ctor = match pat. ty . kind ( ) {
367+ // This is a box pattern.
368+ ty:: Adt ( adt, ..) if adt. is_box ( ) => Struct ,
369+ ty:: Ref ( ..) => Ref ,
370+ _ => bug ! ( "pattern has unexpected type: pat: {:?}, ty: {:?}" , pat, pat. ty) ,
371+ } ;
364372 }
365373 PatKind :: Leaf { subpatterns } | PatKind :: Variant { subpatterns, .. } => {
366374 match pat. ty . kind ( ) {
367375 ty:: Tuple ( fs) => {
368- ctor = Single ;
376+ ctor = Struct ;
369377 let mut wilds: SmallVec < [ _ ; 2 ] > =
370378 fs. iter ( ) . map ( |ty| DeconstructedPat :: wildcard ( ty, pat. span ) ) . collect ( ) ;
371379 for pat in subpatterns {
@@ -380,7 +388,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
380388 // _)` or a box pattern. As a hack to avoid an ICE with the former, we
381389 // ignore other fields than the first one. This will trigger an error later
382390 // anyway.
383- // See https://github.com/rust-lang/rust/issues/82772 ,
391+ // See https://github.com/rust-lang/rust/issues/82772,
384392 // explanation: https://github.com/rust-lang/rust/pull/82789#issuecomment-796921977
385393 // The problem is that we can't know from the type whether we'll match
386394 // normally or through box-patterns. We'll have to figure out a proper
@@ -392,12 +400,13 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
392400 } else {
393401 DeconstructedPat :: wildcard ( args. type_at ( 0 ) , pat. span )
394402 } ;
395- ctor = Single ;
403+ ctor = Struct ;
396404 fields = singleton ( pat) ;
397405 }
398406 ty:: Adt ( adt, _) => {
399407 ctor = match pat. kind {
400- PatKind :: Leaf { .. } => Single ,
408+ PatKind :: Leaf { .. } if adt. is_union ( ) => UnionField ,
409+ PatKind :: Leaf { .. } => Struct ,
401410 PatKind :: Variant { variant_index, .. } => Variant ( variant_index) ,
402411 _ => bug ! ( ) ,
403412 } ;
@@ -477,11 +486,11 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
477486 // with other `Deref` patterns. This could have been done in `const_to_pat`,
478487 // but that causes issues with the rest of the matching code.
479488 // So here, the constructor for a `"foo"` pattern is `&` (represented by
480- // `Single `), and has one field. That field has constructor `Str(value)` and no
481- // fields .
489+ // `Ref `), and has one field. That field has constructor `Str(value)` and no
490+ // subfields .
482491 // Note: `t` is `str`, not `&str`.
483492 let subpattern = DeconstructedPat :: new ( Str ( * value) , & [ ] , * t, pat. span ) ;
484- ctor = Single ;
493+ ctor = Ref ;
485494 fields = singleton ( subpattern)
486495 }
487496 // All constants that can be structurally matched have already been expanded
@@ -657,7 +666,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
657666 let kind = match pat. ctor ( ) {
658667 Bool ( b) => PatKind :: Constant { value : mir:: Const :: from_bool ( cx. tcx , * b) } ,
659668 IntRange ( range) => return self . hoist_pat_range ( range, pat. ty ( ) ) ,
660- Single | Variant ( _) => match pat. ty ( ) . kind ( ) {
669+ Struct | Variant ( _) | UnionField => match pat. ty ( ) . kind ( ) {
661670 ty:: Tuple ( ..) => PatKind :: Leaf {
662671 subpatterns : subpatterns
663672 . enumerate ( )
@@ -686,13 +695,13 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
686695 PatKind :: Leaf { subpatterns }
687696 }
688697 }
689- // Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
690- // be careful to reconstruct the correct constant pattern here. However a string
691- // literal pattern will never be reported as a non-exhaustiveness witness, so we
692- // ignore this issue.
693- ty:: Ref ( ..) => PatKind :: Deref { subpattern : subpatterns. next ( ) . unwrap ( ) } ,
694698 _ => bug ! ( "unexpected ctor for type {:?} {:?}" , pat. ctor( ) , pat. ty( ) ) ,
695699 } ,
700+ // Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
701+ // be careful to reconstruct the correct constant pattern here. However a string
702+ // literal pattern will never be reported as a non-exhaustiveness witness, so we
703+ // ignore this issue.
704+ Ref => PatKind :: Deref { subpattern : subpatterns. next ( ) . unwrap ( ) } ,
696705 Slice ( slice) => {
697706 match slice. kind {
698707 SliceKind :: FixedLen ( _) => PatKind :: Slice {
@@ -758,7 +767,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
758767 let mut start_or_comma = || start_or_continue ( ", " ) ;
759768
760769 match pat. ctor ( ) {
761- Single | Variant ( _) => match pat. ty ( ) . kind ( ) {
770+ Struct | Variant ( _) | UnionField => match pat. ty ( ) . kind ( ) {
762771 ty:: Adt ( def, _) if def. is_box ( ) => {
763772 // Without `box_patterns`, the only legal pattern of type `Box` is `_` (outside
764773 // of `std`). So this branch is only reachable when the feature is enabled and
@@ -789,15 +798,15 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
789798 }
790799 write ! ( f, ")" )
791800 }
792- // Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
793- // be careful to detect strings here. However a string literal pattern will never
794- // be reported as a non-exhaustiveness witness, so we can ignore this issue.
795- ty:: Ref ( _, _, mutbl) => {
796- let subpattern = pat. iter_fields ( ) . next ( ) . unwrap ( ) ;
797- write ! ( f, "&{}{:?}" , mutbl. prefix_str( ) , subpattern)
798- }
799801 _ => write ! ( f, "_" ) ,
800802 } ,
803+ // Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
804+ // be careful to detect strings here. However a string literal pattern will never
805+ // be reported as a non-exhaustiveness witness, so we can ignore this issue.
806+ Ref => {
807+ let subpattern = pat. iter_fields ( ) . next ( ) . unwrap ( ) ;
808+ write ! ( f, "&{:?}" , subpattern)
809+ }
801810 Slice ( slice) => {
802811 let mut subpatterns = pat. iter_fields ( ) ;
803812 write ! ( f, "[" ) ?;
0 commit comments