@@ -907,9 +907,8 @@ fn get_nullable_type<'tcx>(
907907 } ;
908908 return get_nullable_type ( tcx, typing_env, inner_field_ty) ;
909909 }
910- ty:: Int ( ty) => Ty :: new_int ( tcx, ty) ,
911- ty:: Uint ( ty) => Ty :: new_uint ( tcx, ty) ,
912- ty:: RawPtr ( ty, mutbl) => Ty :: new_ptr ( tcx, ty, mutbl) ,
910+ ty:: Pat ( base, ..) => return get_nullable_type ( tcx, typing_env, base) ,
911+ ty:: Int ( _) | ty:: Uint ( _) | ty:: RawPtr ( ..) => ty,
913912 // As these types are always non-null, the nullable equivalent of
914913 // `Option<T>` of these types are their raw pointer counterparts.
915914 ty:: Ref ( _region, ty, mutbl) => Ty :: new_ptr ( tcx, ty, mutbl) ,
@@ -965,63 +964,69 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
965964 ckind : CItemKind ,
966965) -> Option < Ty < ' tcx > > {
967966 debug ! ( "is_repr_nullable_ptr(tcx, ty = {:?})" , ty) ;
968- if let ty:: Adt ( ty_def, args) = ty. kind ( ) {
969- let field_ty = match & ty_def. variants ( ) . raw [ ..] {
970- [ var_one, var_two] => match ( & var_one. fields . raw [ ..] , & var_two. fields . raw [ ..] ) {
971- ( [ ] , [ field] ) | ( [ field] , [ ] ) => field. ty ( tcx, args) ,
972- ( [ field1] , [ field2] ) => {
973- let ty1 = field1. ty ( tcx, args) ;
974- let ty2 = field2. ty ( tcx, args) ;
975-
976- if is_niche_optimization_candidate ( tcx, typing_env, ty1) {
977- ty2
978- } else if is_niche_optimization_candidate ( tcx, typing_env, ty2) {
979- ty1
980- } else {
981- return None ;
967+ match ty. kind ( ) {
968+ ty:: Adt ( ty_def, args) => {
969+ let field_ty = match & ty_def. variants ( ) . raw [ ..] {
970+ [ var_one, var_two] => match ( & var_one. fields . raw [ ..] , & var_two. fields . raw [ ..] ) {
971+ ( [ ] , [ field] ) | ( [ field] , [ ] ) => field. ty ( tcx, args) ,
972+ ( [ field1] , [ field2] ) => {
973+ let ty1 = field1. ty ( tcx, args) ;
974+ let ty2 = field2. ty ( tcx, args) ;
975+
976+ if is_niche_optimization_candidate ( tcx, typing_env, ty1) {
977+ ty2
978+ } else if is_niche_optimization_candidate ( tcx, typing_env, ty2) {
979+ ty1
980+ } else {
981+ return None ;
982+ }
982983 }
983- }
984+ _ => return None ,
985+ } ,
984986 _ => return None ,
985- } ,
986- _ => return None ,
987- } ;
987+ } ;
988988
989- if !ty_is_known_nonnull ( tcx, typing_env, field_ty, ckind) {
990- return None ;
991- }
989+ if !ty_is_known_nonnull ( tcx, typing_env, field_ty, ckind) {
990+ return None ;
991+ }
992992
993- // At this point, the field's type is known to be nonnull and the parent enum is Option-like.
994- // If the computed size for the field and the enum are different, the nonnull optimization isn't
995- // being applied (and we've got a problem somewhere).
996- let compute_size_skeleton = |t| SizeSkeleton :: compute ( t, tcx, typing_env) . ok ( ) ;
997- if !compute_size_skeleton ( ty) ?. same_size ( compute_size_skeleton ( field_ty) ?) {
998- bug ! ( "improper_ctypes: Option nonnull optimization not applied?" ) ;
999- }
993+ // At this point, the field's type is known to be nonnull and the parent enum is Option-like.
994+ // If the computed size for the field and the enum are different, the nonnull optimization isn't
995+ // being applied (and we've got a problem somewhere).
996+ let compute_size_skeleton = |t| SizeSkeleton :: compute ( t, tcx, typing_env) . ok ( ) ;
997+ if !compute_size_skeleton ( ty) ?. same_size ( compute_size_skeleton ( field_ty) ?) {
998+ bug ! ( "improper_ctypes: Option nonnull optimization not applied?" ) ;
999+ }
10001000
1001- // Return the nullable type this Option-like enum can be safely represented with.
1002- let field_ty_layout = tcx. layout_of ( typing_env. as_query_input ( field_ty) ) ;
1003- if field_ty_layout. is_err ( ) && !field_ty. has_non_region_param ( ) {
1004- bug ! ( "should be able to compute the layout of non-polymorphic type" ) ;
1005- }
1001+ // Return the nullable type this Option-like enum can be safely represented with.
1002+ let field_ty_layout = tcx. layout_of ( typing_env. as_query_input ( field_ty) ) ;
1003+ if field_ty_layout. is_err ( ) && !field_ty. has_non_region_param ( ) {
1004+ bug ! ( "should be able to compute the layout of non-polymorphic type" ) ;
1005+ }
10061006
1007- let field_ty_abi = & field_ty_layout. ok ( ) ?. backend_repr ;
1008- if let BackendRepr :: Scalar ( field_ty_scalar) = field_ty_abi {
1009- match field_ty_scalar. valid_range ( & tcx) {
1010- WrappingRange { start : 0 , end }
1011- if end == field_ty_scalar. size ( & tcx) . unsigned_int_max ( ) - 1 =>
1012- {
1013- return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
1014- }
1015- WrappingRange { start : 1 , .. } => {
1016- return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
1017- }
1018- WrappingRange { start, end } => {
1019- unreachable ! ( "Unhandled start and end range: ({}, {})" , start, end)
1020- }
1021- } ;
1007+ let field_ty_abi = & field_ty_layout. ok ( ) ?. backend_repr ;
1008+ if let BackendRepr :: Scalar ( field_ty_scalar) = field_ty_abi {
1009+ match field_ty_scalar. valid_range ( & tcx) {
1010+ WrappingRange { start : 0 , end }
1011+ if end == field_ty_scalar. size ( & tcx) . unsigned_int_max ( ) - 1 =>
1012+ {
1013+ return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
1014+ }
1015+ WrappingRange { start : 1 , .. } => {
1016+ return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
1017+ }
1018+ WrappingRange { start, end } => {
1019+ unreachable ! ( "Unhandled start and end range: ({}, {})" , start, end)
1020+ }
1021+ } ;
1022+ }
1023+ None
10221024 }
1025+ ty:: Pat ( base, pat) => match * * pat {
1026+ ty:: PatternKind :: Range { .. } => get_nullable_type ( tcx, typing_env, * base) ,
1027+ } ,
1028+ _ => None ,
10231029 }
1024- None
10251030}
10261031
10271032impl < ' a , ' tcx > ImproperCTypesVisitor < ' a , ' tcx > {
0 commit comments