@@ -238,7 +238,7 @@ use super::{FieldPat, Pat, PatKind, PatRange};
238
238
use rustc:: hir:: def_id:: DefId ;
239
239
use rustc:: hir:: { HirId , RangeEnd } ;
240
240
use rustc:: ty:: layout:: { Integer , IntegerExt , Size , VariantIdx } ;
241
- use rustc:: ty:: { self , Const , Ty , TyCtxt , TypeFoldable } ;
241
+ use rustc:: ty:: { self , Const , Ty , TyCtxt , TypeFoldable , VariantDef } ;
242
242
243
243
use rustc:: lint;
244
244
use rustc:: mir:: interpret:: { truncate, AllocId , ConstValue , Pointer , Scalar } ;
@@ -596,9 +596,21 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
596
596
}
597
597
}
598
598
599
- fn is_local ( & self , ty : Ty < ' tcx > ) -> bool {
599
+ // Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`.
600
+ pub fn is_foreign_non_exhaustive_enum ( & self , ty : Ty < ' tcx > ) -> bool {
600
601
match ty. kind {
601
- ty:: Adt ( adt_def, ..) => adt_def. did . is_local ( ) ,
602
+ ty:: Adt ( def, ..) => {
603
+ def. is_enum ( ) && def. is_variant_list_non_exhaustive ( ) && !def. did . is_local ( )
604
+ }
605
+ _ => false ,
606
+ }
607
+ }
608
+
609
+ // Returns whether the given variant is from another crate and has its fields declared
610
+ // `#[non_exhaustive]`.
611
+ fn is_foreign_non_exhaustive_variant ( & self , ty : Ty < ' tcx > , variant : & VariantDef ) -> bool {
612
+ match ty. kind {
613
+ ty:: Adt ( def, ..) => variant. is_field_list_non_exhaustive ( ) && !def. did . is_local ( ) ,
602
614
_ => false ,
603
615
}
604
616
}
@@ -858,8 +870,7 @@ impl<'tcx> Constructor<'tcx> {
858
870
vec ! [ Pat :: wildcard_from_ty( substs. type_at( 0 ) ) ]
859
871
} else {
860
872
let variant = & adt. variants [ self . variant_index_for_adt ( cx, adt) ] ;
861
- let is_non_exhaustive =
862
- variant. is_field_list_non_exhaustive ( ) && !cx. is_local ( ty) ;
873
+ let is_non_exhaustive = cx. is_foreign_non_exhaustive_variant ( ty, variant) ;
863
874
variant
864
875
. fields
865
876
. iter ( )
@@ -1264,8 +1275,7 @@ fn all_constructors<'a, 'tcx>(
1264
1275
// ```
1265
1276
// we don't want to show every possible IO error, but instead have only `_` as the
1266
1277
// witness.
1267
- let is_declared_nonexhaustive =
1268
- def. is_variant_list_non_exhaustive ( ) && !cx. is_local ( pcx. ty ) ;
1278
+ let is_declared_nonexhaustive = cx. is_foreign_non_exhaustive_enum ( pcx. ty ) ;
1269
1279
1270
1280
// If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
1271
1281
// as though it had an "unknown" constructor to avoid exposing its emptyness. Note that
@@ -2307,7 +2317,7 @@ fn specialize_one_pattern<'p, 'tcx>(
2307
2317
2308
2318
PatKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
2309
2319
let ref variant = adt_def. variants [ variant_index] ;
2310
- let is_non_exhaustive = variant . is_field_list_non_exhaustive ( ) && ! cx. is_local ( pat. ty ) ;
2320
+ let is_non_exhaustive = cx. is_foreign_non_exhaustive_variant ( pat. ty , variant ) ;
2311
2321
Some ( Variant ( variant. def_id ) )
2312
2322
. filter ( |variant_constructor| variant_constructor == constructor)
2313
2323
. map ( |_| {
0 commit comments