@@ -759,12 +759,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
759
759
760
760
if let Some ( t) = single_contained {
761
761
let mut v = Vec :: new ( ) ;
762
- let needs_deref = self . write_empty_rust_val_check_suffix ( generics, & mut v, t) ;
762
+ let ( needs_deref, ret_ref ) = self . write_empty_rust_val_check_suffix ( generics, & mut v, t) ;
763
763
let s = String :: from_utf8 ( v) . unwrap ( ) ;
764
- if needs_deref {
764
+ if needs_deref && ret_ref {
765
765
return Some ( ( "if " , vec ! [
766
766
( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ &mut *{} }}" , var_access) )
767
767
] , ") }" ) ) ;
768
+ } else if needs_deref {
769
+ return Some ( ( "if " , vec ! [
770
+ ( format!( "{} {{ None }} else {{ Some(" , s) , format!( "unsafe {{ *Box::from_raw({}) }}" , var_access) )
771
+ ] , ") }" ) ) ;
768
772
} else {
769
773
return Some ( ( "if " , vec ! [
770
774
( format!( "{} {{ None }} else {{ Some(" , s) , format!( "{}" , var_access) )
@@ -1058,36 +1062,36 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
1058
1062
/// Prints a suffix to determine if a variable is empty (ie was set by write_empty_rust_val),
1059
1063
/// returning whether we need to dereference the inner value before using it (ie it is a
1060
1064
/// pointer).
1061
- pub fn write_empty_rust_val_check_suffix < W : std:: io:: Write > ( & self , generics : Option < & GenericTypes > , w : & mut W , t : & syn:: Type ) -> bool {
1065
+ pub fn write_empty_rust_val_check_suffix < W : std:: io:: Write > ( & self , generics : Option < & GenericTypes > , w : & mut W , t : & syn:: Type ) -> ( bool , bool ) {
1062
1066
match t {
1063
1067
syn:: Type :: Path ( p) => {
1064
1068
let resolved = self . resolve_path ( & p. path , generics) ;
1065
1069
if self . crate_types . opaques . get ( & resolved) . is_some ( ) {
1066
1070
write ! ( w, ".inner.is_null()" ) . unwrap ( ) ;
1067
- false
1071
+ ( false , false )
1068
1072
} else {
1069
1073
if let Some ( suffix) = self . empty_val_check_suffix_from_path ( & resolved) {
1070
1074
write ! ( w, "{}" , suffix) . unwrap ( ) ;
1071
- false // We may eventually need to allow empty_val_check_suffix_from_path to specify if we need a deref or not
1075
+ ( false , false ) // We may eventually need to allow empty_val_check_suffix_from_path to specify if we need a deref or not
1072
1076
} else {
1073
1077
write ! ( w, " == std::ptr::null_mut()" ) . unwrap ( ) ;
1074
- false
1078
+ ( true , false )
1075
1079
}
1076
1080
}
1077
1081
} ,
1078
1082
syn:: Type :: Array ( a) => {
1079
1083
if let syn:: Expr :: Lit ( l) = & a. len {
1080
1084
if let syn:: Lit :: Int ( i) = & l. lit {
1081
1085
write ! ( w, " == [0; {}]" , i. base10_digits( ) ) . unwrap ( ) ;
1082
- false
1086
+ ( false , false )
1083
1087
} else { unimplemented ! ( ) ; }
1084
1088
} else { unimplemented ! ( ) ; }
1085
1089
} ,
1086
1090
syn:: Type :: Slice ( _) => {
1087
1091
// Option<[]> always implies that we want to treat len() == 0 differently from
1088
1092
// None, so we always map an Option<[]> into a pointer.
1089
1093
write ! ( w, " == std::ptr::null_mut()" ) . unwrap ( ) ;
1090
- true
1094
+ ( true , true )
1091
1095
} ,
1092
1096
_ => unimplemented ! ( ) ,
1093
1097
}
@@ -1698,7 +1702,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
1698
1702
if single_ident_generic_path_to_ident ( & p_arg. path ) . is_some ( ) {
1699
1703
if self . crate_types . opaques . get ( & resolved) . is_some ( ) {
1700
1704
write ! ( w, "crate::{}" , resolved) . unwrap ( ) ;
1701
- } else { unimplemented ! ( ) ; }
1705
+ } else {
1706
+ let cty = self . c_type_from_path ( & resolved, true , true ) . expect ( "Template generics should be opaque or have a predefined mapping" ) ;
1707
+ w. write ( cty. as_bytes ( ) ) . unwrap ( ) ;
1708
+ }
1702
1709
} else { unimplemented ! ( ) ; }
1703
1710
} else { unimplemented ! ( ) ; }
1704
1711
} else if let syn:: Type :: Array ( a_arg) = t {
@@ -1758,7 +1765,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
1758
1765
if self . c_type_has_inner_from_path( & subtype) {
1759
1766
if !self . write_c_path_intern( generics, w, & $p_arg. path, is_ref, is_mut, ptr_for_ref) { return false ; }
1760
1767
} else {
1761
- if !self . write_c_path_intern( generics, w, & $p_arg. path, true , is_mut, true ) { return false ; }
1768
+ // Option<T> needs to be converted to a *mut T, ie mut ptr-for-ref
1769
+ if !self . write_c_path_intern( generics, w, & $p_arg. path, true , true , true ) { return false ; }
1762
1770
}
1763
1771
} else {
1764
1772
if $p_arg. path. segments. len( ) == 1 {
0 commit comments