writeln_field_docs(w, &field.attrs, "\t\t", types, Some(&gen_types), &field.ty);
write!(w, "\t\t{}: ", field.ident.as_ref().unwrap()).unwrap();
write!(&mut constr, "{}{}: ", if idx != 0 { ", " } else { "" }, field.ident.as_ref().unwrap()).unwrap();
- types.write_c_type(w, &field.ty, Some(&gen_types), false);
- types.write_c_type(&mut constr, &field.ty, Some(&gen_types), false);
+ types.write_c_type(w, &field.ty, Some(&gen_types), true);
+ types.write_c_type(&mut constr, &field.ty, Some(&gen_types), true);
writeln!(w, ",").unwrap();
}
write!(w, "\t}}").unwrap();
} else if let syn::Fields::Unnamed(fields) = &var.fields {
if fields.unnamed.len() == 1 {
let mut empty_check = Vec::new();
- types.write_c_type(&mut empty_check, &fields.unnamed[0].ty, Some(&gen_types), false);
+ types.write_c_type(&mut empty_check, &fields.unnamed[0].ty, Some(&gen_types), true);
if empty_check.is_empty() {
empty_tuple_variant = true;
}
}
if !empty_tuple_variant {
needs_free = true;
- write!(w, "(").unwrap();
+ writeln!(w, "(").unwrap();
for (idx, field) in fields.unnamed.iter().enumerate() {
if export_status(&field.attrs) == ExportStatus::TestOnly { continue; }
+ writeln_field_docs(w, &field.attrs, "\t\t", types, Some(&gen_types), &field.ty);
+ write!(w, "\t\t").unwrap();
+ types.write_c_type(w, &field.ty, Some(&gen_types), true);
+
write!(&mut constr, "{}: ", ('a' as u8 + idx as u8) as char).unwrap();
- types.write_c_type(w, &field.ty, Some(&gen_types), false);
types.write_c_type(&mut constr, &field.ty, Some(&gen_types), false);
if idx != fields.unnamed.len() - 1 {
- write!(w, ",").unwrap();
+ writeln!(w, ",").unwrap();
write!(&mut constr, ",").unwrap();
}
}
} else if let syn::Fields::Unnamed(fields) = &var.fields {
if !empty_tuple_variant {
write!(&mut constr, "(").unwrap();
- for idx in 0..fields.unnamed.len() {
- write!(&mut constr, "{}, ", ('a' as u8 + idx as u8) as char).unwrap();
+ for (idx, field) in fields.unnamed.iter().enumerate() {
+ let mut ref_c_ty = Vec::new();
+ let mut nonref_c_ty = Vec::new();
+ types.write_c_type(&mut ref_c_ty, &field.ty, Some(&gen_types), false);
+ types.write_c_type(&mut nonref_c_ty, &field.ty, Some(&gen_types), true);
+
+ if ref_c_ty != nonref_c_ty {
+ // We blindly assume references in field types are always opaque types, and
+ // print out an opaque reference -> owned reference conversion here.
+ write!(&mut constr, "{} {{ inner: {}.inner, is_owned: false }}, ", String::from_utf8(nonref_c_ty).unwrap(), ('a' as u8 + idx as u8) as char).unwrap();
+ } else {
+ write!(&mut constr, "{}, ", ('a' as u8 + idx as u8) as char).unwrap();
+ }
}
writeln!(&mut constr, ")").unwrap();
} else {
writeln!(&mut constr, "}}").unwrap();
writeln!(w, ",").unwrap();
}
- writeln!(w, "}}\nuse {}::{} as native{};\nimpl {} {{", types.module_path, e.ident, e.ident, e.ident).unwrap();
+ writeln!(w, "}}\nuse {}::{} as {}Import;", types.module_path, e.ident, e.ident).unwrap();
+ write!(w, "pub(crate) type native{} = {}Import", e.ident, e.ident).unwrap();
+ maybe_write_generics(w, &e.generics, &types, true);
+ writeln!(w, ";\n\nimpl {} {{", e.ident).unwrap();
macro_rules! write_conv {
($fn_sig: expr, $to_c: expr, $ref: expr) => {
} else if let syn::Fields::Unnamed(fields) = &var.fields {
if fields.unnamed.len() == 1 {
let mut empty_check = Vec::new();
- types.write_c_type(&mut empty_check, &fields.unnamed[0].ty, Some(&gen_types), false);
+ types.write_c_type(&mut empty_check, &fields.unnamed[0].ty, Some(&gen_types), true);
if empty_check.is_empty() {
empty_tuple_variant = true;
}
let mut sink = ::std::io::sink();
let mut out: &mut dyn std::io::Write = if $ref { &mut sink } else { w };
let new_var = if $to_c {
- types.write_to_c_conversion_new_var(&mut out, $field_ident, &$field.ty, Some(&gen_types), false)
+ types.write_to_c_conversion_new_var(&mut out, $field_ident, &$field.ty, Some(&gen_types), true)
} else {
types.write_from_c_conversion_new_var(&mut out, $field_ident, &$field.ty, Some(&gen_types))
};
if new_var {
let nonref_ident = format_ident!("{}_nonref", $field_ident);
if $to_c {
- types.write_to_c_conversion_new_var(w, &nonref_ident, &$field.ty, Some(&gen_types), false);
+ types.write_to_c_conversion_new_var(w, &nonref_ident, &$field.ty, Some(&gen_types), true);
} else {
types.write_from_c_conversion_new_var(w, &nonref_ident, &$field.ty, Some(&gen_types));
}
($field: expr, $field_ident: expr) => { {
if export_status(&$field.attrs) == ExportStatus::TestOnly { continue; }
if $to_c {
- types.write_to_c_conversion_inline_prefix(w, &$field.ty, Some(&gen_types), false);
+ types.write_to_c_conversion_inline_prefix(w, &$field.ty, Some(&gen_types), true);
} else {
types.write_from_c_conversion_prefix(w, &$field.ty, Some(&gen_types));
}
write!(w, "{}{}", $field_ident,
if $ref { "_nonref" } else { "" }).unwrap();
if $to_c {
- types.write_to_c_conversion_inline_suffix(w, &$field.ty, Some(&gen_types), false);
+ types.write_to_c_conversion_inline_suffix(w, &$field.ty, Some(&gen_types), true);
} else {
types.write_from_c_conversion_suffix(w, &$field.ty, Some(&gen_types));
}