@@ -907,9 +907,8 @@ fn get_nullable_type<'tcx>(
907
907
} ;
908
908
return get_nullable_type ( tcx, typing_env, inner_field_ty) ;
909
909
}
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,
913
912
// As these types are always non-null, the nullable equivalent of
914
913
// `Option<T>` of these types are their raw pointer counterparts.
915
914
ty:: Ref ( _region, ty, mutbl) => Ty :: new_ptr ( tcx, ty, mutbl) ,
@@ -965,63 +964,69 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
965
964
ckind : CItemKind ,
966
965
) -> Option < Ty < ' tcx > > {
967
966
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
+ }
982
983
}
983
- }
984
+ _ => return None ,
985
+ } ,
984
986
_ => return None ,
985
- } ,
986
- _ => return None ,
987
- } ;
987
+ } ;
988
988
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
+ }
992
992
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
+ }
1000
1000
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
+ }
1006
1006
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
1022
1024
}
1025
+ ty:: Pat ( base, pat) => match * * pat {
1026
+ ty:: PatternKind :: Range { .. } => get_nullable_type ( tcx, typing_env, * base) ,
1027
+ } ,
1028
+ _ => None ,
1023
1029
}
1024
- None
1025
1030
}
1026
1031
1027
1032
impl < ' a , ' tcx > ImproperCTypesVisitor < ' a , ' tcx > {
0 commit comments