@@ -11,7 +11,7 @@ use rustc_index::vec::Idx;
1111use rustc_middle:: mir:: interpret:: { sign_extend, truncate} ;
1212use rustc_middle:: ty:: layout:: { IntegerExt , SizeSkeleton } ;
1313use rustc_middle:: ty:: subst:: SubstsRef ;
14- use rustc_middle:: ty:: { self , AdtKind , Ty , TyCtxt , TypeFoldable } ;
14+ use rustc_middle:: ty:: { self , AdtKind , Ty , TypeFoldable } ;
1515use rustc_span:: source_map;
1616use rustc_span:: symbol:: sym;
1717use rustc_span:: { Span , DUMMY_SP } ;
@@ -550,25 +550,26 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
550550 _ => false ,
551551 }
552552}
553- /// Given a potentially non-null type `ty`, return its default, nullable type.
554- fn get_nullable_type < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
555- match ty. kind {
553+ /// Given a non-null scalar (or transparent) type `ty`, return the nullable version of that type.
554+ /// If the type passed in was not scalar, returns None.
555+ fn get_nullable_type < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> Option < Ty < ' tcx > > {
556+ let tcx = cx. tcx ;
557+ Some ( match ty. kind {
556558 ty:: Adt ( field_def, field_substs) => {
557- let field_variants = & field_def. variants ;
558- // We hit this case for #[repr(transparent)] structs with a single
559- // field.
560- debug_assert ! (
561- field_variants. len( ) == 1 && field_variants[ VariantIdx :: new( 0 ) ] . fields. len( ) == 1 ,
562- "inner ty not a newtype struct"
563- ) ;
564- debug_assert ! ( field_def. repr. transparent( ) , "inner ty not transparent" ) ;
565- // As it's easy to get this wrong, it's worth noting that
566- // `inner_field_ty` is not the same as `field_ty`: Given Option<S>,
567- // where S is a transparent newtype of some type T, `field_ty`
568- // gives us S, while `inner_field_ty` is T.
569- let inner_field_ty =
570- field_def. variants [ VariantIdx :: new ( 0 ) ] . fields [ 0 ] . ty ( tcx, field_substs) ;
571- get_nullable_type ( tcx, inner_field_ty)
559+ let inner_field_ty = {
560+ let mut first_non_zst_ty = field_def. all_fields ( ) . filter_map ( |f| {
561+ let field_ty =
562+ tcx. normalize_erasing_regions ( cx. param_env , f. ty ( tcx, field_substs) ) ;
563+ if !field_ty. is_zst ( tcx, f. did ) { Some ( field_ty) } else { None }
564+ } ) ;
565+ debug_assert_eq ! (
566+ first_non_zst_ty. clone( ) . count( ) ,
567+ 1 ,
568+ "Wrong number of fields for transparent type"
569+ ) ;
570+ first_non_zst_ty. next ( ) . expect ( "No non-zst fields in transparent type." )
571+ } ;
572+ return get_nullable_type ( cx, inner_field_ty) ;
572573 }
573574 ty:: Int ( ty) => tcx. mk_mach_int ( ty) ,
574575 ty:: Uint ( ty) => tcx. mk_mach_uint ( ty) ,
@@ -585,9 +586,13 @@ fn get_nullable_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
585586 // We should only ever reach this case if ty_is_known_nonnull is extended
586587 // to other types.
587588 ref unhandled => {
588- unreachable ! ( "Unhandled scalar kind: {:?} while checking {:?}" , unhandled, ty)
589+ debug ! (
590+ "get_nullable_type: Unhandled scalar kind: {:?} while checking {:?}" ,
591+ unhandled, ty
592+ ) ;
593+ return None ;
589594 }
590- }
595+ } )
591596}
592597
593598/// Check if this `ty` can be safely exported based on the "nullable pointer optimization".
@@ -633,9 +638,9 @@ crate fn repr_nullable_ptr<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option
633638 let field_ty_abi = & cx. layout_of ( field_ty) . unwrap ( ) . abi ;
634639 if let Abi :: Scalar ( field_ty_scalar) = field_ty_abi {
635640 match ( field_ty_scalar. valid_range . start ( ) , field_ty_scalar. valid_range . end ( ) ) {
636- ( 0 , _) => bug ! ( "Non-null optimisation extended to a non-zero value." ) ,
641+ ( 0 , _) => unreachable ! ( "Non-null optimisation extended to a non-zero value." ) ,
637642 ( 1 , _) => {
638- return Some ( get_nullable_type ( cx. tcx , field_ty) ) ;
643+ return Some ( get_nullable_type ( cx, field_ty) . unwrap ( ) ) ;
639644 }
640645 ( start, end) => unreachable ! ( "Unhandled start and end range: ({}, {})" , start, end) ,
641646 } ;
0 commit comments