Repository: carbon-language/carbon-lang
File: common/error_test.cpp (C++)

Code before:

TYPED_TEST(ErrorOrTest, AssignOrReturnHasErrorInExpected) {
  using TestErrorOr = typename TestFixture::template TestErrorOrTemp<int>;
  auto result = [this]() -> TestErrorOr {
    CARBON_ASSIGN_OR_RETURN(int a, TestErrorOr(this->MakeError()));
    return a;
  }();
  EXPECT_THAT(result, IsError(this->ErrorStr()));
}

class AnotherCustomError : public ErrorBase<AnotherCustomError> {
 public:
  auto Print(llvm::raw_ostream& os) const -> void {
    os << "Another custom test error!";
  }

  explicit operator CustomError() { return CustomError(); }
};

TYPED_TEST(ErrorOrTest, AssignOrReturnNoErrorAcrossErrorTypes) {
  using TestErrorOr = typename TestFixture::template TestErrorOrTemp<int>;
  auto result = []() -> ErrorOr<int> {
    CARBON_ASSIGN_OR_RETURN(int a, TestErrorOr(1));
    CARBON_ASSIGN_OR_RETURN(const int b, []() -> TestErrorOr {
      CARBON_ASSIGN_OR_RETURN(
          int inner, (static_cast<ErrorOr<int, AnotherCustomError>>(2)));
      return inner;
    }());
    int c = 0;
    CARBON_ASSIGN_OR_RETURN(c, TestErrorOr(3));
    return a + b + c;
  }();
  EXPECT_THAT(result, IsSuccess(Eq(6)));
}

TYPED_TEST(ErrorOrTest, AssignOrReturnErrorAcrossErrorTypes) {
  using TestErrorOr = typename TestFixture::template TestErrorOrTemp<int>;
  auto result = []() -> ErrorOr<int> {
    CARBON_ASSIGN_OR_RETURN(int a, TestErrorOr(1));
    CARBON_ASSIGN_OR_RETURN(const int b, []() -> TestErrorOr {
      CARBON_ASSIGN_OR_RETURN(int inner,
                              (static_cast<ErrorOr<int, AnotherCustomError>>(
                                  AnotherCustomError())));
      return inner;
    }());
    int c = 0;
    CARBON_ASSIGN_OR_RETURN(c, TestErrorOr(3));
    return a + b + c;
  }();

  // When directly using the `Error` type, the explicit custom type above has

Review comment (suggestion):
```suggestion
          int inner, (ErrorOr<int, AnotherCustomError>(2)));
```

Per your comment about what you're trying to test -- maybe the cast here isn't needed, and you can just construct?

I'd just been assuming because you originally had that c-style cast

Code after:
    return a;
  }();
  EXPECT_THAT(result, IsError(this->ErrorStr()));
}

class AnotherCustomError : public ErrorBase<AnotherCustomError> {
 public:
  auto Print(llvm::raw_ostream& os) const -> void {
    os << "Another custom test error!";
  }

  explicit operator CustomError() { return CustomError(); }
};

TYPED_TEST(ErrorOrTest, AssignOrReturnNoErrorAcrossErrorTypes) {
  using TestErrorOr = ErrorOr<int, TypeParam>;
  auto result = []() -> ErrorOr<int> {
    CARBON_ASSIGN_OR_RETURN(int a, TestErrorOr(1));
    CARBON_ASSIGN_OR_RETURN(const int b, []() -> TestErrorOr {
      CARBON_ASSIGN_OR_RETURN(int inner, (ErrorOr<int, AnotherCustomError>(2)));
      return inner;
    }());
    int c = 0;
    CARBON_ASSIGN_OR_RETURN(c, TestErrorOr(3));
    return a + b + c;
  }();
  EXPECT_THAT(result, IsSuccess(Eq(6)));
}

TYPED_TEST(ErrorOrTest, AssignOrReturnErrorAcrossErrorTypes) {
  using TestErrorOr = ErrorOr<int, TypeParam>;
  auto result = []() -> ErrorOr<int> {
    CARBON_ASSIGN_OR_RETURN(int a, TestErrorOr(1));
    CARBON_ASSIGN_OR_RETURN(const int b, []() -> TestErrorOr {
      CARBON_ASSIGN_OR_RETURN(
          int inner, (ErrorOr<int, AnotherCustomError>(AnotherCustomError())));
      return inner;
    }());
    int c = 0;
    CARBON_ASSIGN_OR_RETURN(c, TestErrorOr(3));
    return a + b + c;
  }();

  // When directly using the `Error` type, the explicit custom type above has
  // its message preserved. When testing against `CustomError`, that one
  // overrides the message.
  if constexpr (std::same_as<TypeParam, Error>) {
    EXPECT_THAT(result, IsError("Another custom test error!"));
  } else {
    EXPECT_THAT(result, IsError("Custom test error!"));
  }