From: Arthur Cohen <arthur.co...@embecosm.com> gcc/rust/ChangeLog:
* util/rust-lang-item.h: Add handling for Result::Ok, Result::Err, Try, Try::into_result, Try::from_ok, Try::from_err. * util/rust-lang-item.cc: Likewise. gcc/testsuite/ChangeLog: * rust/compile/try-trait.rs: New test. --- gcc/rust/util/rust-lang-item.cc | 8 +++++ gcc/rust/util/rust-lang-item.h | 12 +++++++ gcc/testsuite/rust/compile/try-trait.rs | 44 +++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 gcc/testsuite/rust/compile/try-trait.rs diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc index 7460df0a6da..ac90f979e83 100644 --- a/gcc/rust/util/rust-lang-item.cc +++ b/gcc/rust/util/rust-lang-item.cc @@ -97,11 +97,19 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{ {"Some", Kind::OPTION_SOME}, {"None", Kind::OPTION_NONE}, + {"Ok", Kind::RESULT_OK}, + {"Err", Kind::RESULT_ERR}, + {"into_iter", Kind::INTOITER_INTOITER}, {"next", Kind::ITERATOR_NEXT}, {"eq", Kind::EQ}, {"partial_ord", Kind::PARTIAL_ORD}, + + {"try", Kind::TRY}, + {"into_result", Kind::TRY_INTO_RESULT}, + {"from_error", Kind::TRY_FROM_ERROR}, + {"from_ok", Kind::TRY_FROM_OK}, }}; tl::optional<LangItem::Kind> diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h index e68f0559084..ad081a7d3fb 100644 --- a/gcc/rust/util/rust-lang-item.h +++ b/gcc/rust/util/rust-lang-item.h @@ -127,8 +127,20 @@ public: OPTION_SOME, OPTION_NONE, + RESULT_OK, + RESULT_ERR, + INTOITER_INTOITER, ITERATOR_NEXT, + + // NOTE: These lang items are *not* necessarily present in later versions of + // Rust (I am unsure at which point they have been removed as the `Try` + // trait is unstable). They will need to be changed when updating the + // targeted Rust version of gccrs + TRY, + TRY_INTO_RESULT, + TRY_FROM_ERROR, + TRY_FROM_OK, }; static const BiMap<std::string, Kind> lang_items; diff --git a/gcc/testsuite/rust/compile/try-trait.rs b/gcc/testsuite/rust/compile/try-trait.rs new file mode 100644 index 00000000000..9ec135dcd56 --- /dev/null +++ b/gcc/testsuite/rust/compile/try-trait.rs @@ -0,0 +1,44 @@ +#[lang = "sized"] +trait Sized {} + +enum Result<T, E> { + #[lang = "Ok"] + Ok(T), + #[lang = "Err"] + Err(E) +} + +#[lang = "try"] +pub trait Try { + /// The type of this value when viewed as successful. + #[unstable(feature = "try_trait", issue = "42327")] + type Ok; + /// The type of this value when viewed as failed. + #[unstable(feature = "try_trait", issue = "42327")] + type Error; + + /// Applies the "?" operator. A return of `Ok(t)` means that the + /// execution should continue normally, and the result of `?` is the + /// value `t`. A return of `Err(e)` means that execution should branch + /// to the innermost enclosing `catch`, or return from the function. + /// + /// If an `Err(e)` result is returned, the value `e` will be "wrapped" + /// in the return type of the enclosing scope (which must itself implement + /// `Try`). Specifically, the value `X::from_error(From::from(e))` + /// is returned, where `X` is the return type of the enclosing function. + #[lang = "into_result"] + #[unstable(feature = "try_trait", issue = "42327")] + fn into_result(self) -> Result<Self::Ok, Self::Error>; + + /// Wrap an error value to construct the composite result. For example, + /// `Result::Err(x)` and `Result::from_error(x)` are equivalent. + #[lang = "from_error"] + #[unstable(feature = "try_trait", issue = "42327")] + fn from_error(v: Self::Error) -> Self; + + /// Wrap an OK value to construct the composite result. For example, + /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent. + #[lang = "from_ok"] + #[unstable(feature = "try_trait", issue = "42327")] + fn from_ok(v: Self::Ok) -> Self; +} -- 2.45.2