@@ -105,7 +105,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
105
105
) -> VariantIdx {
106
106
match * ctor {
107
107
Variant ( idx) => idx,
108
- Single => {
108
+ Struct | UnionField => {
109
109
assert ! ( !adt. is_enum( ) ) ;
110
110
FIRST_VARIANT
111
111
}
@@ -123,9 +123,8 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
123
123
) -> & ' p [ DeconstructedPat < ' p , ' tcx > ] {
124
124
let cx = self ;
125
125
match ctor {
126
- Single | Variant ( _) => match ty. kind ( ) {
126
+ Struct | Variant ( _) | UnionField => match ty. kind ( ) {
127
127
ty:: Tuple ( fs) => cx. alloc_wildcard_slice ( fs. iter ( ) ) ,
128
- ty:: Ref ( _, rty, _) => cx. alloc_wildcard_slice ( once ( * rty) ) ,
129
128
ty:: Adt ( adt, args) => {
130
129
if adt. is_box ( ) {
131
130
// The only legal patterns of type `Box` (outside `std`) are `_` and box
@@ -138,7 +137,11 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
138
137
cx. alloc_wildcard_slice ( tys)
139
138
}
140
139
}
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:?}" ) ,
142
145
} ,
143
146
Slice ( slice) => match * ty. kind ( ) {
144
147
ty:: Slice ( ty) | ty:: Array ( ty, _) => {
@@ -167,9 +170,8 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
167
170
/// `Fields::wildcards`.
168
171
pub ( crate ) fn ctor_arity ( & self , ctor : & Constructor < ' tcx > , ty : Ty < ' tcx > ) -> usize {
169
172
match ctor {
170
- Single | Variant ( _) => match ty. kind ( ) {
173
+ Struct | Variant ( _) | UnionField => match ty. kind ( ) {
171
174
ty:: Tuple ( fs) => fs. len ( ) ,
172
- ty:: Ref ( ..) => 1 ,
173
175
ty:: Adt ( adt, ..) => {
174
176
if adt. is_box ( ) {
175
177
// The only legal patterns of type `Box` (outside `std`) are `_` and box
@@ -181,8 +183,9 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
181
183
self . list_variant_nonhidden_fields ( ty, variant) . count ( )
182
184
}
183
185
}
184
- _ => bug ! ( "Unexpected type for `Single` constructor : {:?}" , ty ) ,
186
+ _ => bug ! ( "Unexpected type for constructor `{ctor:?}` : {ty :?}" ) ,
185
187
} ,
188
+ Ref => 1 ,
186
189
Slice ( slice) => slice. arity ( ) ,
187
190
Bool ( ..)
188
191
| IntRange ( ..)
@@ -298,9 +301,9 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
298
301
ConstructorSet :: Variants { variants, non_exhaustive : is_declared_nonexhaustive }
299
302
}
300
303
}
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 ,
304
307
ty:: Never => ConstructorSet :: NoConstructors ,
305
308
// This type is one for which we cannot list constructors, like `str` or `f64`.
306
309
// FIXME(Nadrieril): which of these are actually allowed?
@@ -359,13 +362,18 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
359
362
fields = & [ ] ;
360
363
}
361
364
PatKind :: Deref { subpattern } => {
362
- ctor = Single ;
363
365
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
+ } ;
364
372
}
365
373
PatKind :: Leaf { subpatterns } | PatKind :: Variant { subpatterns, .. } => {
366
374
match pat. ty . kind ( ) {
367
375
ty:: Tuple ( fs) => {
368
- ctor = Single ;
376
+ ctor = Struct ;
369
377
let mut wilds: SmallVec < [ _ ; 2 ] > =
370
378
fs. iter ( ) . map ( |ty| DeconstructedPat :: wildcard ( ty, pat. span ) ) . collect ( ) ;
371
379
for pat in subpatterns {
@@ -380,7 +388,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
380
388
// _)` or a box pattern. As a hack to avoid an ICE with the former, we
381
389
// ignore other fields than the first one. This will trigger an error later
382
390
// anyway.
383
- // See https://github.com/rust-lang/rust/issues/82772 ,
391
+ // See https://github.com/rust-lang/rust/issues/82772,
384
392
// explanation: https://github.com/rust-lang/rust/pull/82789#issuecomment-796921977
385
393
// The problem is that we can't know from the type whether we'll match
386
394
// normally or through box-patterns. We'll have to figure out a proper
@@ -392,12 +400,13 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
392
400
} else {
393
401
DeconstructedPat :: wildcard ( args. type_at ( 0 ) , pat. span )
394
402
} ;
395
- ctor = Single ;
403
+ ctor = Struct ;
396
404
fields = singleton ( pat) ;
397
405
}
398
406
ty:: Adt ( adt, _) => {
399
407
ctor = match pat. kind {
400
- PatKind :: Leaf { .. } => Single ,
408
+ PatKind :: Leaf { .. } if adt. is_union ( ) => UnionField ,
409
+ PatKind :: Leaf { .. } => Struct ,
401
410
PatKind :: Variant { variant_index, .. } => Variant ( variant_index) ,
402
411
_ => bug ! ( ) ,
403
412
} ;
@@ -477,11 +486,11 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
477
486
// with other `Deref` patterns. This could have been done in `const_to_pat`,
478
487
// but that causes issues with the rest of the matching code.
479
488
// 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 .
482
491
// Note: `t` is `str`, not `&str`.
483
492
let subpattern = DeconstructedPat :: new ( Str ( * value) , & [ ] , * t, pat. span ) ;
484
- ctor = Single ;
493
+ ctor = Ref ;
485
494
fields = singleton ( subpattern)
486
495
}
487
496
// All constants that can be structurally matched have already been expanded
@@ -657,7 +666,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
657
666
let kind = match pat. ctor ( ) {
658
667
Bool ( b) => PatKind :: Constant { value : mir:: Const :: from_bool ( cx. tcx , * b) } ,
659
668
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 ( ) {
661
670
ty:: Tuple ( ..) => PatKind :: Leaf {
662
671
subpatterns : subpatterns
663
672
. enumerate ( )
@@ -686,13 +695,13 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
686
695
PatKind :: Leaf { subpatterns }
687
696
}
688
697
}
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 ( ) } ,
694
698
_ => bug ! ( "unexpected ctor for type {:?} {:?}" , pat. ctor( ) , pat. ty( ) ) ,
695
699
} ,
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 ( ) } ,
696
705
Slice ( slice) => {
697
706
match slice. kind {
698
707
SliceKind :: FixedLen ( _) => PatKind :: Slice {
@@ -758,7 +767,7 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
758
767
let mut start_or_comma = || start_or_continue ( ", " ) ;
759
768
760
769
match pat. ctor ( ) {
761
- Single | Variant ( _) => match pat. ty ( ) . kind ( ) {
770
+ Struct | Variant ( _) | UnionField => match pat. ty ( ) . kind ( ) {
762
771
ty:: Adt ( def, _) if def. is_box ( ) => {
763
772
// Without `box_patterns`, the only legal pattern of type `Box` is `_` (outside
764
773
// of `std`). So this branch is only reachable when the feature is enabled and
@@ -789,15 +798,15 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
789
798
}
790
799
write ! ( f, ")" )
791
800
}
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
- }
799
801
_ => write ! ( f, "_" ) ,
800
802
} ,
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
+ }
801
810
Slice ( slice) => {
802
811
let mut subpatterns = pat. iter_fields ( ) ;
803
812
write ! ( f, "[" ) ?;
0 commit comments