@@ -257,6 +257,19 @@ 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
+
271
+
272
+
260
273
impl < ' a , ' c : ' a > TypeResolver < ' a , ' c > {
261
274
pub fn new ( orig_crate : & ' a str , module_path : & ' a str , crate_types : & ' a mut CrateTypes < ' c > ) -> Self {
262
275
let mut imports = HashMap :: new ( ) ;
@@ -757,20 +770,21 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
757
770
758
771
if let Some ( t) = single_contained {
759
772
let mut v = Vec :: new ( ) ;
760
- let ( needs_deref , ret_ref) = self . write_empty_rust_val_check_suffix ( generics, & mut v, t) ;
773
+ let ret_ref = self . write_empty_rust_val_check_suffix ( generics, & mut v, t) ;
761
774
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
- ] , ") }" ) ) ;
775
+ match ret_ref {
776
+ EmptyValExpectedTy :: ReferenceAsPointer =>
777
+ return Some ( ( "if " , vec ! [
778
+ ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ &mut *{} }}" , var_access) )
779
+ ] , ") }" ) ) ,
780
+ EmptyValExpectedTy :: OwnedPointer =>
781
+ return Some ( ( "if " , vec ! [
782
+ ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ *Box::from_raw({}) }}" , var_access) )
783
+ ] , ") }" ) ) ,
784
+ EmptyValExpectedTy :: NonPointer =>
785
+ return Some ( ( "if " , vec ! [
786
+ ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "{}" , var_access) )
787
+ ] , ") }" ) ) ,
774
788
}
775
789
} else { unreachable ! ( ) ; }
776
790
} ,
@@ -1054,39 +1068,42 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
1054
1068
}
1055
1069
}
1056
1070
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 ) {
1071
+ /// Prints a suffix to determine if a variable is empty (ie was set by write_empty_rust_val).
1072
+ /// See EmptyValExpectedTy for information on return types.
1073
+ /// returning two bools - the first indicates that the variable is mapped as a pointer which
1074
+ /// needs to be dereferenced before use, and the second indicates the variable needs to be
1075
+ /// dereferenced but is expected to be used as a reference, not moved.
1076
+ fn write_empty_rust_val_check_suffix < W : std:: io:: Write > ( & self , generics : Option < & GenericTypes > , w : & mut W , t : & syn:: Type ) -> EmptyValExpectedTy {
1061
1077
match t {
1062
1078
syn:: Type :: Path ( p) => {
1063
1079
let resolved = self . resolve_path ( & p. path , generics) ;
1064
1080
if self . crate_types . opaques . get ( & resolved) . is_some ( ) {
1065
1081
write ! ( w, ".inner.is_null()" ) . unwrap ( ) ;
1066
- ( false , false )
1082
+ EmptyValExpectedTy :: NonPointer
1067
1083
} else {
1068
1084
if let Some ( suffix) = self . empty_val_check_suffix_from_path ( & resolved) {
1069
1085
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
1086
+ // We may eventually need to allow empty_val_check_suffix_from_path to specify if we need a deref or not
1087
+ EmptyValExpectedTy :: NonPointer
1071
1088
} else {
1072
1089
write ! ( w, " == std::ptr::null_mut()" ) . unwrap ( ) ;
1073
- ( true , false )
1090
+ EmptyValExpectedTy :: OwnedPointer
1074
1091
}
1075
1092
}
1076
1093
} ,
1077
1094
syn:: Type :: Array ( a) => {
1078
1095
if let syn:: Expr :: Lit ( l) = & a. len {
1079
1096
if let syn:: Lit :: Int ( i) = & l. lit {
1080
1097
write ! ( w, " == [0; {}]" , i. base10_digits( ) ) . unwrap ( ) ;
1081
- ( false , false )
1098
+ EmptyValExpectedTy :: NonPointer
1082
1099
} else { unimplemented ! ( ) ; }
1083
1100
} else { unimplemented ! ( ) ; }
1084
1101
} ,
1085
1102
syn:: Type :: Slice ( _) => {
1086
1103
// Option<[]> always implies that we want to treat len() == 0 differently from
1087
1104
// None, so we always map an Option<[]> into a pointer.
1088
1105
write ! ( w, " == std::ptr::null_mut()" ) . unwrap ( ) ;
1089
- ( true , true )
1106
+ EmptyValExpectedTy :: ReferenceAsPointer
1090
1107
} ,
1091
1108
_ => unimplemented ! ( ) ,
1092
1109
}
0 commit comments