@@ -891,9 +891,8 @@ fn get_nullable_type<'tcx>(
891891 } ;
892892 return get_nullable_type ( tcx, typing_env, inner_field_ty) ;
893893 }
894- ty:: Int ( ty) => Ty :: new_int ( tcx, ty) ,
895- ty:: Uint ( ty) => Ty :: new_uint ( tcx, ty) ,
896- ty:: RawPtr ( ty, mutbl) => Ty :: new_ptr ( tcx, ty, mutbl) ,
894+ ty:: Pat ( base, ..) => return get_nullable_type ( tcx, typing_env, base) ,
895+ ty:: Int ( _) | ty:: Uint ( _) | ty:: RawPtr ( ..) => ty,
897896 // As these types are always non-null, the nullable equivalent of
898897 // `Option<T>` of these types are their raw pointer counterparts.
899898 ty:: Ref ( _region, ty, mutbl) => Ty :: new_ptr ( tcx, ty, mutbl) ,
@@ -949,63 +948,69 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
949948 ckind : CItemKind ,
950949) -> Option < Ty < ' tcx > > {
951950 debug ! ( "is_repr_nullable_ptr(tcx, ty = {:?})" , ty) ;
952- if let ty:: Adt ( ty_def, args) = ty. kind ( ) {
953- let field_ty = match & ty_def. variants ( ) . raw [ ..] {
954- [ var_one, var_two] => match ( & var_one. fields . raw [ ..] , & var_two. fields . raw [ ..] ) {
955- ( [ ] , [ field] ) | ( [ field] , [ ] ) => field. ty ( tcx, args) ,
956- ( [ field1] , [ field2] ) => {
957- let ty1 = field1. ty ( tcx, args) ;
958- let ty2 = field2. ty ( tcx, args) ;
959-
960- if is_niche_optimization_candidate ( tcx, typing_env, ty1) {
961- ty2
962- } else if is_niche_optimization_candidate ( tcx, typing_env, ty2) {
963- ty1
964- } else {
965- return None ;
951+ match ty. kind ( ) {
952+ ty:: Adt ( ty_def, args) => {
953+ let field_ty = match & ty_def. variants ( ) . raw [ ..] {
954+ [ var_one, var_two] => match ( & var_one. fields . raw [ ..] , & var_two. fields . raw [ ..] ) {
955+ ( [ ] , [ field] ) | ( [ field] , [ ] ) => field. ty ( tcx, args) ,
956+ ( [ field1] , [ field2] ) => {
957+ let ty1 = field1. ty ( tcx, args) ;
958+ let ty2 = field2. ty ( tcx, args) ;
959+
960+ if is_niche_optimization_candidate ( tcx, typing_env, ty1) {
961+ ty2
962+ } else if is_niche_optimization_candidate ( tcx, typing_env, ty2) {
963+ ty1
964+ } else {
965+ return None ;
966+ }
966967 }
967- }
968+ _ => return None ,
969+ } ,
968970 _ => return None ,
969- } ,
970- _ => return None ,
971- } ;
971+ } ;
972972
973- if !ty_is_known_nonnull ( tcx, typing_env, field_ty, ckind) {
974- return None ;
975- }
973+ if !ty_is_known_nonnull ( tcx, typing_env, field_ty, ckind) {
974+ return None ;
975+ }
976976
977- // At this point, the field's type is known to be nonnull and the parent enum is Option-like.
978- // If the computed size for the field and the enum are different, the nonnull optimization isn't
979- // being applied (and we've got a problem somewhere).
980- let compute_size_skeleton = |t| SizeSkeleton :: compute ( t, tcx, typing_env) . ok ( ) ;
981- if !compute_size_skeleton ( ty) ?. same_size ( compute_size_skeleton ( field_ty) ?) {
982- bug ! ( "improper_ctypes: Option nonnull optimization not applied?" ) ;
983- }
977+ // At this point, the field's type is known to be nonnull and the parent enum is Option-like.
978+ // If the computed size for the field and the enum are different, the nonnull optimization isn't
979+ // being applied (and we've got a problem somewhere).
980+ let compute_size_skeleton = |t| SizeSkeleton :: compute ( t, tcx, typing_env) . ok ( ) ;
981+ if !compute_size_skeleton ( ty) ?. same_size ( compute_size_skeleton ( field_ty) ?) {
982+ bug ! ( "improper_ctypes: Option nonnull optimization not applied?" ) ;
983+ }
984984
985- // Return the nullable type this Option-like enum can be safely represented with.
986- let field_ty_layout = tcx. layout_of ( typing_env. as_query_input ( field_ty) ) ;
987- if field_ty_layout. is_err ( ) && !field_ty. has_non_region_param ( ) {
988- bug ! ( "should be able to compute the layout of non-polymorphic type" ) ;
989- }
985+ // Return the nullable type this Option-like enum can be safely represented with.
986+ let field_ty_layout = tcx. layout_of ( typing_env. as_query_input ( field_ty) ) ;
987+ if field_ty_layout. is_err ( ) && !field_ty. has_non_region_param ( ) {
988+ bug ! ( "should be able to compute the layout of non-polymorphic type" ) ;
989+ }
990990
991- let field_ty_abi = & field_ty_layout. ok ( ) ?. backend_repr ;
992- if let BackendRepr :: Scalar ( field_ty_scalar) = field_ty_abi {
993- match field_ty_scalar. valid_range ( & tcx) {
994- WrappingRange { start : 0 , end }
995- if end == field_ty_scalar. size ( & tcx) . unsigned_int_max ( ) - 1 =>
996- {
997- return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
998- }
999- WrappingRange { start : 1 , .. } => {
1000- return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
1001- }
1002- WrappingRange { start, end } => {
1003- unreachable ! ( "Unhandled start and end range: ({}, {})" , start, end)
1004- }
1005- } ;
991+ let field_ty_abi = & field_ty_layout. ok ( ) ?. backend_repr ;
992+ if let BackendRepr :: Scalar ( field_ty_scalar) = field_ty_abi {
993+ match field_ty_scalar. valid_range ( & tcx) {
994+ WrappingRange { start : 0 , end }
995+ if end == field_ty_scalar. size ( & tcx) . unsigned_int_max ( ) - 1 =>
996+ {
997+ return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
998+ }
999+ WrappingRange { start : 1 , .. } => {
1000+ return Some ( get_nullable_type ( tcx, typing_env, field_ty) . unwrap ( ) ) ;
1001+ }
1002+ WrappingRange { start, end } => {
1003+ unreachable ! ( "Unhandled start and end range: ({}, {})" , start, end)
1004+ }
1005+ } ;
1006+ }
1007+ None
10061008 }
1009+ ty:: Pat ( base, pat) => match * * pat {
1010+ ty:: PatternKind :: Range { .. } => get_nullable_type ( tcx, typing_env, * base) ,
1011+ } ,
1012+ _ => None ,
10071013 }
1008- None
10091014}
10101015
10111016impl < ' a , ' tcx > ImproperCTypesVisitor < ' a , ' tcx > {
0 commit comments