Skip to content

Commit a86b1d7

Browse files
committed
Use native types when converting for for single-impl traits
Now that we properly handle single-impl traits as Rust types (i.e. in generic parameters), we have to handle "converting" single-impl traits. Here we implement this, diverging from the impl of the underlying impl'd trait by keeping the existing type as-passed and only ref'ing it if required.
1 parent c4f2096 commit a86b1d7

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

c-bindings-gen/src/types.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,7 +2248,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
22482248
}
22492249

22502250
fn write_conversion_inline_intern<W: std::io::Write,
2251-
LP: Fn(&str, bool, bool) -> Option<String>, DL: Fn(&mut W, &DeclType, &str, bool, bool), SC: Fn(bool, Option<&str>) -> String>
2251+
LP: Fn(&str, bool, bool) -> Option<String>, DL: Fn(&mut W, &DeclType, &str, bool, bool, bool), SC: Fn(bool, Option<&str>) -> String>
22522252
(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool,
22532253
tupleconv: &str, prefix: bool, sliceconv: SC, path_lookup: LP, decl_lookup: DL) {
22542254
match generics.resolve_type(t) {
@@ -2271,14 +2271,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
22712271
} else if let Some(c_type) = path_lookup(&resolved_path, is_ref, ptr_for_ref) {
22722272
write!(w, "{}", c_type).unwrap();
22732273
} else if let Some((_, generics)) = self.crate_types.opaques.get(&resolved_path) {
2274-
decl_lookup(w, &DeclType::StructImported { generics: &generics }, &resolved_path, is_ref, is_mut);
2274+
decl_lookup(w, &DeclType::StructImported { generics: &generics }, &resolved_path, is_ref, is_mut, false);
22752275
} else if self.crate_types.mirrored_enums.get(&resolved_path).is_some() {
2276-
decl_lookup(w, &DeclType::MirroredEnum, &resolved_path, is_ref, is_mut);
2276+
decl_lookup(w, &DeclType::MirroredEnum, &resolved_path, is_ref, is_mut, false);
22772277
} else if let Some(t) = self.crate_types.traits.get(&resolved_path) {
2278-
decl_lookup(w, &DeclType::Trait(t), &resolved_path, is_ref, is_mut);
2278+
decl_lookup(w, &DeclType::Trait(t), &resolved_path, is_ref, is_mut, false);
22792279
} else if let Some(ident) = single_ident_generic_path_to_ident(&p.path) {
22802280
if let Some(decl_type) = self.types.maybe_resolve_declared(ident) {
2281-
decl_lookup(w, decl_type, &self.maybe_resolve_ident(ident).unwrap(), is_ref, is_mut);
2281+
decl_lookup(w, decl_type, &self.maybe_resolve_ident(ident).unwrap(), is_ref, is_mut, false);
22822282
} else { unimplemented!(); }
22832283
} else {
22842284
if let Some(trait_impls) = self.crate_types.traits_impld.get(&resolved_path) {
@@ -2287,7 +2287,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
22872287
// in the whole crate, just treat it as a reference to whatever the
22882288
// implementor is.
22892289
let implementor = self.crate_types.opaques.get(&trait_impls[0]).unwrap();
2290-
decl_lookup(w, &DeclType::StructImported { generics: &implementor.1 }, &trait_impls[0], true, is_mut);
2290+
decl_lookup(w, &DeclType::StructImported { generics: &implementor.1 }, &trait_impls[0], true, is_mut, true);
22912291
return;
22922292
}
22932293
}
@@ -2371,11 +2371,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
23712371
fn write_to_c_conversion_inline_prefix_inner<W: std::io::Write>(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, ptr_for_ref: bool, from_ptr: bool) {
23722372
self.write_conversion_inline_intern(w, t, generics, is_ref, false, ptr_for_ref, "() /*", true, |_, _| "local_".to_owned(),
23732373
|a, b, c| self.to_c_conversion_inline_prefix_from_path(a, b, c),
2374-
|w, decl_type, decl_path, is_ref, _is_mut| {
2374+
|w, decl_type, decl_path, is_ref, _is_mut, is_trait_alias| {
23752375
match decl_type {
23762376
DeclType::MirroredEnum if is_ref && ptr_for_ref => write!(w, "crate::{}::from_native(", decl_path).unwrap(),
23772377
DeclType::MirroredEnum if is_ref => write!(w, "&crate::{}::from_native(", decl_path).unwrap(),
23782378
DeclType::MirroredEnum => write!(w, "crate::{}::native_into(", decl_path).unwrap(),
2379+
DeclType::StructImported {..} if is_trait_alias => {
2380+
if is_ref { write!(w, "&").unwrap(); }
2381+
},
23792382
DeclType::EnumIgnored {..}|DeclType::StructImported {..} if is_ref && from_ptr => {
23802383
if !ptr_for_ref { write!(w, "&").unwrap(); }
23812384
write!(w, "crate::{} {{ inner: unsafe {{ (", decl_path).unwrap()
@@ -2400,8 +2403,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
24002403
fn write_to_c_conversion_inline_suffix_inner<W: std::io::Write>(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, ptr_for_ref: bool, from_ptr: bool) {
24012404
self.write_conversion_inline_intern(w, t, generics, is_ref, false, ptr_for_ref, "*/", false, |_, _| ".into()".to_owned(),
24022405
|a, b, c| self.to_c_conversion_inline_suffix_from_path(a, b, c),
2403-
|w, decl_type, full_path, is_ref, _is_mut| match decl_type {
2406+
|w, decl_type, full_path, is_ref, _is_mut, is_trait_alias| match decl_type {
24042407
DeclType::MirroredEnum => write!(w, ")").unwrap(),
2408+
DeclType::StructImported {..} if is_trait_alias => {
2409+
write!(w, ".as_ref_to()").unwrap();
2410+
},
24052411
DeclType::EnumIgnored { generics }|DeclType::StructImported { generics } if is_ref => {
24062412
write!(w, " as *const {}<", full_path).unwrap();
24072413
for param in generics.params.iter() {
@@ -2438,7 +2444,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
24382444
fn write_from_c_conversion_prefix_inner<W: std::io::Write>(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, _ptr_for_ref: bool) {
24392445
self.write_conversion_inline_intern(w, t, generics, is_ref, false, false, "() /*", true, |_, _| "&local_".to_owned(),
24402446
|a, b, _c| self.from_c_conversion_prefix_from_path(a, b),
2441-
|w, decl_type, _full_path, is_ref, _is_mut| match decl_type {
2447+
|w, decl_type, _full_path, is_ref, _is_mut, _is_trait_alias| match decl_type {
24422448
DeclType::StructImported {..} if is_ref => write!(w, "").unwrap(),
24432449
DeclType::StructImported {..} if !is_ref => write!(w, "*unsafe {{ Box::from_raw(").unwrap(),
24442450
DeclType::MirroredEnum if is_ref => write!(w, "&").unwrap(),
@@ -2459,7 +2465,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
24592465
(true, Some(_)) => unreachable!(),
24602466
},
24612467
|a, b, _c| self.from_c_conversion_suffix_from_path(a, b),
2462-
|w, decl_type, _full_path, is_ref, is_mut| match decl_type {
2468+
|w, decl_type, _full_path, is_ref, is_mut, is_trait_alias| match decl_type {
2469+
DeclType::StructImported {..} if is_trait_alias => write!(w, ".as_ref_to()").unwrap(),
24632470
DeclType::StructImported {..} if is_ref && ptr_for_ref => write!(w, "XXX unimplemented").unwrap(),
24642471
DeclType::StructImported {..} if is_mut && is_ref => write!(w, ".get_native_mut_ref()").unwrap(),
24652472
DeclType::StructImported {..} if is_ref => write!(w, ".get_native_ref()").unwrap(),
@@ -2482,7 +2489,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
24822489
Some(format!("&{}", conv))
24832490
} else { None }
24842491
},
2485-
|w, decl_type, _full_path, is_ref, _is_mut| match decl_type {
2492+
|w, decl_type, _full_path, is_ref, _is_mut, _is_trait_alias| match decl_type {
24862493
DeclType::StructImported {..} if !is_ref => write!(w, "").unwrap(),
24872494
_ => unimplemented!(),
24882495
});
@@ -2496,7 +2503,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
24962503
(true, Some(_)) => unreachable!(),
24972504
},
24982505
|a, b, _c| self.from_c_conversion_suffix_from_path(a, b),
2499-
|w, decl_type, _full_path, is_ref, _is_mut| match decl_type {
2506+
|w, decl_type, _full_path, is_ref, _is_mut, _is_trait_alias| match decl_type {
25002507
DeclType::StructImported {..} if !is_ref => write!(w, ".get_native_ref()").unwrap(),
25012508
_ => unimplemented!(),
25022509
});

0 commit comments

Comments
 (0)