@@ -1508,22 +1508,10 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
15081508
15091509    let  typing_env = ty:: TypingEnv :: non_body_analysis ( tcx,  adt. did ( ) ) ; 
15101510    // For each field, figure out if it has "trivial" layout (i.e., is a 1-ZST). 
1511-     // Even some 1-ZST fields are not allowed though, if they have `non_exhaustive` or private 
1512-     // fields or `repr(C)`. We call those fields "unsuited". 
15131511    struct  FieldInfo < ' tcx >  { 
15141512        span :  Span , 
15151513        trivial :  bool , 
1516-         unsuited :  Option < UnsuitedInfo < ' tcx > > , 
1517-     } 
1518-     struct  UnsuitedInfo < ' tcx >  { 
1519-         /// The source of the problem, a type that is found somewhere within the field type. 
15201514        ty :  Ty < ' tcx > , 
1521-         reason :  UnsuitedReason , 
1522-     } 
1523-     enum  UnsuitedReason  { 
1524-         NonExhaustive , 
1525-         PrivateField , 
1526-         ReprC , 
15271515    } 
15281516
15291517    let  field_infos = adt. all_fields ( ) . map ( |field| { 
@@ -1532,60 +1520,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
15321520        // We are currently checking the type this field came from, so it must be local 
15331521        let  span = tcx. hir_span_if_local ( field. did ) . unwrap ( ) ; 
15341522        let  trivial = layout. is_ok_and ( |layout| layout. is_1zst ( ) ) ; 
1535-         if  !trivial { 
1536-             // No need to even compute `unsuited`. 
1537-             return  FieldInfo  {  span,  trivial,  unsuited :  None  } ; 
1538-         } 
1539- 
1540-         fn  check_unsuited < ' tcx > ( 
1541-             tcx :  TyCtxt < ' tcx > , 
1542-             typing_env :  ty:: TypingEnv < ' tcx > , 
1543-             ty :  Ty < ' tcx > , 
1544-         )  -> ControlFlow < UnsuitedInfo < ' tcx > >  { 
1545-             // We can encounter projections during traversal, so ensure the type is normalized. 
1546-             let  ty = tcx. try_normalize_erasing_regions ( typing_env,  ty) . unwrap_or ( ty) ; 
1547-             match  ty. kind ( )  { 
1548-                 ty:: Tuple ( list)  => list. iter ( ) . try_for_each ( |t| check_unsuited ( tcx,  typing_env,  t) ) , 
1549-                 ty:: Array ( ty,  _)  => check_unsuited ( tcx,  typing_env,  * ty) , 
1550-                 ty:: Adt ( def,  args)  => { 
1551-                     if  !def. did ( ) . is_local ( ) 
1552-                         && !find_attr ! ( 
1553-                             tcx. get_all_attrs( def. did( ) ) , 
1554-                             AttributeKind :: PubTransparent ( _) 
1555-                         ) 
1556-                     { 
1557-                         let  non_exhaustive = def. is_variant_list_non_exhaustive ( ) 
1558-                             || def
1559-                                 . variants ( ) 
1560-                                 . iter ( ) 
1561-                                 . any ( ty:: VariantDef :: is_field_list_non_exhaustive) ; 
1562-                         let  has_priv = def. all_fields ( ) . any ( |f| !f. vis . is_public ( ) ) ; 
1563-                         if  non_exhaustive || has_priv { 
1564-                             return  ControlFlow :: Break ( UnsuitedInfo  { 
1565-                                 ty, 
1566-                                 reason :  if  non_exhaustive { 
1567-                                     UnsuitedReason :: NonExhaustive 
1568-                                 }  else  { 
1569-                                     UnsuitedReason :: PrivateField 
1570-                                 } , 
1571-                             } ) ; 
1572-                         } 
1573-                     } 
1574-                     if  def. repr ( ) . c ( )  { 
1575-                         return  ControlFlow :: Break ( UnsuitedInfo  { 
1576-                             ty, 
1577-                             reason :  UnsuitedReason :: ReprC , 
1578-                         } ) ; 
1579-                     } 
1580-                     def. all_fields ( ) 
1581-                         . map ( |field| field. ty ( tcx,  args) ) 
1582-                         . try_for_each ( |t| check_unsuited ( tcx,  typing_env,  t) ) 
1583-                 } 
1584-                 _ => ControlFlow :: Continue ( ( ) ) , 
1585-             } 
1586-         } 
1587- 
1588-         FieldInfo  {  span,  trivial,  unsuited :  check_unsuited ( tcx,  typing_env,  ty) . break_value ( )  } 
1523+         return  FieldInfo  {  span,  trivial,  ty } ; 
15891524    } ) ; 
15901525
15911526    let  non_trivial_fields = field_infos
@@ -1603,10 +1538,63 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
16031538        return ; 
16041539    } 
16051540
1541+     // Even some 1-ZST fields are not allowed though, if they have `non_exhaustive` or private 
1542+     // fields or `repr(C)`. We call those fields "unsuited". 
1543+     struct  UnsuitedInfo < ' tcx >  { 
1544+         /// The source of the problem, a type that is found somewhere within the field type. 
1545+          ty :  Ty < ' tcx > , 
1546+         reason :  UnsuitedReason , 
1547+     } 
1548+     enum  UnsuitedReason  { 
1549+         NonExhaustive , 
1550+         PrivateField , 
1551+         ReprC , 
1552+     } 
1553+ 
1554+     fn  check_unsuited < ' tcx > ( 
1555+         tcx :  TyCtxt < ' tcx > , 
1556+         typing_env :  ty:: TypingEnv < ' tcx > , 
1557+         ty :  Ty < ' tcx > , 
1558+     )  -> ControlFlow < UnsuitedInfo < ' tcx > >  { 
1559+         // We can encounter projections during traversal, so ensure the type is normalized. 
1560+         let  ty = tcx. try_normalize_erasing_regions ( typing_env,  ty) . unwrap_or ( ty) ; 
1561+         match  ty. kind ( )  { 
1562+             ty:: Tuple ( list)  => list. iter ( ) . try_for_each ( |t| check_unsuited ( tcx,  typing_env,  t) ) , 
1563+             ty:: Array ( ty,  _)  => check_unsuited ( tcx,  typing_env,  * ty) , 
1564+             ty:: Adt ( def,  args)  => { 
1565+                 if  !def. did ( ) . is_local ( ) 
1566+                     && !find_attr ! ( tcx. get_all_attrs( def. did( ) ) ,  AttributeKind :: PubTransparent ( _) ) 
1567+                 { 
1568+                     let  non_exhaustive = def. is_variant_list_non_exhaustive ( ) 
1569+                         || def. variants ( ) . iter ( ) . any ( ty:: VariantDef :: is_field_list_non_exhaustive) ; 
1570+                     let  has_priv = def. all_fields ( ) . any ( |f| !f. vis . is_public ( ) ) ; 
1571+                     if  non_exhaustive || has_priv { 
1572+                         return  ControlFlow :: Break ( UnsuitedInfo  { 
1573+                             ty, 
1574+                             reason :  if  non_exhaustive { 
1575+                                 UnsuitedReason :: NonExhaustive 
1576+                             }  else  { 
1577+                                 UnsuitedReason :: PrivateField 
1578+                             } , 
1579+                         } ) ; 
1580+                     } 
1581+                 } 
1582+                 if  def. repr ( ) . c ( )  { 
1583+                     return  ControlFlow :: Break ( UnsuitedInfo  {  ty,  reason :  UnsuitedReason :: ReprC  } ) ; 
1584+                 } 
1585+                 def. all_fields ( ) 
1586+                     . map ( |field| field. ty ( tcx,  args) ) 
1587+                     . try_for_each ( |t| check_unsuited ( tcx,  typing_env,  t) ) 
1588+             } 
1589+             _ => ControlFlow :: Continue ( ( ) ) , 
1590+         } 
1591+     } 
1592+ 
16061593    let  mut  prev_unsuited_1zst = false ; 
16071594    for  field in  field_infos { 
1608-         if  let  Some ( unsuited)  = field. unsuited  { 
1609-             assert ! ( field. trivial) ; 
1595+         if  field. trivial 
1596+             && let  Some ( unsuited)  = check_unsuited ( tcx,  typing_env,  field. ty ) . break_value ( ) 
1597+         { 
16101598            // If there are any non-trivial fields, then there can be no non-exhaustive 1-zsts. 
16111599            // Otherwise, it's only an issue if there's >1 non-exhaustive 1-zst. 
16121600            if  non_trivial_count > 0  || prev_unsuited_1zst { 
0 commit comments