Resolve MSVC "C-linkage specified, but returns UDT" warning
cxxbridge\sources\tests\ffi\lib.rs.cc(1335): warning C4190: 'tests$cxxbridge1$c_return_str' has C-linkage specified, but returns UDT 'rust::cxxbridge1::Str' which is incompatible with C
cxxbridge\include\rust/cxx.h(93): note: see declaration of 'rust::cxxbridge1::Str'
cxxbridge\sources\tests\ffi\lib.rs.cc(1340): warning C4190: 'tests$cxxbridge1$c_return_slice_char' has C-linkage specified, but returns UDT 'rust::cxxbridge1::Slice<const char>' which is incompatible with C
cxxbridge\crate\tests/ffi/tests.h(93): note: see declaration of 'rust::cxxbridge1::Slice<const char>'
cxxbridge\sources\tests\ffi\lib.rs.cc(1345): warning C4190: 'tests$cxxbridge1$c_return_mutsliceu8' has C-linkage specified, but returns UDT 'rust::cxxbridge1::Slice<uint8_t>' which is incompatible with C
cxxbridge\crate\tests/ffi/tests.h(94): note: see declaration of 'rust::cxxbridge1::Slice<uint8_t>'
cxxbridge\sources\tests\ffi\lib.rs.cc(1976): warning C4190: 'tests$cxxbridge1$r_return_str' has C-linkage specified, but returns UDT 'rust::cxxbridge1::Str' which is incompatible with C
cxxbridge\include\rust/cxx.h(93): note: see declaration of 'rust::cxxbridge1::Str'
cxxbridge\sources\tests\ffi\lib.rs.cc(1978): warning C4190: 'tests$cxxbridge1$r_return_sliceu8' has C-linkage specified, but returns UDT 'rust::cxxbridge1::Slice<const uint8_t>' which is incompatible with C
cxxbridge\crate\tests/ffi/tests.h(163): note: see declaration of 'rust::cxxbridge1::Slice<const uint8_t>'
cxxbridge\sources\tests\ffi\lib.rs.cc(1980): warning C4190: 'tests$cxxbridge1$r_return_mutsliceu8' has C-linkage specified, but returns UDT 'rust::cxxbridge1::Slice<uint8_t>' which is incompatible with C
cxxbridge\crate\tests/ffi/tests.h(94): note: see declaration of 'rust::cxxbridge1::Slice<uint8_t>'
diff --git a/gen/src/write.rs b/gen/src/write.rs
index dcb7850..02f615d 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -133,15 +133,15 @@
let mut slice_in_return_position = OrderedSet::new();
for api in apis {
if let Api::CxxFunction(efn) | Api::RustFunction(efn) = api {
- if let Some(ty @ Type::SliceRef(_)) = &efn.ret {
+ if let Some(ty @ Type::Str(_)) | Some(ty @ Type::SliceRef(_)) = &efn.ret {
slice_in_return_position.insert(ty);
}
}
}
for ty in &slice_in_return_position {
- write!(out, "template class ");
+ write!(out, "template class ::rust::repr::Fat<");
write_type(out, ty);
- writeln!(out, ";");
+ writeln!(out, ">;");
}
out.next_section();
@@ -756,8 +756,10 @@
} else if efn.ret.is_some() {
write!(out, "return ");
}
- if let Some(Type::Ref(_)) = efn.ret {
- write!(out, "&");
+ match &efn.ret {
+ Some(Type::Ref(_)) => write!(out, "&"),
+ Some(Type::Str(_)) | Some(Type::SliceRef(_)) if !indirect_return => write!(out, "{{"),
+ _ => {}
}
match &efn.receiver {
None => write!(out, "{}$(", efn.name.rust),
@@ -795,6 +797,7 @@
match &efn.ret {
Some(Type::RustBox(_)) => write!(out, ".into_raw()"),
Some(Type::UniquePtr(_)) => write!(out, ".release()"),
+ Some(Type::Str(_)) | Some(Type::SliceRef(_)) if !indirect_return => write!(out, "}}"),
_ => {}
}
if indirect_return {
@@ -1038,8 +1041,10 @@
write!(out, ")");
if !indirect_return {
if let Some(ret) = &sig.ret {
- if let Type::RustBox(_) | Type::UniquePtr(_) = ret {
- write!(out, ")");
+ match ret {
+ Type::RustBox(_) | Type::UniquePtr(_) => write!(out, ")"),
+ Type::Str(_) | Type::SliceRef(_) => write!(out, ".repr"),
+ _ => {}
}
}
}
@@ -1109,6 +1114,12 @@
write_type(out, &ty.inner);
write!(out, " *");
}
+ Some(ty @ Type::Str(_)) | Some(ty @ Type::SliceRef(_)) => {
+ out.builtin.repr_fat = true;
+ write!(out, "::rust::repr::Fat<");
+ write_type(out, ty);
+ write!(out, "> ");
+ }
Some(ty) if out.types.needs_indirect_abi(ty) => write!(out, "void "),
_ => write_return_type(out, ty),
}