Decouple Error from Str::Repr

It was misleading to use Str (which ordinarily represents borrowed
strings) also for owned error messages.
This commit is contained in:
David Tolnay 2020-10-31 14:37:14 -07:00
parent 5b41479aeb
commit a0c9bc7167
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
3 changed files with 33 additions and 13 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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