@@ -257,6 +257,17 @@ pub struct TypeResolver<'mod_lifetime, 'crate_lft: 'mod_lifetime> {
257
257
pub crate_types : & ' mod_lifetime mut CrateTypes < ' crate_lft > ,
258
258
}
259
259
260
+ /// Returned by write_empty_rust_val_check_suffix to indicate what type of dereferencing needs to
261
+ /// happen to get the inner value of a generic.
262
+ enum EmptyValExpectedTy {
263
+ /// A type which has a flag for being empty (eg an array where we treat all-0s as empty).
264
+ NonPointer ,
265
+ /// A pointer that we want to dereference and move out of.
266
+ OwnedPointer ,
267
+ /// A pointer which we want to convert to a reference.
268
+ ReferenceAsPointer ,
269
+ }
270
+
260
271
impl < ' a , ' c : ' a > TypeResolver < ' a , ' c > {
261
272
pub fn new ( orig_crate : & ' a str , module_path : & ' a str , crate_types : & ' a mut CrateTypes < ' c > ) -> Self {
262
273
let mut imports = HashMap :: new ( ) ;
@@ -757,20 +768,21 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
757
768
758
769
if let Some ( t) = single_contained {
759
770
let mut v = Vec :: new ( ) ;
760
- let ( needs_deref , ret_ref) = self . write_empty_rust_val_check_suffix ( generics, & mut v, t) ;
771
+ let ret_ref = self . write_empty_rust_val_check_suffix ( generics, & mut v, t) ;
761
772
let s = String :: from_utf8 ( v) . unwrap ( ) ;
762
- if needs_deref && ret_ref {
763
- return Some ( ( "if " , vec ! [
764
- ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ &mut *{} }}" , var_access) )
765
- ] , ") }" ) ) ;
766
- } else if needs_deref {
767
- return Some ( ( "if " , vec ! [
768
- ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ *Box::from_raw({}) }}" , var_access) )
769
- ] , ") }" ) ) ;
770
- } else {
771
- return Some ( ( "if " , vec ! [
772
- ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "{}" , var_access) )
773
- ] , ") }" ) ) ;
773
+ match ret_ref {
774
+ EmptyValExpectedTy :: ReferenceAsPointer =>
775
+ return Some ( ( "if " , vec ! [
776
+ ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ &mut *{} }}" , var_access) )
777
+ ] , ") }" ) ) ,
778
+ EmptyValExpectedTy :: OwnedPointer =>
779
+ return Some ( ( "if " , vec ! [
780
+ ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ *Box::from_raw({}) }}" , var_access) )
781
+ ] , ") }" ) ) ,
782
+ EmptyValExpectedTy :: NonPointer =>
783
+ return Some ( ( "if " , vec ! [
784
+ ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "{}" , var_access) )
785
+ ] , ") }" ) ) ,
774
786
}
775
787
} else { unreachable ! ( ) ; }
776
788
} ,
@@ -1054,39 +1066,39 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
1054
1066
}
1055
1067
}
1056
1068
1057
- /// Prints a suffix to determine if a variable is empty (ie was set by write_empty_rust_val),
1058
- /// returning whether we need to dereference the inner value before using it (ie it is a
1059
- /// pointer).
1060
- pub fn write_empty_rust_val_check_suffix < W : std:: io:: Write > ( & self , generics : Option < & GenericTypes > , w : & mut W , t : & syn:: Type ) -> ( bool , bool ) {
1069
+ /// Prints a suffix to determine if a variable is empty (ie was set by write_empty_rust_val).
1070
+ /// See EmptyValExpectedTy for information on return types.
1071
+ fn write_empty_rust_val_check_suffix < W : std:: io:: Write > ( & self , generics : Option < & GenericTypes > , w : & mut W , t : & syn:: Type ) -> EmptyValExpectedTy {
1061
1072
match t {
1062
1073
syn:: Type :: Path ( p) => {
1063
1074
let resolved = self . resolve_path ( & p. path , generics) ;
1064
1075
if self . crate_types . opaques . get ( & resolved) . is_some ( ) {
1065
1076
write ! ( w, ".inner.is_null()" ) . unwrap ( ) ;
1066
- ( false , false )
1077
+ EmptyValExpectedTy :: NonPointer
1067
1078
} else {
1068
1079
if let Some ( suffix) = self . empty_val_check_suffix_from_path ( & resolved) {
1069
1080
write ! ( w, "{}" , suffix) . unwrap ( ) ;
1070
- ( false , false ) // We may eventually need to allow empty_val_check_suffix_from_path to specify if we need a deref or not
1081
+ // We may eventually need to allow empty_val_check_suffix_from_path to specify if we need a deref or not
1082
+ EmptyValExpectedTy :: NonPointer
1071
1083
} else {
1072
1084
write ! ( w, " == std::ptr::null_mut()" ) . unwrap ( ) ;
1073
- ( true , false )
1085
+ EmptyValExpectedTy :: OwnedPointer
1074
1086
}
1075
1087
}
1076
1088
} ,
1077
1089
syn:: Type :: Array ( a) => {
1078
1090
if let syn:: Expr :: Lit ( l) = & a. len {
1079
1091
if let syn:: Lit :: Int ( i) = & l. lit {
1080
1092
write ! ( w, " == [0; {}]" , i. base10_digits( ) ) . unwrap ( ) ;
1081
- ( false , false )
1093
+ EmptyValExpectedTy :: NonPointer
1082
1094
} else { unimplemented ! ( ) ; }
1083
1095
} else { unimplemented ! ( ) ; }
1084
1096
} ,
1085
1097
syn:: Type :: Slice ( _) => {
1086
1098
// Option<[]> always implies that we want to treat len() == 0 differently from
1087
1099
// None, so we always map an Option<[]> into a pointer.
1088
1100
write ! ( w, " == std::ptr::null_mut()" ) . unwrap ( ) ;
1089
- ( true , true )
1101
+ EmptyValExpectedTy :: ReferenceAsPointer
1090
1102
} ,
1091
1103
_ => unimplemented ! ( ) ,
1092
1104
}
0 commit comments