@@ -620,6 +620,27 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
620
620
_ => false ,
621
621
}
622
622
}
623
+
624
+ /// In the cases of either a `#[non_exhaustive]` field list or a non-public field, we hide
625
+ /// uninhabited fields in order not to reveal the uninhabitedness of the whole variant.
626
+ fn hide_uninhabited_field (
627
+ & self ,
628
+ adt_ty : Ty < ' tcx > ,
629
+ variant : & VariantDef ,
630
+ field : & FieldDef ,
631
+ ) -> bool {
632
+ match adt_ty. kind {
633
+ ty:: Adt ( def, substs) => {
634
+ let is_non_exhaustive = self . is_foreign_non_exhaustive_variant ( adt_ty, variant) ;
635
+ let field_ty = field. ty ( self . tcx , substs) ;
636
+ let is_visible =
637
+ adt. is_enum ( ) || field. vis . is_accessible_from ( self . module , self . tcx ) ;
638
+ let is_uninhabited = self . is_uninhabited ( field_ty) ;
639
+ is_uninhabited && ( !is_visible || is_non_exhaustive)
640
+ }
641
+ _ => false ,
642
+ }
643
+ }
623
644
}
624
645
625
646
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
@@ -881,30 +902,19 @@ impl<'tcx> Constructor<'tcx> {
881
902
vec ! [ Pat :: wildcard_from_ty( substs. type_at( 0 ) ) ]
882
903
} else {
883
904
let variant = & adt. variants [ self . variant_index_for_adt ( cx, adt) ] ;
884
- let is_non_exhaustive = cx. is_foreign_non_exhaustive_variant ( ty, variant) ;
885
905
variant
886
906
. fields
887
907
. iter ( )
888
908
. map ( |field| {
889
- let ty = field. ty ( cx. tcx , substs) ;
890
- let is_visible = adt. is_enum ( )
891
- || field. vis . is_accessible_from ( cx. module , cx. tcx ) ;
892
- let is_inhabited = !cx. is_uninhabited ( ty) ;
893
- // Treat all uninhabited non-visible fields as `TyErr`. They can't
894
- // appear in any other pattern from this match (because they are
895
- // private), so their type does not matter - but we don't want
896
- // to know they are uninhabited.
897
- // Also treat all uninhabited types in non-exhaustive variants as
898
- // `TyErr`.
899
- let allowed_to_inspect =
900
- is_inhabited || ( is_visible && !is_non_exhaustive) ;
901
-
902
- if allowed_to_inspect {
903
- Pat :: wildcard_from_ty ( ty)
909
+ // Treat hidden fields as TyErr so we don't know they are
910
+ // uninhabited.
911
+ if cx. hide_uninhabited_field ( ty, variant, field) {
912
+ cx. tcx . types . err
904
913
} else {
905
- Pat :: wildcard_from_ty ( cx. tcx . types . err )
914
+ field . ty ( cx. tcx , substs )
906
915
}
907
916
} )
917
+ . map ( Pat :: wildcard_from_ty)
908
918
. collect ( )
909
919
}
910
920
}
0 commit comments