Eliminate Str::Repr struct

This commit is contained in:
David Tolnay 2020-10-31 12:31:10 -07:00
parent 1549106cb0
commit 5df1f06eb8
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
4 changed files with 22 additions and 39 deletions

View File

@ -619,7 +619,6 @@ fn write_cxx_function_shim(out: &mut OutFile, efn: &ExternFn, impl_annotations:
} }
match &efn.ret { match &efn.ret {
Some(Type::Ref(_)) => write!(out, "&"), Some(Type::Ref(_)) => write!(out, "&"),
Some(Type::Str(_)) if !indirect_return => write!(out, "::rust::Str::Repr("),
Some(Type::SliceRefU8(_)) if !indirect_return => { Some(Type::SliceRefU8(_)) if !indirect_return => {
write!(out, "::rust::Slice<uint8_t>::Repr(") write!(out, "::rust::Slice<uint8_t>::Repr(")
} }
@ -659,7 +658,7 @@ fn write_cxx_function_shim(out: &mut OutFile, efn: &ExternFn, impl_annotations:
match &efn.ret { match &efn.ret {
Some(Type::RustBox(_)) => write!(out, ".into_raw()"), Some(Type::RustBox(_)) => write!(out, ".into_raw()"),
Some(Type::UniquePtr(_)) => write!(out, ".release()"), Some(Type::UniquePtr(_)) => write!(out, ".release()"),
Some(Type::Str(_)) | Some(Type::SliceRefU8(_)) if !indirect_return => write!(out, ")"), Some(Type::SliceRefU8(_)) if !indirect_return => write!(out, ")"),
_ => {} _ => {}
} }
if indirect_return { if indirect_return {
@ -866,7 +865,6 @@ fn write_rust_function_shim_impl(
write!(out, ", "); write!(out, ", ");
} }
match &arg.ty { match &arg.ty {
Type::Str(_) => write!(out, "::rust::Str::Repr("),
Type::SliceRefU8(_) => write!(out, "::rust::Slice<uint8_t>::Repr("), Type::SliceRefU8(_) => write!(out, "::rust::Slice<uint8_t>::Repr("),
ty if out.types.needs_indirect_abi(ty) => write!(out, "&"), ty if out.types.needs_indirect_abi(ty) => write!(out, "&"),
_ => {} _ => {}
@ -875,7 +873,7 @@ fn write_rust_function_shim_impl(
match &arg.ty { match &arg.ty {
Type::RustBox(_) => write!(out, ".into_raw()"), Type::RustBox(_) => write!(out, ".into_raw()"),
Type::UniquePtr(_) => write!(out, ".release()"), Type::UniquePtr(_) => write!(out, ".release()"),
Type::Str(_) | Type::SliceRefU8(_) => write!(out, ")"), Type::SliceRefU8(_) => write!(out, ")"),
ty if ty != RustString && out.types.needs_indirect_abi(ty) => write!(out, "$.value"), ty if ty != RustString && out.types.needs_indirect_abi(ty) => write!(out, "$.value"),
_ => {} _ => {}
} }
@ -939,7 +937,6 @@ fn write_indirect_return_type(out: &mut OutFile, ty: &Type) {
write_type(out, &ty.inner); write_type(out, &ty.inner);
write!(out, " *"); write!(out, " *");
} }
Type::Str(_) => write!(out, "::rust::Str::Repr"),
Type::SliceRefU8(_) => write!(out, "::rust::Slice<uint8_t>::Repr"), Type::SliceRefU8(_) => write!(out, "::rust::Slice<uint8_t>::Repr"),
_ => write_type(out, ty), _ => write_type(out, ty),
} }
@ -967,7 +964,6 @@ fn write_extern_return_type_space(out: &mut OutFile, ty: &Option<Type>) {
write_type(out, &ty.inner); write_type(out, &ty.inner);
write!(out, " *"); write!(out, " *");
} }
Some(Type::Str(_)) => write!(out, "::rust::Str::Repr "),
Some(Type::SliceRefU8(_)) => write!(out, "::rust::Slice<uint8_t>::Repr "), Some(Type::SliceRefU8(_)) => write!(out, "::rust::Slice<uint8_t>::Repr "),
Some(ty) if out.types.needs_indirect_abi(ty) => write!(out, "void "), Some(ty) if out.types.needs_indirect_abi(ty) => write!(out, "void "),
_ => write_return_type(out, ty), _ => write_return_type(out, ty),
@ -980,7 +976,6 @@ fn write_extern_arg(out: &mut OutFile, arg: &Var) {
write_type_space(out, &ty.inner); write_type_space(out, &ty.inner);
write!(out, "*"); write!(out, "*");
} }
Type::Str(_) => write!(out, "::rust::Str::Repr "),
Type::SliceRefU8(_) => write!(out, "::rust::Slice<uint8_t>::Repr "), Type::SliceRefU8(_) => write!(out, "::rust::Slice<uint8_t>::Repr "),
_ => write_type_space(out, &arg.ty), _ => write_type_space(out, &arg.ty),
} }

View File

@ -79,20 +79,12 @@ public:
Str(const Str &) noexcept = default; Str(const Str &) noexcept = default;
~Str() noexcept = default; ~Str() noexcept = default;
// Repr is PRIVATE; must not be used other than by our generated code. private:
//
// Not necessarily ABI compatible with &str. Codegen will translate to // Not necessarily ABI compatible with &str. Codegen will translate to
// cxx::rust_str::RustStr which matches this layout. // cxx::rust_str::RustStr which matches this layout.
struct Repr final {
const char *ptr; const char *ptr;
size_t len; size_t len;
}; };
Str(Repr) noexcept;
explicit operator Repr() const noexcept;
private:
Repr repr;
};
#endif // CXXBRIDGE05_RUST_STR #endif // CXXBRIDGE05_RUST_STR
#ifndef CXXBRIDGE05_RUST_SLICE #ifndef CXXBRIDGE05_RUST_SLICE

View File

@ -115,33 +115,33 @@ std::ostream &operator<<(std::ostream &os, const String &s) {
return os; return os;
} }
Str::Str() noexcept : repr(Repr{reinterpret_cast<const char *>(1), 0}) {} Str::Str() noexcept : ptr(reinterpret_cast<const char *>(1)), len(0) {}
static void initStr(Str::Repr repr) { static void initStr(const char *ptr, size_t len) {
if (!cxxbridge05$str$valid(repr.ptr, repr.len)) { if (!cxxbridge05$str$valid(ptr, len)) {
panic<std::invalid_argument>("data for rust::Str is not utf-8"); panic<std::invalid_argument>("data for rust::Str is not utf-8");
} }
} }
Str::Str(const std::string &s) : repr(Repr{s.data(), s.length()}) { Str::Str(const std::string &s) : ptr(s.data()), len(s.length()) {
initStr(this->repr); initStr(this->ptr, this->len);
} }
Str::Str(const char *s) : repr(Repr{s, std::strlen(s)}) { Str::Str(const char *s) : ptr(s), len(std::strlen(s)) {
assert(s != nullptr); assert(s != nullptr);
initStr(this->repr); initStr(this->ptr, this->len);
} }
Str::Str(const char *s, size_t len) Str::Str(const char *s, size_t len)
: repr( : ptr(s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s),
Repr{s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s, len(len) {
len}) {
assert(s != nullptr || len == 0); assert(s != nullptr || len == 0);
initStr(this->repr); initStr(this->ptr, this->len);
} }
Str &Str::operator=(Str other) noexcept { Str &Str::operator=(Str other) noexcept {
this->repr = other.repr; this->ptr = other.ptr;
this->len = other.len;
return *this; return *this;
} }
@ -149,15 +149,11 @@ Str::operator std::string() const {
return std::string(this->data(), this->size()); return std::string(this->data(), this->size());
} }
const char *Str::data() const noexcept { return this->repr.ptr; } const char *Str::data() const noexcept { return this->ptr; }
size_t Str::size() const noexcept { return this->repr.len; } size_t Str::size() const noexcept { return this->len; }
size_t Str::length() const noexcept { return this->repr.len; } size_t Str::length() const noexcept { return this->len; }
Str::Str(Repr repr_) noexcept : repr(repr_) {}
Str::operator Repr() const noexcept { return this->repr; }
std::ostream &operator<<(std::ostream &os, const Str &s) { std::ostream &operator<<(std::ostream &os, const Str &s) {
os.write(s.data(), s.size()); os.write(s.data(), s.size());

View File

@ -18,7 +18,7 @@ fn test_extern_c_function() {
let output = str::from_utf8(&generated.implementation).unwrap(); let output = str::from_utf8(&generated.implementation).unwrap();
// To avoid continual breakage we won't test every byte. // To avoid continual breakage we won't test every byte.
// Let's look for the major features. // Let's look for the major features.
assert!(output.contains("void cxxbridge05$do_cpp_thing(::rust::Str::Repr foo)")); assert!(output.contains("void cxxbridge05$do_cpp_thing(::rust::Str foo)"));
} }
#[test] #[test]
@ -28,5 +28,5 @@ fn test_impl_annotation() {
let source = BRIDGE0.parse().unwrap(); let source = BRIDGE0.parse().unwrap();
let generated = generate_header_and_cc(source, &opt).unwrap(); let generated = generate_header_and_cc(source, &opt).unwrap();
let output = str::from_utf8(&generated.implementation).unwrap(); let output = str::from_utf8(&generated.implementation).unwrap();
assert!(output.contains("ANNOTATION void cxxbridge05$do_cpp_thing(::rust::Str::Repr foo)")); assert!(output.contains("ANNOTATION void cxxbridge05$do_cpp_thing(::rust::Str foo)"));
} }