@@ -620,6 +620,27 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
620620 _ => false ,
621621 }
622622 }
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+ }
623644}
624645
625646#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
@@ -881,30 +902,19 @@ impl<'tcx> Constructor<'tcx> {
881902 vec ! [ Pat :: wildcard_from_ty( substs. type_at( 0 ) ) ]
882903 } else {
883904 let variant = & adt. variants [ self . variant_index_for_adt ( cx, adt) ] ;
884- let is_non_exhaustive = cx. is_foreign_non_exhaustive_variant ( ty, variant) ;
885905 variant
886906 . fields
887907 . iter ( )
888908 . 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
904913 } else {
905- Pat :: wildcard_from_ty ( cx. tcx . types . err )
914+ field . ty ( cx. tcx , substs )
906915 }
907916 } )
917+ . map ( Pat :: wildcard_from_ty)
908918 . collect ( )
909919 }
910920 }
0 commit comments