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),
     }