From 99ce20624629921771de2674946bbb2f9707ca5a Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Thu, 2 Oct 2025 22:36:02 +1000 Subject: [PATCH] [orc-rt] Add support for constructing Expected values. (#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). --- 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 6b43b3388aff..48d9064440b6 100644 --- a/orc-rt/include/orc-rt/Error.h +++ b/orc-rt/include/orc-rt/Error.h @@ -288,6 +288,10 @@ private: Error *Err; }; +/// Tag to force construction of an Expected value in the success state. See +/// Expected constructor for details. +struct ForceExpectedSuccessValue {}; + template class ORC_RT_NODISCARD Expected { template friend class Expected; @@ -310,6 +314,13 @@ public: new (getErrorStorage()) error_type(Err.takePayload()); } + template + Expected(OtherT &&Val, ForceExpectedSuccessValue _, + std::enable_if_t> * = nullptr) + : HasError(false), Unchecked(true) { + new (getStorage()) storage_type(std::forward(Val)); + } + /// Create an Expected from a T value. template Expected(OtherT &&Val, diff --git a/orc-rt/unittests/ErrorTest.cpp b/orc-rt/unittests/ErrorTest.cpp index 3fd8279b7dd7..0da55c33961c 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 works as expected with . +TEST(ErrorTest, ExpectedError) { + { + // Test success-success case. + Expected E(Error::success(), ForceExpectedSuccessValue()); + EXPECT_TRUE(!!E); + cantFail(E.takeError()); + auto Err = std::move(*E); + EXPECT_FALSE(!!Err); + } + + { + // Test "failure" success case. + Expected E(make_error("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());