Index: include/llvm/Support/FormatVariadicDetails.h =================================================================== --- include/llvm/Support/FormatVariadicDetails.h +++ include/llvm/Support/FormatVariadicDetails.h @@ -17,6 +17,7 @@ namespace llvm { template struct format_provider {}; +class Error; namespace detail { class format_adapter { @@ -38,6 +39,11 @@ } }; +// Hack to allow accepting Error by value: formatv("Error: {0}", V.takeError()); +// In this case the error must be marked as consumed. +template void cleanup(T &&) {} +void cleanup(llvm::Error &&E); + template class stream_operator_format_adapter : public format_adapter { T Item; @@ -45,8 +51,10 @@ public: explicit stream_operator_format_adapter(T &&Item) : Item(std::forward(Item)) {} + stream_operator_format_adapter(stream_operator_format_adapter &&) = default; void format(llvm::raw_ostream &S, StringRef Options) override { S << Item; } + ~stream_operator_format_adapter() { detail::cleanup(std::forward(Item)); } }; template class missing_format_adapter; Index: lib/Support/FormatVariadic.cpp =================================================================== --- lib/Support/FormatVariadic.cpp +++ lib/Support/FormatVariadic.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Error.h" using namespace llvm; @@ -152,3 +153,5 @@ } return Replacements; } + +void detail::cleanup(llvm::Error &&E) { consumeError(std::move(E)); } Index: unittests/Support/FormatVariadicTest.cpp =================================================================== --- unittests/Support/FormatVariadicTest.cpp +++ unittests/Support/FormatVariadicTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FormatAdapters.h" #include "gtest/gtest.h" @@ -680,3 +681,11 @@ adl::X X; EXPECT_EQ("X", formatv("{0}", X).str()); } + +TEST(FormatVariadicTest, FormatError) { + auto E1 = make_error("X", inconvertibleErrorCode()); + EXPECT_EQ("X", formatv("{0}", E1).str()); + EXPECT_TRUE(E1.isA()); // not consumed + EXPECT_EQ("X", formatv("{0}", std::move(E1)).str()); + EXPECT_FALSE(E1.isA()); // consumed +}