diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/cxx/book/src/binding/result.md | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/cxx/book/src/binding/result.md')
-rw-r--r-- | vendor/cxx/book/src/binding/result.md | 148 |
1 files changed, 0 insertions, 148 deletions
diff --git a/vendor/cxx/book/src/binding/result.md b/vendor/cxx/book/src/binding/result.md deleted file mode 100644 index e49dcf4de..000000000 --- a/vendor/cxx/book/src/binding/result.md +++ /dev/null @@ -1,148 +0,0 @@ -{{#title Result<T> — Rust ♡ C++}} -# Result\<T\> - -Result\<T\> is allowed as the return type of an extern function in either -direction. Its behavior is to translate to/from C++ exceptions. If your codebase -does not use C++ exceptions, or prefers to represent fallibility using something -like outcome\<T\>, leaf::result\<T\>, StatusOr\<T\>, etc then you'll need to -handle the translation of those to Rust Result\<T\> using your own shims for -now. Better support for this is planned. - -If an exception is thrown from an `extern "C++"` function that is *not* declared -by the CXX bridge to return Result, the program calls C++'s `std::terminate`. -The behavior is equivalent to the same exception being thrown through a -`noexcept` C++ function. - -If a panic occurs in *any* `extern "Rust"` function, regardless of whether it is -declared by the CXX bridge to return Result, a message is logged and the program -calls Rust's `std::process::abort`. - -## Returning Result from Rust to C++ - -An `extern "Rust"` function returning a Result turns into a `throw` in C++ if -the Rust side produces an error. - -Note that the return type written inside of cxx::bridge must be written without -a second type parameter. Only the Ok type is specified for the purpose of the -FFI. The Rust *implementation* (outside of the bridge module) may pick any error -type as long as it has a std::fmt::Display impl. - -```rust,noplayground -# use std::io; -# -#[cxx::bridge] -mod ffi { - extern "Rust" { - fn fallible1(depth: usize) -> Result<String>; - fn fallible2() -> Result<()>; - } -} - -fn fallible1(depth: usize) -> anyhow::Result<String> { - if depth == 0 { - return Err(anyhow::Error::msg("fallible1 requires depth > 0")); - } - ... -} - -fn fallible2() -> Result<(), io::Error> { - ... - Ok(()) -} -``` - -The exception that gets thrown by CXX on the C++ side is always of type -`rust::Error` and has the following C++ public API. The `what()` member function -gives the error message according to the Rust error's std::fmt::Display impl. - -```cpp,hidelines -// rust/cxx.h -# -# namespace rust { - -class Error final : public std::exception { -public: - Error(const Error &); - Error(Error &&) noexcept; - ~Error() noexcept; - - Error &operator=(const Error &); - Error &operator=(Error &&) noexcept; - - const char *what() const noexcept override; -}; -# -# } // namespace rust -``` - -## Returning Result from C++ to Rust - -An `extern "C++"` function returning a Result turns into a `catch` in C++ that -converts the exception into an Err for Rust. - -Note that the return type written inside of cxx::bridge must be written without -a second type parameter. Only the Ok type is specified for the purpose of the -FFI. The resulting error type created by CXX when an `extern "C++"` function -throws will always be of type **[`cxx::Exception`]**. - -[`cxx::Exception`]: https://docs.rs/cxx/*/cxx/struct.Exception.html - -```rust,noplayground -# use std::process; -# -#[cxx::bridge] -mod ffi { - unsafe extern "C++" { - include!("example/include/example.h"); - fn fallible1(depth: usize) -> Result<String>; - fn fallible2() -> Result<()>; - } -} - -fn main() { - if let Err(err) = ffi::fallible1(99) { - eprintln!("Error: {}", err); - process::exit(1); - } -} -``` - -The specific set of caught exceptions and the conversion to error message are -both customizable. The way you do this is by defining a template function -`rust::behavior::trycatch` with a suitable signature inside any one of the -headers `include!`'d by your cxx::bridge. - -The template signature is required to be: - -```cpp,hidelines -namespace rust { -namespace behavior { - -template <typename Try, typename Fail> -static void trycatch(Try &&func, Fail &&fail) noexcept; - -} // namespace behavior -} // namespace rust -``` - -The default `trycatch` used by CXX if you have not provided your own is the -following. You must follow the same pattern: invoke `func` with no arguments, -catch whatever exception(s) you want, and invoke `fail` with the error message -you'd like for the Rust error to have. - -```cpp,hidelines -# #include <exception> -# -# namespace rust { -# namespace behavior { -# -template <typename Try, typename Fail> -static void trycatch(Try &&func, Fail &&fail) noexcept try { - func(); -} catch (const std::exception &e) { - fail(e.what()); -} -# -# } // namespace behavior -# } // namespace rust -``` |