@@ -394,16 +394,6 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
394394 }
395395 }
396396
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-
407397 fn is_non_exhaustive_enum ( & self , ty : Ty < ' tcx > ) -> bool {
408398 match ty. kind {
409399 ty:: Adt ( adt_def, ..) => adt_def. is_variant_list_non_exhaustive ( ) ,
@@ -1252,19 +1242,12 @@ pub fn is_useful<'p, 'a, 'tcx>(
12521242 debug ! ( "is_useful_expand_first_col: pcx={:#?}, expanding {:#?}" , pcx, v[ 0 ] ) ;
12531243
12541244 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 )
12681251 } else {
12691252 debug ! ( "is_useful - expanding wildcard" ) ;
12701253
@@ -1548,27 +1531,30 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
15481531 // Use T as the sub pattern type of Box<T>.
15491532 vec ! [ substs. type_at( 0 ) ]
15501533 } 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| {
15521537 let is_visible = adt. is_enum ( )
15531538 || 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+ } ,
15721558 }
15731559 } ) . collect ( )
15741560 }
@@ -1874,15 +1860,18 @@ fn constructor_covered_by_range<'tcx>(
18741860 }
18751861}
18761862
1877- fn patterns_for_variant < ' p , ' tcx > (
1863+ fn patterns_for_variant < ' p , ' a : ' p , ' tcx > (
1864+ cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
18781865 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 ] > {
18821869 let mut result = SmallVec :: from_slice ( wild_patterns) ;
18831870
18841871 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+ }
18861875 }
18871876
18881877 debug ! ( "patterns_for_variant({:#?}, {:#?}) = {:#?}" , subpatterns, wild_patterns, result) ;
@@ -1916,13 +1905,14 @@ fn specialize<'p, 'a: 'p, 'tcx>(
19161905
19171906 PatKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
19181907 let ref variant = adt_def. variants [ variant_index] ;
1908+ let is_non_exhaustive = variant. is_field_list_non_exhaustive ( ) && !cx. is_local ( pat. ty ) ;
19191909 Some ( Variant ( variant. def_id ) )
19201910 . 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 ) )
19221912 }
19231913
19241914 PatKind :: Leaf { ref subpatterns } => {
1925- Some ( patterns_for_variant ( subpatterns, wild_patterns) )
1915+ Some ( patterns_for_variant ( cx , subpatterns, wild_patterns, false ) )
19261916 }
19271917
19281918 PatKind :: Deref { ref subpattern } => {
0 commit comments