Bug 1582358 - Fix move semantics for Result where the error is non-copiable. r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D46428

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-09-20 01:18:40 +00:00
parent 45d763195f
commit 5c4d9db375
2 changed files with 47 additions and 2 deletions

View File

@ -339,6 +339,18 @@ class MOZ_MUST_USE_TYPE Result final {
MOZ_ASSERT(isErr());
}
/**
* Implementation detail of MOZ_TRY().
* Create an error result from another error result.
*/
template <typename E2>
MOZ_IMPLICIT Result(GenericErrorResult<E2>&& aErrorResult)
: mImpl(std::forward<E2>(aErrorResult.mErrorValue)) {
static_assert(mozilla::IsConvertible<E2, E>::value,
"E2 must be convertible to E");
MOZ_ASSERT(isErr());
}
/**
* Implementation detail of MOZ_TRY().
* Create an error result from another error result.
@ -470,12 +482,13 @@ class MOZ_MUST_USE_TYPE GenericErrorResult {
friend class Result;
public:
explicit GenericErrorResult(E aErrorValue) : mErrorValue(aErrorValue) {}
explicit GenericErrorResult(E aErrorValue)
: mErrorValue(std::forward<E>(aErrorValue)) {}
};
template <typename E>
inline GenericErrorResult<E> Err(E&& aErrorValue) {
return GenericErrorResult<E>(aErrorValue);
return GenericErrorResult<E>(std::forward<E>(aErrorValue));
}
} // namespace mozilla

View File

@ -231,6 +231,16 @@ using UniqueResult = Result<UniquePtr<int>, const char*>;
static UniqueResult UniqueTask() { return mozilla::MakeUnique<int>(3); }
static UniqueResult UniqueTaskError() { return Err("bad"); }
using UniqueErrorResult = Result<int, UniquePtr<int>>;
static UniqueErrorResult UniqueError() {
return Err(mozilla::MakeUnique<int>(4));
}
static Result<Ok, UniquePtr<int>> TryUniqueErrorResult() {
MOZ_TRY(UniqueError());
return Ok();
}
static void UniquePtrTest() {
{
auto result = UniqueTask();
@ -256,6 +266,28 @@ static void UniquePtrTest() {
MOZ_RELEASE_ASSERT(result.isOk());
MOZ_RELEASE_ASSERT(result.inspect() && *result.inspect() == 6);
}
{
auto result = UniqueError();
MOZ_RELEASE_ASSERT(result.isErr());
MOZ_RELEASE_ASSERT(result.inspectErr());
MOZ_RELEASE_ASSERT(*result.inspectErr() == 4);
auto err = result.unwrapErr();
MOZ_RELEASE_ASSERT(!result.inspectErr());
MOZ_RELEASE_ASSERT(err);
MOZ_RELEASE_ASSERT(*err == 4);
result = UniqueErrorResult(0);
MOZ_RELEASE_ASSERT(result.isOk() && result.unwrap() == 0);
}
{
auto result = TryUniqueErrorResult();
MOZ_RELEASE_ASSERT(result.isErr());
auto err = result.unwrapErr();
MOZ_RELEASE_ASSERT(err && *err == 4);
MOZ_RELEASE_ASSERT(!result.inspectErr());
}
}
/* * */