From a0c9bc7167891d7522270f19b971b3a25d7ed807 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 31 Oct 2020 14:37:14 -0700 Subject: [PATCH] Decouple Error from Str::Repr It was misleading to use Str (which ordinarily represents borrowed strings) also for owned error messages. --- gen/src/write.rs | 25 ++++++++++++++++++++++--- include/cxx.h | 6 ++++-- src/cxx.cc | 15 +++++++-------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/gen/src/write.rs b/gen/src/write.rs index 25f1b0b6..8de422d9 100644 --- a/gen/src/write.rs +++ b/gen/src/write.rs @@ -315,6 +315,25 @@ fn write_include_cxxbridge(out: &mut OutFile, apis: &[Api]) { writeln!(out, "}};"); } + if needs_rust_error { + out.begin_block("namespace repr"); + writeln!(out, "struct PtrLen final {{"); + writeln!(out, " const char *ptr;"); + writeln!(out, " size_t len;"); + writeln!(out, "}};"); + out.end_block("namespace repr"); + + writeln!(out, "class impl final {{"); + writeln!(out, "public:"); + writeln!(out, " static Error error(repr::PtrLen ptrlen) noexcept {{"); + writeln!(out, " Error error;"); + writeln!(out, " error.msg = ptrlen.ptr;"); + writeln!(out, " error.len = ptrlen.len;"); + writeln!(out, " return error;"); + writeln!(out, " }}"); + writeln!(out, "}};"); + } + out.end_block("namespace cxxbridge05"); if needs_trycatch { @@ -685,7 +704,7 @@ fn write_rust_function_decl_impl( indirect_call: bool, ) { if sig.throws { - write!(out, "::rust::Str::Repr "); + write!(out, "::rust::repr::PtrLen "); } else { write_extern_return_type_space(out, &sig.ret); } @@ -823,7 +842,7 @@ fn write_rust_function_shim_impl( } } if sig.throws { - write!(out, "::rust::Str::Repr error$ = "); + write!(out, "::rust::repr::PtrLen error$ = "); } write!(out, "{}(", invoke); if sig.receiver.is_some() { @@ -871,7 +890,7 @@ fn write_rust_function_shim_impl( writeln!(out, ";"); if sig.throws { writeln!(out, " if (error$.ptr) {{"); - writeln!(out, " throw ::rust::Error(error$);"); + writeln!(out, " throw ::rust::impl::error(error$);"); writeln!(out, " }}"); } if indirect_return { diff --git a/include/cxx.h b/include/cxx.h index bf16dd05..d044111b 100644 --- a/include/cxx.h +++ b/include/cxx.h @@ -251,12 +251,14 @@ class Error final : public std::exception { public: Error(const Error &); Error(Error &&) noexcept; - Error(Str::Repr) noexcept; ~Error() noexcept; const char *what() const noexcept override; private: - Str::Repr msg; + Error() noexcept = default; + friend class impl; + const char *msg; + size_t len; }; #endif // CXXBRIDGE05_RUST_ERROR diff --git a/src/cxx.cc b/src/cxx.cc index 43bf245b..077f8ced 100644 --- a/src/cxx.cc +++ b/src/cxx.cc @@ -172,22 +172,21 @@ const char *cxxbridge05$error(const char *ptr, size_t len) { } } // extern "C" -Error::Error(Str::Repr msg) noexcept : msg(msg) {} - Error::Error(const Error &other) { - this->msg.ptr = cxxbridge05$error(other.msg.ptr, other.msg.len); - this->msg.len = other.msg.len; + this->msg = cxxbridge05$error(other.msg, other.len); + this->len = other.len; } Error::Error(Error &&other) noexcept { this->msg = other.msg; - other.msg.ptr = nullptr; - other.msg.len = 0; + this->len = other.len; + other.msg = nullptr; + other.len = 0; } -Error::~Error() noexcept { delete[] this->msg.ptr; } +Error::~Error() noexcept { delete[] this->msg; } -const char *Error::what() const noexcept { return this->msg.ptr; } +const char *Error::what() const noexcept { return this->msg; } } // namespace cxxbridge05 } // namespace rust