@@ -394,16 +394,6 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
394
394
}
395
395
}
396
396
397
- fn is_non_exhaustive_variant < ' p > ( & self , pattern : & ' p Pat < ' tcx > ) -> bool {
398
- match * pattern. kind {
399
- PatKind :: Variant { adt_def, variant_index, .. } => {
400
- let ref variant = adt_def. variants [ variant_index] ;
401
- variant. is_field_list_non_exhaustive ( )
402
- }
403
- _ => false ,
404
- }
405
- }
406
-
407
397
fn is_non_exhaustive_enum ( & self , ty : Ty < ' tcx > ) -> bool {
408
398
match ty. kind {
409
399
ty:: Adt ( adt_def, ..) => adt_def. is_variant_list_non_exhaustive ( ) ,
@@ -1252,19 +1242,12 @@ pub fn is_useful<'p, 'a, 'tcx>(
1252
1242
debug ! ( "is_useful_expand_first_col: pcx={:#?}, expanding {:#?}" , pcx, v[ 0 ] ) ;
1253
1243
1254
1244
if let Some ( constructors) = pat_constructors ( cx, v[ 0 ] , pcx) {
1255
- let is_declared_nonexhaustive = cx. is_non_exhaustive_variant ( v[ 0 ] ) && !cx. is_local ( pcx. ty ) ;
1256
- debug ! ( "is_useful - expanding constructors: {:#?}, is_declared_nonexhaustive: {:?}" ,
1257
- constructors, is_declared_nonexhaustive) ;
1258
-
1259
- if is_declared_nonexhaustive {
1260
- Useful
1261
- } else {
1262
- split_grouped_constructors (
1263
- cx. tcx , cx. param_env , constructors, matrix, pcx. ty , pcx. span , Some ( hir_id) ,
1264
- ) . into_iter ( ) . map ( |c|
1265
- is_useful_specialized ( cx, matrix, v, c, pcx. ty , witness, hir_id)
1266
- ) . find ( |result| result. is_useful ( ) ) . unwrap_or ( NotUseful )
1267
- }
1245
+ debug ! ( "is_useful - expanding constructors: {:#?}" , constructors) ;
1246
+ split_grouped_constructors (
1247
+ cx. tcx , cx. param_env , constructors, matrix, pcx. ty , pcx. span , Some ( hir_id) ,
1248
+ ) . into_iter ( ) . map ( |c|
1249
+ is_useful_specialized ( cx, matrix, v, c, pcx. ty , witness, hir_id)
1250
+ ) . find ( |result| result. is_useful ( ) ) . unwrap_or ( NotUseful )
1268
1251
} else {
1269
1252
debug ! ( "is_useful - expanding wildcard" ) ;
1270
1253
@@ -1548,27 +1531,30 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
1548
1531
// Use T as the sub pattern type of Box<T>.
1549
1532
vec ! [ substs. type_at( 0 ) ]
1550
1533
} else {
1551
- adt. variants [ ctor. variant_index_for_adt ( cx, adt) ] . fields . iter ( ) . map ( |field| {
1534
+ let variant = & adt. variants [ ctor. variant_index_for_adt ( cx, adt) ] ;
1535
+ let is_non_exhaustive = variant. is_field_list_non_exhaustive ( ) && !cx. is_local ( ty) ;
1536
+ variant. fields . iter ( ) . map ( |field| {
1552
1537
let is_visible = adt. is_enum ( )
1553
1538
|| field. vis . is_accessible_from ( cx. module , cx. tcx ) ;
1554
- if is_visible {
1555
- let ty = field. ty ( cx. tcx , substs) ;
1556
- match ty. kind {
1557
- // If the field type returned is an array of an unknown
1558
- // size return an TyErr.
1559
- ty:: Array ( _, len)
1560
- if len. try_eval_usize ( cx. tcx , cx. param_env ) . is_none ( ) =>
1561
- cx. tcx . types . err ,
1562
- _ => ty,
1563
- }
1564
- } else {
1565
- // Treat all non-visible fields as TyErr. They
1566
- // can't appear in any other pattern from
1567
- // this match (because they are private),
1568
- // so their type does not matter - but
1569
- // we don't want to know they are
1570
- // uninhabited.
1571
- cx. tcx . types . err
1539
+ let is_uninhabited = cx. is_uninhabited ( field. ty ( cx. tcx , substs) ) ;
1540
+ match ( is_visible, is_non_exhaustive, is_uninhabited) {
1541
+ // Treat all uninhabited types in non-exhaustive variants as `TyErr`.
1542
+ ( _, true , true ) => cx. tcx . types . err ,
1543
+ // Treat all non-visible fields as `TyErr`. They can't appear in any
1544
+ // other pattern from this match (because they are private), so their
1545
+ // type does not matter - but we don't want to know they are uninhabited.
1546
+ ( false , ..) => cx. tcx . types . err ,
1547
+ ( true , ..) => {
1548
+ let ty = field. ty ( cx. tcx , substs) ;
1549
+ match ty. kind {
1550
+ // If the field type returned is an array of an unknown
1551
+ // size return an TyErr.
1552
+ ty:: Array ( _, len)
1553
+ if len. try_eval_usize ( cx. tcx , cx. param_env ) . is_none ( ) =>
1554
+ cx. tcx . types . err ,
1555
+ _ => ty,
1556
+ }
1557
+ } ,
1572
1558
}
1573
1559
} ) . collect ( )
1574
1560
}
@@ -1874,15 +1860,18 @@ fn constructor_covered_by_range<'tcx>(
1874
1860
}
1875
1861
}
1876
1862
1877
- fn patterns_for_variant < ' p , ' tcx > (
1863
+ fn patterns_for_variant < ' p , ' a : ' p , ' tcx > (
1864
+ cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
1878
1865
subpatterns : & ' p [ FieldPat < ' tcx > ] ,
1879
- wild_patterns : & [ & ' p Pat < ' tcx > ] )
1880
- -> SmallVec < [ & ' p Pat < ' tcx > ; 2 ] >
1881
- {
1866
+ wild_patterns : & [ & ' p Pat < ' tcx > ] ,
1867
+ is_non_exhaustive : bool ,
1868
+ ) -> SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > {
1882
1869
let mut result = SmallVec :: from_slice ( wild_patterns) ;
1883
1870
1884
1871
for subpat in subpatterns {
1885
- result[ subpat. field . index ( ) ] = & subpat. pattern ;
1872
+ if !is_non_exhaustive || !cx. is_uninhabited ( subpat. pattern . ty ) {
1873
+ result[ subpat. field . index ( ) ] = & subpat. pattern ;
1874
+ }
1886
1875
}
1887
1876
1888
1877
debug ! ( "patterns_for_variant({:#?}, {:#?}) = {:#?}" , subpatterns, wild_patterns, result) ;
@@ -1916,13 +1905,14 @@ fn specialize<'p, 'a: 'p, 'tcx>(
1916
1905
1917
1906
PatKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
1918
1907
let ref variant = adt_def. variants [ variant_index] ;
1908
+ let is_non_exhaustive = variant. is_field_list_non_exhaustive ( ) && !cx. is_local ( pat. ty ) ;
1919
1909
Some ( Variant ( variant. def_id ) )
1920
1910
. filter ( |variant_constructor| variant_constructor == constructor)
1921
- . map ( |_| patterns_for_variant ( subpatterns, wild_patterns) )
1911
+ . map ( |_| patterns_for_variant ( cx , subpatterns, wild_patterns, is_non_exhaustive ) )
1922
1912
}
1923
1913
1924
1914
PatKind :: Leaf { ref subpatterns } => {
1925
- Some ( patterns_for_variant ( subpatterns, wild_patterns) )
1915
+ Some ( patterns_for_variant ( cx , subpatterns, wild_patterns, false ) )
1926
1916
}
1927
1917
1928
1918
PatKind :: Deref { ref subpattern } => {
0 commit comments