[llvm] [orc-rt] Add support for constructing Expected<Error> values. (PR #161656)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 2 05:30:30 PDT 2025
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/161656
These will be used in upcoming RPC support patches where the outer Expected value captures any RPC-infrastructure errors, and the inner Error is returned from the romet call (i.e. the remote handler's return type is Error).
>From e321e75092bc810c221db5cdb8b3775eafca70d4 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Thu, 2 Oct 2025 22:21:46 +1000
Subject: [PATCH] [orc-rt] Add support for constructing Expected<Error> values.
These will be used in upcoming RPC support patches where the outer Expected
value captures any RPC-infrastructure errors, and the inner Error is returned
from the romet call (i.e. the remote handler's return type is Error).
---
orc-rt/include/orc-rt/Error.h | 11 +++++++++++
orc-rt/unittests/ErrorTest.cpp | 23 +++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/orc-rt/include/orc-rt/Error.h b/orc-rt/include/orc-rt/Error.h
index 6b43b3388aff4..48d9064440b6d 100644
--- a/orc-rt/include/orc-rt/Error.h
+++ b/orc-rt/include/orc-rt/Error.h
@@ -288,6 +288,10 @@ class ErrorAsOutParameter {
Error *Err;
};
+/// Tag to force construction of an Expected value in the success state. See
+/// Expected constructor for details.
+struct ForceExpectedSuccessValue {};
+
template <typename T> class ORC_RT_NODISCARD Expected {
template <class OtherT> friend class Expected;
@@ -310,6 +314,13 @@ template <typename T> class ORC_RT_NODISCARD Expected {
new (getErrorStorage()) error_type(Err.takePayload());
}
+ template <typename OtherT>
+ Expected(OtherT &&Val, ForceExpectedSuccessValue _,
+ std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
+ : HasError(false), Unchecked(true) {
+ new (getStorage()) storage_type(std::forward<OtherT>(Val));
+ }
+
/// Create an Expected from a T value.
template <typename OtherT>
Expected(OtherT &&Val,
diff --git a/orc-rt/unittests/ErrorTest.cpp b/orc-rt/unittests/ErrorTest.cpp
index 3fd8279b7dd77..0da55c33961c8 100644
--- a/orc-rt/unittests/ErrorTest.cpp
+++ b/orc-rt/unittests/ErrorTest.cpp
@@ -386,6 +386,29 @@ TEST(ErrorTest, ExpectedCovariance) {
(void)!!A2;
}
+// Test that Expected<Error> works as expected with .
+TEST(ErrorTest, ExpectedError) {
+ {
+ // Test success-success case.
+ Expected<Error> E(Error::success(), ForceExpectedSuccessValue());
+ EXPECT_TRUE(!!E);
+ cantFail(E.takeError());
+ auto Err = std::move(*E);
+ EXPECT_FALSE(!!Err);
+ }
+
+ {
+ // Test "failure" success case.
+ Expected<Error> E(make_error<StringError>("foo"),
+ ForceExpectedSuccessValue());
+ EXPECT_TRUE(!!E);
+ cantFail(E.takeError());
+ auto Err = std::move(*E);
+ EXPECT_TRUE(!!Err);
+ EXPECT_EQ(toString(std::move(Err)), "foo");
+ }
+}
+
// Test that the ExitOnError utility works as expected.
TEST(ErrorTest, CantFailSuccess) {
cantFail(Error::success());
More information about the llvm-commits
mailing list