Skip to content

Commit 99ce206

Browse files
authored
[orc-rt] Add support for constructing Expected<Error> 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).
1 parent 9583b39 commit 99ce206

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

orc-rt/include/orc-rt/Error.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ class ErrorAsOutParameter {
288288
Error *Err;
289289
};
290290

291+
/// Tag to force construction of an Expected value in the success state. See
292+
/// Expected constructor for details.
293+
struct ForceExpectedSuccessValue {};
294+
291295
template <typename T> class ORC_RT_NODISCARD Expected {
292296

293297
template <class OtherT> friend class Expected;
@@ -310,6 +314,13 @@ template <typename T> class ORC_RT_NODISCARD Expected {
310314
new (getErrorStorage()) error_type(Err.takePayload());
311315
}
312316

317+
template <typename OtherT>
318+
Expected(OtherT &&Val, ForceExpectedSuccessValue _,
319+
std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
320+
: HasError(false), Unchecked(true) {
321+
new (getStorage()) storage_type(std::forward<OtherT>(Val));
322+
}
323+
313324
/// Create an Expected from a T value.
314325
template <typename OtherT>
315326
Expected(OtherT &&Val,

orc-rt/unittests/ErrorTest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,29 @@ TEST(ErrorTest, ExpectedCovariance) {
386386
(void)!!A2;
387387
}
388388

389+
// Test that Expected<Error> works as expected with .
390+
TEST(ErrorTest, ExpectedError) {
391+
{
392+
// Test success-success case.
393+
Expected<Error> E(Error::success(), ForceExpectedSuccessValue());
394+
EXPECT_TRUE(!!E);
395+
cantFail(E.takeError());
396+
auto Err = std::move(*E);
397+
EXPECT_FALSE(!!Err);
398+
}
399+
400+
{
401+
// Test "failure" success case.
402+
Expected<Error> E(make_error<StringError>("foo"),
403+
ForceExpectedSuccessValue());
404+
EXPECT_TRUE(!!E);
405+
cantFail(E.takeError());
406+
auto Err = std::move(*E);
407+
EXPECT_TRUE(!!Err);
408+
EXPECT_EQ(toString(std::move(Err)), "foo");
409+
}
410+
}
411+
389412
// Test that the ExitOnError utility works as expected.
390413
TEST(ErrorTest, CantFailSuccess) {
391414
cantFail(Error::success());

0 commit comments

Comments
 (0)