diff --git a/common/BUILD b/common/BUILD index b6d1ff7ac018..a3d5173df792 100644 --- a/common/BUILD +++ b/common/BUILD @@ -68,6 +68,7 @@ cc_library( hdrs = ["check.h"], deps = [ ":ostream", + ":template_string", "@llvm-project//llvm:Support", ], ) @@ -329,6 +330,7 @@ cc_library( hdrs = ["raw_hashtable_metadata_group.h"], deps = [ ":check", + ":ostream", "@llvm-project//llvm:Support", ], ) diff --git a/common/array_stack.h b/common/array_stack.h index ff22147722da..c39bccf1d8cf 100644 --- a/common/array_stack.h +++ b/common/array_stack.h @@ -62,15 +62,15 @@ class ArrayStack { // Appends a value to the top array on the stack. auto AppendToTop(ValueT value) -> void { - CARBON_CHECK(!array_offsets_.empty()) - << "Must call PushArray before PushValue."; + CARBON_CHECK(!array_offsets_.empty(), + "Must call PushArray before PushValue."); values_.push_back(value); } // Adds multiple values to the top array on the stack. auto AppendToTop(llvm::ArrayRef values) -> void { - CARBON_CHECK(!array_offsets_.empty()) - << "Must call PushArray before PushValues."; + CARBON_CHECK(!array_offsets_.empty(), + "Must call PushArray before PushValues."); values_.append(values.begin(), values.end()); } diff --git a/common/check.h b/common/check.h index ef8e1367a37c..1db43681c7d0 100644 --- a/common/check.h +++ b/common/check.h @@ -14,30 +14,40 @@ namespace Carbon { // a bug in the application. // // For example: -// CARBON_CHECK(is_valid) << "Data is not valid!"; -#define CARBON_CHECK(...) \ - (__VA_ARGS__) ? (void)0 \ - : CARBON_CHECK_INTERNAL_STREAM() \ - << "CHECK failure at " << __FILE__ << ":" << __LINE__ \ - << ": " #__VA_ARGS__ \ - << Carbon::Internal::ExitingStream::AddSeparator() +// CARBON_CHECK(is_valid, "Data is not valid!"); +// +// The condition must be parenthesized if it contains top-level commas, for +// example in a template argument list: +// CARBON_CHECK((inst.IsOneOf()), +// "Unexpected inst {0}", inst); +#define CARBON_CHECK(condition, ...) \ + (condition) ? (void)0 \ + : CARBON_INTERNAL_CHECK(condition __VA_OPT__(, ) __VA_ARGS__) // DCHECK calls CHECK in debug mode, and does nothing otherwise. #ifndef NDEBUG -#define CARBON_DCHECK(...) CARBON_CHECK(__VA_ARGS__) +#define CARBON_DCHECK(condition, ...) \ + CARBON_CHECK(condition __VA_OPT__(, ) __VA_ARGS__) #else -#define CARBON_DCHECK(...) CARBON_CHECK(true || (__VA_ARGS__)) +// When in a debug build we want to preserve as much as we can of how the +// parameters are used, other than making them be trivially in dead code and +// eliminated by the optimizer. As a consequence we preserve the condition but +// prefix it with a short-circuit operator, and we still emit the (dead) call to +// the check implementation. But we use a special implementation that reduces +// the compile time cost. +#define CARBON_DCHECK(condition, ...) \ + (true || (condition)) \ + ? (void)0 \ + : CARBON_INTERNAL_DEAD_DCHECK(condition __VA_OPT__(, ) __VA_ARGS__) #endif -// This is similar to CHECK, but is unconditional. Writing CARBON_FATAL() is -// clearer than CARBON_CHECK(false) because it avoids confusion about control -// flow. +// This is similar to CHECK, but is unconditional. Writing +// `CARBON_FATAL("message")` is clearer than `CARBON_CHECK(false, "message") +// because it avoids confusion about control flow. // // For example: -// CARBON_FATAL() << "Unreachable!"; -#define CARBON_FATAL() \ - CARBON_CHECK_INTERNAL_STREAM() \ - << "FATAL failure at " << __FILE__ << ":" << __LINE__ << ": " +// CARBON_FATAL("Unreachable!"); +#define CARBON_FATAL(...) CARBON_INTERNAL_FATAL(__VA_ARGS__) } // namespace Carbon diff --git a/common/check_internal.cpp b/common/check_internal.cpp index f365eed0c66a..9fc5cd653a15 100644 --- a/common/check_internal.cpp +++ b/common/check_internal.cpp @@ -4,7 +4,7 @@ #include "common/check_internal.h" -#include "llvm/Support/ErrorHandling.h" +#include "common/ostream.h" #include "llvm/Support/Signals.h" namespace Carbon::Internal { @@ -14,22 +14,20 @@ static auto PrintAfterStackTrace(void* str) -> void { llvm::errs() << reinterpret_cast(str); } -ExitingStream::~ExitingStream() { - llvm_unreachable( - "Exiting streams should only be constructed by check.h macros that " - "ensure the special operator| exits the program prior to their " - "destruction!"); -} +auto CheckFailImpl(const char* kind, const char* file, int line, + const char* condition_str, llvm::StringRef extra_message) + -> void { + // Render the final check string here. + std::string message = llvm::formatv( + "{0} failure at {1}:{2}{3}{4}{5}{6}\n", kind, file, line, + llvm::StringRef(condition_str).empty() ? "" : ": ", condition_str, + extra_message.empty() ? "" : ": ", extra_message); -auto ExitingStream::Done() -> void { - buffer_ << "\n"; - buffer_.flush(); - - // Register another signal handler to print the buffered message. This is - // because we want it at the bottom of output, after LLVM's builtin stack - // output, rather than the top. + // Register another signal handler to print the message. This is because we + // want it at the bottom of output, after LLVM's builtin stack output, rather + // than the top. llvm::sys::AddSignalHandler(PrintAfterStackTrace, - const_cast(buffer_str_.c_str())); + const_cast(message.c_str())); // It's useful to exit the program with `std::abort()` for integration with // debuggers and other tools. We also assume LLVM's exit handling is // installed, which will stack trace on `std::abort()`. diff --git a/common/check_internal.h b/common/check_internal.h index 9f4ea0e042c7..300b6028cff9 100644 --- a/common/check_internal.h +++ b/common/check_internal.h @@ -5,73 +5,106 @@ #ifndef CARBON_COMMON_CHECK_INTERNAL_H_ #define CARBON_COMMON_CHECK_INTERNAL_H_ -#include "common/ostream.h" +#include "common/template_string.h" +#include "llvm/Support/FormatVariadic.h" namespace Carbon::Internal { -// Wraps a stream and exiting for fatal errors. Should only be used by check.h -// macros. -class ExitingStream { - public: - // A tag type that renders as ": " in an ExitingStream, but only if it is - // followed by additional output. Otherwise, it renders as "". Primarily used - // when building macros around these streams. - struct AddSeparator {}; +// Implements the check failure message printing. +// +// This is out-of-line and will arrange to stop the program, print any debugging +// information and this string. +// +// This API uses `const char*` C string arguments rather than `llvm::StringRef` +// because we know that these are available as C strings and passing them that +// way lets the code size of calling it be smaller: it only needs to materialize +// a single pointer argument for each. The runtime cost of re-computing the size +// should be minimal. The extra message however might not be compile-time +// guaranteed to be a C string so we use a normal `StringRef` there. +[[noreturn]] auto CheckFailImpl(const char* kind, const char* file, int line, + const char* condition_str, + llvm::StringRef extra_message) -> void; - // Internal type used in macros to dispatch to the `operator|` overload. - struct Helper {}; - - ExitingStream() - // Prefix the buffer with the current bug report message. - : buffer_(buffer_str_) {} - - // Never called. - [[noreturn]] ~ExitingStream(); - - // If the bool cast occurs, it's because the condition is false. This supports - // && short-circuiting the creation of ExitingStream. - explicit operator bool() const { return true; } - - // Forward output to llvm::errs. - template - auto operator<<(const T& message) -> ExitingStream& { - if (separator_) { - buffer_ << ": "; - separator_ = false; - } - buffer_ << message; - return *this; +// Prints a check failure, including rendering any user-provided message using +// a format string. +// +// Most of the parameters are passed as compile-time template strings to avoid +// runtime cost of parameter setup in optimized builds. Each of these are passed +// along to the underlying implementation to include in the final printed +// message. +// +// Any user-provided format string and values are directly passed to +// `llvm::formatv` which handles all of the formatting of output. +template +[[noreturn, gnu::cold, clang::noinline, clang::preserve_most]] auto CheckFail( + Ts&&... values) -> void { + if constexpr (llvm::StringRef(FormatStr).empty()) { + // Skip the format string rendering if empty. Note that we don't skip it + // even if there are no values as we want to have consistent handling of + // `{}`s in the format string. This case is about when there is no message + // at all, just the condition. + CheckFailImpl(Kind.c_str(), File.c_str(), Line, ConditionStr.c_str(), ""); + } else { + CheckFailImpl( + Kind.c_str(), File.c_str(), Line, ConditionStr.c_str(), + llvm::formatv(FormatStr.c_str(), std::forward(values)...).str()); } - - auto operator<<(AddSeparator /*add_separator*/) -> ExitingStream& { - separator_ = true; - return *this; - } - - // Low-precedence binary operator overload used in check.h macros to flush the - // output and exit the program. We do this in a binary operator rather than - // the destructor to ensure good debug info and backtraces for errors. - [[noreturn]] friend auto operator|(Helper /*helper*/, ExitingStream& stream) - -> void { - stream.Done(); - } - - private: - [[noreturn]] auto Done() -> void; - - // Whether a separator should be printed if << is used again. - bool separator_ = false; - - std::string buffer_str_; - llvm::raw_string_ostream buffer_; -}; +} } // namespace Carbon::Internal -// Raw exiting stream. This should be used when building forms of exiting -// macros. It evaluates to a temporary `ExitingStream` object that can be -// manipulated, streamed into, and then will exit the program. -#define CARBON_CHECK_INTERNAL_STREAM() \ - Carbon::Internal::ExitingStream::Helper() | Carbon::Internal::ExitingStream() +// Implements check messages without any formatted values. +// +// Passes each of the provided components of the message to the template +// parameters of the check failure printing function above, including an empty +// string for the format string. Because there are multiple template arguments, +// the entire call is wrapped in parentheses. +#define CARBON_INTERNAL_CHECK_IMPL(kind, file, line, condition_str) \ + (Carbon::Internal::CheckFail()) + +// Implements check messages with a format string and potentially formatted +// values. +// +// Each of the main components is passed as a template arguments, and then any +// formatted values are passed as arguments. Because there are multiple template +// arguments, the entire call is wrapped in parentheses. +#define CARBON_INTERNAL_CHECK_IMPL_FORMAT(kind, file, line, condition_str, \ + format_str, ...) \ + (Carbon::Internal::CheckFail( \ + __VA_ARGS__)) + +// Implements the failure of a check. +// +// Collects all the metadata about the failure to be printed, such as source +// location and stringified condition, and passes those, any format string and +// formatted arguments to the correct implementation macro above. +#define CARBON_INTERNAL_CHECK(condition, ...) \ + CARBON_INTERNAL_CHECK_IMPL##__VA_OPT__(_FORMAT)( \ + "CHECK", __FILE__, __LINE__, #condition __VA_OPT__(, ) __VA_ARGS__) + +// Implements the fatal macro. +// +// Similar to the check failure macro, but tags the message as a fatal one and +// leaves the stringified condition empty. +#define CARBON_INTERNAL_FATAL(...) \ + CARBON_INTERNAL_CHECK_IMPL##__VA_OPT__(_FORMAT)( \ + "FATAL", __FILE__, __LINE__, "" __VA_OPT__(, ) __VA_ARGS__) + +#ifdef NDEBUG +// For `DCHECK` in optimized builds we have a dead check that we want to +// potentially "use" arguments, but otherwise have the minimal overhead. We +// avoid forming interesting format strings here so that we don't have to +// repeatedly instantiate the `Check` function above. This format string would +// be an error if actually used. +#define CARBON_INTERNAL_DEAD_DCHECK(condition, ...) \ + CARBON_INTERNAL_DEAD_DCHECK_IMPL##__VA_OPT__(_FORMAT)(__VA_ARGS__) + +#define CARBON_INTERNAL_DEAD_DCHECK_IMPL() \ + Carbon::Internal::CheckFail<"", "", 0, "", "">() + +#define CARBON_INTERNAL_DEAD_DCHECK_IMPL_FORMAT(format_str, ...) \ + Carbon::Internal::CheckFail<"", "", 0, "", "">(__VA_ARGS__) +#endif #endif // CARBON_COMMON_CHECK_INTERNAL_H_ diff --git a/common/check_test.cpp b/common/check_test.cpp index 96660bcaf32d..24963bd6f6e1 100644 --- a/common/check_test.cpp +++ b/common/check_test.cpp @@ -26,32 +26,41 @@ TEST(CheckTest, CheckTrueCallbackNotUsed) { called = true; return "called"; }; - CARBON_CHECK(true) << callback(); + CARBON_CHECK(true, "{0}", callback()); EXPECT_FALSE(called); } TEST(CheckTest, CheckFalseMessage) { - ASSERT_DEATH({ CARBON_CHECK(false) << "msg"; }, + ASSERT_DEATH({ CARBON_CHECK(false, "msg"); }, "\nCHECK failure at common/check_test.cpp:.+: false: msg\n"); } +TEST(CheckTest, CheckFalseFormattedMessage) { + const char msg[] = "msg"; + std::string str = "str"; + int i = 1; + ASSERT_DEATH( + { CARBON_CHECK(false, "{0} {1} {2} {3}", msg, str, i, 0); }, + "\nCHECK failure at common/check_test.cpp:.+: false: msg str 1 0\n"); +} + TEST(CheckTest, CheckOutputForms) { const char msg[] = "msg"; std::string str = "str"; int i = 1; - CARBON_CHECK(true) << msg << str << i << 0; + CARBON_CHECK(true, "{0} {1} {2} {3}", msg, str, i, 0); } TEST(CheckTest, Fatal) { - ASSERT_DEATH({ CARBON_FATAL() << "msg"; }, + ASSERT_DEATH({ CARBON_FATAL("msg"); }, "\nFATAL failure at common/check_test.cpp:.+: msg\n"); } TEST(CheckTest, FatalHasStackDump) { - ASSERT_DEATH({ CARBON_FATAL() << "msg"; }, "\nStack dump:\n"); + ASSERT_DEATH({ CARBON_FATAL("msg"); }, "\nStack dump:\n"); } -auto FatalNoReturnRequired() -> int { CARBON_FATAL() << "msg"; } +auto FatalNoReturnRequired() -> int { CARBON_FATAL("msg"); } TEST(ErrorTest, FatalNoReturnRequired) { ASSERT_DEATH({ FatalNoReturnRequired(); }, diff --git a/common/command_line.cpp b/common/command_line.cpp index 8f1b60b9510c..bc95c8e73faf 100644 --- a/common/command_line.cpp +++ b/common/command_line.cpp @@ -22,7 +22,7 @@ auto operator<<(llvm::raw_ostream& output, ParseResult result) case ParseResult::Success: return output << "Success"; } - CARBON_FATAL() << "Corrupt parse result!"; + CARBON_FATAL("Corrupt parse result!"); } auto operator<<(llvm::raw_ostream& output, ArgKind kind) -> llvm::raw_ostream& { @@ -40,7 +40,7 @@ auto operator<<(llvm::raw_ostream& output, ArgKind kind) -> llvm::raw_ostream& { case ArgKind::Invalid: return output << "Invalid"; } - CARBON_FATAL() << "Corrupt argument kind!"; + CARBON_FATAL("Corrupt argument kind!"); } auto operator<<(llvm::raw_ostream& output, CommandKind kind) @@ -55,7 +55,7 @@ auto operator<<(llvm::raw_ostream& output, CommandKind kind) case CommandKind::MetaAction: return output << "MetaAction"; } - CARBON_FATAL() << "Corrupt command kind!"; + CARBON_FATAL("Corrupt command kind!"); } Arg::Arg(const ArgInfo& info) : info(info) {} @@ -315,8 +315,9 @@ void MetaPrinter::PrintHelpForSubcommandName( } void MetaPrinter::PrintVersion(const Command& command) const { - CARBON_CHECK(!command.info.version.empty()) - << "Printing should not be enabled without a version string configured."; + CARBON_CHECK( + !command.info.version.empty(), + "Printing should not be enabled without a version string configured."); PrintRawVersion(command, /*indent=*/""); if (!command.info.build_info.empty()) { out_ << "\n"; @@ -463,13 +464,14 @@ void MetaPrinter::PrintOptionUsage(const Arg& option) const { } void MetaPrinter::PrintOptionShortName(const Arg& arg) const { - CARBON_CHECK(!arg.info.short_name.empty()) << "No short name to use."; + CARBON_CHECK(!arg.info.short_name.empty(), "No short name to use."); out_ << "-" << arg.info.short_name; } void MetaPrinter::PrintArgShortValues(const Arg& arg) const { - CARBON_CHECK(arg.kind == Arg::Kind::OneOf) - << "Only one-of arguments have interesting value snippets to print."; + CARBON_CHECK( + arg.kind == Arg::Kind::OneOf, + "Only one-of arguments have interesting value snippets to print."); llvm::ListSeparator sep; for (llvm::StringRef value_string : arg.value_strings) { out_ << sep << value_string; @@ -517,7 +519,7 @@ void MetaPrinter::PrintArgHelp(const Arg& arg, llvm::StringRef indent) const { // No value help. break; case Arg::Kind::Invalid: - CARBON_FATAL() << "Argument configured without any action or kind!"; + CARBON_FATAL("Argument configured without any action or kind!"); } } @@ -793,11 +795,11 @@ void Parser::PopulateMaps(const Command& command) { if (option->info.short_name.empty()) { continue; } - CARBON_CHECK(option->info.short_name.size() == 1) - << "Short option names must have exactly one character."; + CARBON_CHECK(option->info.short_name.size() == 1, + "Short option names must have exactly one character."); unsigned char short_char = option->info.short_name[0]; - CARBON_CHECK(short_char < short_option_table_.size()) - << "Short option name outside of the expected range."; + CARBON_CHECK(short_char < short_option_table_.size(), + "Short option name outside of the expected range."); short_option_table_[short_char] = &map_entry.second; } subcommand_map_.clear(); @@ -807,7 +809,7 @@ void Parser::PopulateMaps(const Command& command) { } void Parser::SetOptionDefault(const Arg& option) { - CARBON_CHECK(option.has_default) << "No default value available!"; + CARBON_CHECK(option.has_default, "No default value available!"); switch (option.kind) { case Arg::Kind::Flag: *option.flag_storage = option.default_flag; @@ -822,9 +824,9 @@ void Parser::SetOptionDefault(const Arg& option) { option.default_action(option); break; case Arg::Kind::MetaActionOnly: - CARBON_FATAL() << "Can't set a default value for a meta action!"; + CARBON_FATAL("Can't set a default value for a meta action!"); case Arg::Kind::Invalid: - CARBON_FATAL() << "Option configured without any action or kind!"; + CARBON_FATAL("Option configured without any action or kind!"); } } @@ -846,7 +848,7 @@ auto Parser::ParseNegatedFlag(const Arg& flag, auto Parser::ParseFlag(const Arg& flag, std::optional value) -> bool { - CARBON_CHECK(flag.kind == Arg::Kind::Flag) << "Incorrect kind: " << flag.kind; + CARBON_CHECK(flag.kind == Arg::Kind::Flag, "Incorrect kind: {0}", flag.kind); if (!value || *value == "true") { *flag.flag_storage = true; } else if (*value == "false") { @@ -862,8 +864,7 @@ auto Parser::ParseFlag(const Arg& flag, std::optional value) auto Parser::ParseIntegerArgValue(const Arg& arg, llvm::StringRef value) -> bool { - CARBON_CHECK(arg.kind == Arg::Kind::Integer) - << "Incorrect kind: " << arg.kind; + CARBON_CHECK(arg.kind == Arg::Kind::Integer, "Incorrect kind: {0}", arg.kind); int integer_value; // Note that this method returns *true* on error! if (value.getAsInteger(/*Radix=*/0, integer_value)) { @@ -881,7 +882,7 @@ auto Parser::ParseIntegerArgValue(const Arg& arg, llvm::StringRef value) auto Parser::ParseStringArgValue(const Arg& arg, llvm::StringRef value) -> bool { - CARBON_CHECK(arg.kind == Arg::Kind::String) << "Incorrect kind: " << arg.kind; + CARBON_CHECK(arg.kind == Arg::Kind::String, "Incorrect kind: {0}", arg.kind); if (!arg.is_append) { *arg.string_storage = value; } else { @@ -891,7 +892,7 @@ auto Parser::ParseStringArgValue(const Arg& arg, llvm::StringRef value) } auto Parser::ParseOneOfArgValue(const Arg& arg, llvm::StringRef value) -> bool { - CARBON_CHECK(arg.kind == Arg::Kind::OneOf) << "Incorrect kind: " << arg.kind; + CARBON_CHECK(arg.kind == Arg::Kind::OneOf, "Incorrect kind: {0}", arg.kind); if (!arg.value_action(arg, value)) { errors_ << "ERROR: Option '--" << arg.info.name << "="; llvm::printEscapedString(value, errors_); @@ -967,7 +968,7 @@ auto Parser::ParseArg(const Arg& arg, bool short_spelling, return false; case Arg::Kind::Flag: case Arg::Kind::Invalid: - CARBON_FATAL() << "Invalid kind!"; + CARBON_FATAL("Invalid kind!"); } } @@ -984,8 +985,8 @@ auto Parser::SplitValue(llvm::StringRef& unparsed_arg) } auto Parser::ParseLongOption(llvm::StringRef unparsed_arg) -> bool { - CARBON_CHECK(unparsed_arg.starts_with("--") && unparsed_arg.size() > 2) - << "Must only be called on a potential long option."; + CARBON_CHECK(unparsed_arg.starts_with("--") && unparsed_arg.size() > 2, + "Must only be called on a potential long option."); // Walk past the double dash. unparsed_arg = unparsed_arg.drop_front(2); @@ -1009,8 +1010,8 @@ auto Parser::ParseLongOption(llvm::StringRef unparsed_arg) -> bool { } auto Parser::ParseShortOptionSeq(llvm::StringRef unparsed_arg) -> bool { - CARBON_CHECK(unparsed_arg.starts_with("-") && unparsed_arg.size() > 1) - << "Must only be called on a potential short option sequence."; + CARBON_CHECK(unparsed_arg.starts_with("-") && unparsed_arg.size() > 1, + "Must only be called on a potential short option sequence."); unparsed_arg = unparsed_arg.drop_front(); std::optional value = SplitValue(unparsed_arg); @@ -1143,10 +1144,10 @@ auto Parser::FinalizeParse() -> ParseResult { // If we were appending to a positional argument, mark that as complete. llvm::ArrayRef positional_args = command_->positional_args; if (appending_to_positional_arg_) { - CARBON_CHECK(static_cast(positional_arg_index_) < - positional_args.size()) - << "Appending to a positional argument with an invalid index: " - << positional_arg_index_; + CARBON_CHECK( + static_cast(positional_arg_index_) < positional_args.size(), + "Appending to a positional argument with an invalid index: {0}", + positional_arg_index_); ++positional_arg_index_; } @@ -1162,15 +1163,15 @@ auto Parser::FinalizeParse() -> ParseResult { return ParseResult::Error; } for (const auto& arg_ptr : unparsed_positional_args) { - CARBON_CHECK(!arg_ptr->is_required) - << "Cannot have required positional parameters after an optional " - "one."; + CARBON_CHECK( + !arg_ptr->is_required, + "Cannot have required positional parameters after an optional one."); } } switch (command_->kind) { case Command::Kind::Invalid: - CARBON_FATAL() << "Should never have a parser with an invalid command!"; + CARBON_FATAL("Should never have a parser with an invalid command!"); case Command::Kind::RequiresSubcommand: errors_ << "ERROR: No subcommand specified. Available subcommands: "; error_meta_printer_.PrintSubcommands(*command_); @@ -1189,11 +1190,13 @@ auto Parser::FinalizeParse() -> ParseResult { auto Parser::ParsePositionalSuffix( llvm::ArrayRef unparsed_args) -> bool { - CARBON_CHECK(!command_->positional_args.empty()) - << "Cannot do positional suffix parsing without positional arguments!"; - CARBON_CHECK(!unparsed_args.empty() && unparsed_args.front() == "--") - << "Must be called with a suffix of arguments starting with a `--` that " - "switches to positional suffix parsing."; + CARBON_CHECK( + !command_->positional_args.empty(), + "Cannot do positional suffix parsing without positional arguments!"); + CARBON_CHECK( + !unparsed_args.empty() && unparsed_args.front() == "--", + "Must be called with a suffix of arguments starting with a `--` that " + "switches to positional suffix parsing."); // Once we're in the positional suffix, we can track empty positional // arguments. bool empty_positional = false; @@ -1291,9 +1294,9 @@ auto Parser::Parse(llvm::ArrayRef unparsed_args) continue; } - CARBON_CHECK(command_->positional_args.empty() || - command_->subcommands.empty()) - << "Cannot have both positional arguments and subcommands!"; + CARBON_CHECK( + command_->positional_args.empty() || command_->subcommands.empty(), + "Cannot have both positional arguments and subcommands!"); if (command_->positional_args.empty() && command_->subcommands.empty()) { errors_ << "ERROR: Found unexpected positional argument or subcommand: '" << unparsed_arg << "'\n"; @@ -1439,12 +1442,13 @@ void CommandBuilder::AddOneOfPositionalArg( void CommandBuilder::AddSubcommand( const CommandInfo& info, llvm::function_ref build) { - CARBON_CHECK(IsValidName(info.name)) - << "Invalid subcommand name: " << info.name; - CARBON_CHECK(subcommand_names_.insert(info.name).second) - << "Added a duplicate subcommand: " << info.name; - CARBON_CHECK(command_.positional_args.empty()) - << "Cannot add subcommands to a command with a positional argument."; + CARBON_CHECK(IsValidName(info.name), "Invalid subcommand name: {0}", + info.name); + CARBON_CHECK(subcommand_names_.insert(info.name).second, + "Added a duplicate subcommand: {0}", info.name); + CARBON_CHECK( + command_.positional_args.empty(), + "Cannot add subcommands to a command with a positional argument."); command_.subcommands.emplace_back(new Command(info, &command_)); CommandBuilder builder(*command_.subcommands.back(), meta_printer_); @@ -1457,25 +1461,28 @@ void CommandBuilder::HelpHidden(bool is_help_hidden) { } void CommandBuilder::RequiresSubcommand() { - CARBON_CHECK(!command_.subcommands.empty()) - << "Cannot require subcommands unless there are subcommands."; - CARBON_CHECK(command_.positional_args.empty()) - << "Cannot require subcommands and have a positional argument."; - CARBON_CHECK(command_.kind == Kind::Invalid) - << "Already established the kind of this command as: " << command_.kind; + CARBON_CHECK(!command_.subcommands.empty(), + "Cannot require subcommands unless there are subcommands."); + CARBON_CHECK(command_.positional_args.empty(), + "Cannot require subcommands and have a positional argument."); + CARBON_CHECK(command_.kind == Kind::Invalid, + "Already established the kind of this command as: {0}", + command_.kind); command_.kind = Kind::RequiresSubcommand; } void CommandBuilder::Do(ActionT action) { - CARBON_CHECK(command_.kind == Kind::Invalid) - << "Already established the kind of this command as: " << command_.kind; + CARBON_CHECK(command_.kind == Kind::Invalid, + "Already established the kind of this command as: {0}", + command_.kind); command_.kind = Kind::Action; command_.action = std::move(action); } void CommandBuilder::Meta(ActionT action) { - CARBON_CHECK(command_.kind == Kind::Invalid) - << "Already established the kind of this command as: " << command_.kind; + CARBON_CHECK(command_.kind == Kind::Invalid, + "Already established the kind of this command as: {0}", + command_.kind); command_.kind = Kind::MetaAction; command_.action = std::move(action); } @@ -1484,10 +1491,9 @@ CommandBuilder::CommandBuilder(Command& command, MetaPrinter& meta_printer) : command_(command), meta_printer_(meta_printer) {} auto CommandBuilder::AddArgImpl(const ArgInfo& info, Arg::Kind kind) -> Arg& { - CARBON_CHECK(IsValidName(info.name)) - << "Invalid argument name: " << info.name; - CARBON_CHECK(arg_names_.insert(info.name).second) - << "Added a duplicate argument name: " << info.name; + CARBON_CHECK(IsValidName(info.name), "Invalid argument name: {0}", info.name); + CARBON_CHECK(arg_names_.insert(info.name).second, + "Added a duplicate argument name: {0}", info.name); command_.options.emplace_back(new Arg(info)); Arg& arg = *command_.options.back(); @@ -1497,23 +1503,23 @@ auto CommandBuilder::AddArgImpl(const ArgInfo& info, Arg::Kind kind) -> Arg& { void CommandBuilder::AddPositionalArgImpl( const ArgInfo& info, Arg::Kind kind, llvm::function_ref build) { - CARBON_CHECK(IsValidName(info.name)) - << "Invalid argument name: " << info.name; - CARBON_CHECK(command_.subcommands.empty()) - << "Cannot add a positional argument to a command with subcommands."; + CARBON_CHECK(IsValidName(info.name), "Invalid argument name: {0}", info.name); + CARBON_CHECK( + command_.subcommands.empty(), + "Cannot add a positional argument to a command with subcommands."); command_.positional_args.emplace_back(new Arg(info)); Arg& arg = *command_.positional_args.back(); arg.kind = kind; build(arg); - CARBON_CHECK(!arg.is_help_hidden) - << "Cannot have a help-hidden positional argument."; + CARBON_CHECK(!arg.is_help_hidden, + "Cannot have a help-hidden positional argument."); if (arg.is_required && command_.positional_args.size() > 1) { - CARBON_CHECK((*std::prev(command_.positional_args.end(), 2))->is_required) - << "A required positional argument cannot be added after an optional " - "one."; + CARBON_CHECK((*std::prev(command_.positional_args.end(), 2))->is_required, + "A required positional argument cannot be added after an " + "optional one."); } } diff --git a/common/command_line.h b/common/command_line.h index c8a8a98598f9..3b0498e023df 100644 --- a/common/command_line.h +++ b/common/command_line.h @@ -735,7 +735,7 @@ struct Command { template void ArgBuilder::MetaAction(T action) { - CARBON_CHECK(!arg_.meta_action) << "Cannot set a meta action twice!"; + CARBON_CHECK(!arg_.meta_action, "Cannot set a meta action twice!"); arg_.meta_action = std::move(action); } @@ -814,9 +814,9 @@ void OneOfArgBuilder::OneOfImpl(const OneOfValueT (&input_values)[N], // Fold over all the input values to see if there is a default. if ((input_values[Indices].is_default || ...)) { - CARBON_CHECK(!arg_.is_append) << "Can't append default."; - CARBON_CHECK((input_values[Indices].is_default + ... + 0) == 1) - << "Cannot default more than one value."; + CARBON_CHECK(!arg_.is_append, "Can't append default."); + CARBON_CHECK((input_values[Indices].is_default + ... + 0) == 1, + "Cannot default more than one value."); arg_.has_default = true; diff --git a/common/error.h b/common/error.h index 9364afae75a8..ffe8557032f7 100644 --- a/common/error.h +++ b/common/error.h @@ -27,7 +27,7 @@ class [[nodiscard]] Error : public Printable { // Represents an error state. explicit Error(llvm::Twine location, llvm::Twine message) : location_(location.str()), message_(message.str()) { - CARBON_CHECK(!message_.empty()) << "Errors must have a message."; + CARBON_CHECK(!message_.empty(), "Errors must have a message."); } // Represents an error with no associated location. diff --git a/common/hashing_test.cpp b/common/hashing_test.cpp index 98d18d52172f..c332db8ccac3 100644 --- a/common/hashing_test.cpp +++ b/common/hashing_test.cpp @@ -653,7 +653,7 @@ auto FindBitRangeCollisions(llvm::ArrayRef> hashes) auto CheckNoDuplicateValues(llvm::ArrayRef hashes) -> void { for (int i = 0, size = hashes.size(); i < size - 1; ++i) { const auto& [_, value] = hashes[i]; - CARBON_CHECK(value != hashes[i + 1].v) << "Duplicate value: " << value; + CARBON_CHECK(value != hashes[i + 1].v, "Duplicate value: {0}", value); } } diff --git a/common/map.h b/common/map.h index 9cc92561282f..33c261073cec 100644 --- a/common/map.h +++ b/common/map.h @@ -472,7 +472,7 @@ MapBase::Insert( std::invocable) { auto [entry, inserted] = this->InsertImpl(lookup_key, key_context); - CARBON_DCHECK(entry) << "Should always result in a valid index."; + CARBON_DCHECK(entry, "Should always result in a valid index."); if (LLVM_LIKELY(!inserted)) { return InsertKVResult(false, *entry); @@ -538,7 +538,7 @@ MapBase::Update( std::invocable) { auto [entry, inserted] = this->InsertImpl(lookup_key, key_context); - CARBON_DCHECK(entry) << "Should always result in a valid index."; + CARBON_DCHECK(entry, "Should always result in a valid index."); if (LLVM_LIKELY(!inserted)) { update_cb(entry->key(), entry->value()); diff --git a/common/map_benchmark.cpp b/common/map_benchmark.cpp index e4224f98d08b..9b7c311bd680 100644 --- a/common/map_benchmark.cpp +++ b/common/map_benchmark.cpp @@ -460,12 +460,12 @@ static void BM_MapInsertSeq(benchmark::State& state) { MapWrapperT m; for (auto k : keys) { bool inserted = m.BenchInsert(k, MakeValue()); - CARBON_DCHECK(inserted) << "Must be a successful insert!"; + CARBON_DCHECK(inserted, "Must be a successful insert!"); } // Now insert a final random repeated key. bool inserted = m.BenchInsert(lookup_keys[i], MakeValue2()); - CARBON_DCHECK(!inserted) << "Must already be in the map!"; + CARBON_DCHECK(!inserted, "Must already be in the map!"); // Rotate through the shuffled keys. i = (i + static_cast(!inserted)) & (LookupKeysSize - 1); @@ -484,7 +484,7 @@ static void BM_MapInsertSeq(benchmark::State& state) { MapWrapperT m; for (auto k : keys) { bool inserted = m.BenchInsert(k, MakeValue()); - CARBON_DCHECK(inserted) << "Must be a successful insert!"; + CARBON_DCHECK(inserted, "Must be a successful insert!"); } ReportMetrics(m, state); diff --git a/common/raw_hashtable.h b/common/raw_hashtable.h index ff5fdace03c1..8a413ce2d8eb 100644 --- a/common/raw_hashtable.h +++ b/common/raw_hashtable.h @@ -381,8 +381,8 @@ class ViewImpl { // given size. This is trivial, but we use this routine to enforce invariants // on the sizes. static constexpr auto EntriesOffset(ssize_t alloc_size) -> ssize_t { - CARBON_DCHECK(llvm::isPowerOf2_64(alloc_size)) - << "Size must be a power of two for a hashed buffer!"; + CARBON_DCHECK(llvm::isPowerOf2_64(alloc_size), + "Size must be a power of two for a hashed buffer!"); // The size is always a power of two. We prevent any too-small sizes so it // being a power of two provides the needed alignment. As a result, the // offset is exactly the size. We validate this here to catch alignment bugs @@ -615,8 +615,8 @@ inline auto ComputeSeed() -> uint64_t { } inline auto ComputeProbeMaskFromSize(ssize_t size) -> size_t { - CARBON_DCHECK(llvm::isPowerOf2_64(size)) - << "Size must be a power of two for a hashed buffer!"; + CARBON_DCHECK(llvm::isPowerOf2_64(size), + "Size must be a power of two for a hashed buffer!"); // Since `size` is a power of two, we can make sure the probes are less // than `size` by making the mask `size - 1`. We also mask off the low // bits so the probes are a multiple of the size of the groups of entries. @@ -659,12 +659,14 @@ class ProbeSequence { // everything down by `GroupSize`. CARBON_DCHECK( (p_ / GroupSize) == - ((start_ / GroupSize + - (step_ / GroupSize + (step_ / GroupSize) * (step_ / GroupSize)) / 2) % - (size_ / GroupSize))) - << "Index in probe sequence does not match the expected formula."; - CARBON_DCHECK(step_ < size_) << "We necessarily visit all groups, so we " - "can't have more probe steps than groups."; + ((start_ / GroupSize + + (step_ / GroupSize + (step_ / GroupSize) * (step_ / GroupSize)) / + 2) % + (size_ / GroupSize)), + "Index in probe sequence does not match the expected formula."); + CARBON_DCHECK(step_ < size_, + "We necessarily visit all groups, so we can't have more " + "probe steps than groups."); #endif } @@ -924,13 +926,14 @@ auto BaseImpl::InsertImpl( } --growth_budget_; - CARBON_DCHECK(growth_budget() >= 0) - << "Growth budget shouldn't have gone negative!"; + CARBON_DCHECK(growth_budget() >= 0, + "Growth budget shouldn't have gone negative!"); return return_insert_at_index(group_index + empty_match.index()); } - CARBON_FATAL() << "We should never finish probing without finding the entry " - "or an empty slot."; + CARBON_FATAL( + "We should never finish probing without finding the entry or an empty " + "slot."); } template @@ -1264,11 +1267,11 @@ BaseImpl::InsertIntoEmpty( template auto BaseImpl::ComputeNextAllocSize( ssize_t old_alloc_size) -> ssize_t { - CARBON_DCHECK(llvm::isPowerOf2_64(old_alloc_size)) - << "Expected a power of two!"; + CARBON_DCHECK(llvm::isPowerOf2_64(old_alloc_size), + "Expected a power of two!"); ssize_t new_alloc_size; bool overflow = __builtin_mul_overflow(old_alloc_size, 2, &new_alloc_size); - CARBON_CHECK(!overflow) << "Computing the new size overflowed `ssize_t`!"; + CARBON_CHECK(!overflow, "Computing the new size overflowed `ssize_t`!"); return new_alloc_size; } @@ -1340,11 +1343,10 @@ auto BaseImpl::GrowToNextAllocSize( llvm::count(llvm::ArrayRef(old_metadata, old_size), MetadataGroup::Empty); ssize_t debug_deleted_count = llvm::count( llvm::ArrayRef(old_metadata, old_size), MetadataGroup::Deleted); - CARBON_DCHECK(debug_empty_count >= - (old_size - GrowthThresholdForAllocSize(old_size))) - << "debug_empty_count: " << debug_empty_count - << ", debug_deleted_count: " << debug_deleted_count - << ", size: " << old_size; + CARBON_DCHECK( + debug_empty_count >= (old_size - GrowthThresholdForAllocSize(old_size)), + "debug_empty_count: {0}, debug_deleted_count: {1}, size: {2}", + debug_empty_count, debug_deleted_count, old_size); #endif // Configure for the new size and allocate the new storage. diff --git a/common/raw_hashtable_benchmark_helpers.cpp b/common/raw_hashtable_benchmark_helpers.cpp index ccb82d2919b4..1199748b35fb 100644 --- a/common/raw_hashtable_benchmark_helpers.cpp +++ b/common/raw_hashtable_benchmark_helpers.cpp @@ -43,8 +43,9 @@ static auto MakeChars() -> llvm::OwningArrayRef { ++i; } } - CARBON_CHECK(i == NumChars) << "Expected exactly " << NumChars - << " characters, got " << i << " instead!"; + CARBON_CHECK(i == NumChars, + "Expected exactly {0} characters, got {1} instead!", NumChars, + i); return characters; } @@ -344,7 +345,7 @@ auto DumpHashStatistics(llvm::ArrayRef keys) -> void { GroupShift); for (auto [i, k] : llvm::enumerate(keys)) { ssize_t hash_index = get_hash_index(k); - CARBON_CHECK(hash_index < (expected_size >> GroupShift)) << hash_index; + CARBON_CHECK(hash_index < (expected_size >> GroupShift), "{0}", hash_index); grouped_key_indices[hash_index].push_back(i); } ssize_t max_group_index = diff --git a/common/raw_hashtable_metadata_group.h b/common/raw_hashtable_metadata_group.h index 497db6009388..5cc03cd4e585 100644 --- a/common/raw_hashtable_metadata_group.h +++ b/common/raw_hashtable_metadata_group.h @@ -10,6 +10,7 @@ #include #include "common/check.h" +#include "common/ostream.h" #include "llvm/ADT/Sequence.h" #include "llvm/ADT/bit.h" #include "llvm/Support/FormatVariadic.h" @@ -80,14 +81,14 @@ class BitIndex // Returns true when there are no matches for the tag. auto empty() const -> bool { - CARBON_DCHECK((bits_ & ZeroMask) == 0) << "Unexpected non-zero bits!"; + CARBON_DCHECK((bits_ & ZeroMask) == 0, "Unexpected non-zero bits!"); __builtin_assume((bits_ & ZeroMask) == 0); return bits_ == 0; } // Returns the index of the first matched tag. auto index() -> ssize_t { - CARBON_DCHECK(bits_ != 0) << "Cannot get an index from zero bits!"; + CARBON_DCHECK(bits_ != 0, "Cannot get an index from zero bits!"); __builtin_assume(bits_ != 0); ssize_t index = unscaled_index(); @@ -102,7 +103,7 @@ class BitIndex // Optimized tool to index a pointer `p` by `index()`. template auto index_ptr(T* pointer) -> T* { - CARBON_DCHECK(bits_ != 0) << "Cannot get an index from zero bits!"; + CARBON_DCHECK(bits_ != 0, "Cannot get an index from zero bits!"); __builtin_assume(bits_ != 0); if constexpr (!ByteEncoding) { return &pointer[unscaled_index()]; @@ -191,7 +192,7 @@ class BitIndexRange : public Printable> { } auto operator*() -> ssize_t& { - CARBON_DCHECK(bits_ != 0) << "Cannot get an index from zero bits!"; + CARBON_DCHECK(bits_ != 0, "Cannot get an index from zero bits!"); __builtin_assume(bits_ != 0); index_ = BitIndexT(bits_).index(); // Note that we store the index in a member so we can return a reference @@ -205,7 +206,7 @@ class BitIndexRange : public Printable> { } auto operator++() -> Iterator& { - CARBON_DCHECK(bits_ != 0) << "Must not increment past the end!"; + CARBON_DCHECK(bits_ != 0, "Must not increment past the end!"); __builtin_assume(bits_ != 0); // Clears the least significant set bit, effectively stepping to the next // match. @@ -270,7 +271,7 @@ class BitIndexRange : public Printable> { // } // if (UseSIMD || DebugSIMD) { // simd_result = SIMDOperation(...) -// CARBON_DCHECK(result == portable_result) << ...; +// CARBON_DCHECK(result == portable_result, "{0}", ...); // } // return UseSIMD ? simd_result : portable_result; // } @@ -533,9 +534,8 @@ inline auto MetadataGroup::Store(uint8_t* metadata, ssize_t index) const } inline auto MetadataGroup::ClearByte(ssize_t byte_index) -> void { - CARBON_DCHECK(FastByteClear) << "Only use byte clearing when fast!"; - CARBON_DCHECK(Size == 8) - << "The clear implementation assumes an 8-byte group."; + CARBON_DCHECK(FastByteClear, "Only use byte clearing when fast!"); + CARBON_DCHECK(Size == 8, "The clear implementation assumes an 8-byte group."); metadata_ints[0] &= ~(static_cast(0xff) << (byte_index * 8)); } @@ -548,9 +548,10 @@ inline auto MetadataGroup::ClearDeleted() -> void { } if constexpr (UseSIMD || DebugSIMD) { simd_g.SIMDClearDeleted(); - CARBON_DCHECK(simd_g == portable_g) - << "SIMD cleared group '" << simd_g - << "' doesn't match portable cleared group '" << portable_g << "'"; + CARBON_DCHECK( + simd_g == portable_g, + "SIMD cleared group '{0}' doesn't match portable cleared group '{1}'", + simd_g, portable_g); } *this = UseSIMD ? simd_g : portable_g; } @@ -559,7 +560,7 @@ inline auto MetadataGroup::Match(uint8_t tag) const -> MatchRange { // The caller should provide us with the present byte hash, and not set any // present bit tag on it so that this layer can manage tagging the high bit of // a present byte. - CARBON_DCHECK((tag & PresentMask) == 0) << llvm::formatv("{0:x}", tag); + CARBON_DCHECK((tag & PresentMask) == 0, "{0:x}", tag); MatchRange portable_result; MatchRange simd_result; @@ -568,9 +569,9 @@ inline auto MetadataGroup::Match(uint8_t tag) const -> MatchRange { } if constexpr (UseSIMD || DebugSIMD) { simd_result = SIMDMatch(tag); - CARBON_DCHECK(simd_result == portable_result) - << "SIMD result '" << simd_result << "' doesn't match portable result '" - << portable_result << "'"; + CARBON_DCHECK(simd_result == portable_result, + "SIMD result '{0}' doesn't match portable result '{1}'", + simd_result, portable_result); } return UseSIMD ? simd_result : portable_result; } @@ -583,9 +584,9 @@ inline auto MetadataGroup::MatchPresent() const -> MatchRange { } if constexpr (UseSIMD || DebugSIMD) { simd_result = SIMDMatchPresent(); - CARBON_DCHECK(simd_result == portable_result) - << "SIMD result '" << simd_result << "' doesn't match portable result '" - << portable_result << "'"; + CARBON_DCHECK(simd_result == portable_result, + "SIMD result '{0}' doesn't match portable result '{1}'", + simd_result, portable_result); } return UseSIMD ? simd_result : portable_result; } @@ -598,9 +599,9 @@ inline auto MetadataGroup::MatchEmpty() const -> MatchIndex { } if constexpr (UseSIMD || DebugSIMD) { simd_result = SIMDMatchEmpty(); - CARBON_DCHECK(simd_result == portable_result) - << "SIMD result '" << simd_result << "' doesn't match portable result '" - << portable_result << "'"; + CARBON_DCHECK(simd_result == portable_result, + "SIMD result '{0}' doesn't match portable result '{1}'", + simd_result, portable_result); } return UseSIMD ? simd_result : portable_result; } @@ -613,9 +614,9 @@ inline auto MetadataGroup::MatchDeleted() const -> MatchIndex { } if constexpr (UseSIMD || DebugSIMD) { simd_result = SIMDMatchDeleted(); - CARBON_DCHECK(simd_result == portable_result) - << "SIMD result '" << simd_result << "' doesn't match portable result '" - << portable_result << "'"; + CARBON_DCHECK(simd_result == portable_result, + "SIMD result '{0}' doesn't match portable result '{1}'", + simd_result, portable_result); } return UseSIMD ? simd_result : portable_result; } @@ -640,29 +641,31 @@ inline auto MetadataGroup::VerifyIndexBits( for (ssize_t byte_index : llvm::seq(0, Size)) { if constexpr (!ByteEncoding) { if (byte_match(metadata_bytes[byte_index])) { - CARBON_CHECK(((index_bits >> byte_index) & 1) == 1) - << "Bit not set at matching byte index: " << byte_index; + CARBON_CHECK(((index_bits >> byte_index) & 1) == 1, + "Bit not set at matching byte index: {0}", byte_index); // Only the first match is needed, so stop scanning once found. break; } - CARBON_CHECK(((index_bits >> byte_index) & 1) == 0) - << "Bit set at non-matching byte index: " << byte_index; + CARBON_CHECK(((index_bits >> byte_index) & 1) == 0, + "Bit set at non-matching byte index: {0}", byte_index); } else { // `index_bits` is byte-encoded rather than bit encoded, so extract a // byte. uint8_t index_byte = (index_bits >> (byte_index * 8)) & 0xFF; if (byte_match(metadata_bytes[byte_index])) { - CARBON_CHECK((index_byte & 0x80) == 0x80) - << "Should have the high bit set for a matching byte, found: " - << llvm::formatv("{0:x}", index_byte); + CARBON_CHECK( + (index_byte & 0x80) == 0x80, + "Should have the high bit set for a matching byte, found: {0:x}", + index_byte); // Only the first match is needed so stop scanning once found. break; } - CARBON_CHECK(index_byte == 0) - << "Should have no bits set for an unmatched byte, found: " - << llvm::formatv("{0:x}", index_byte); + CARBON_CHECK( + index_byte == 0, + "Should have no bits set for an unmatched byte, found: {0:x}", + index_byte); } } return true; @@ -674,24 +677,26 @@ inline auto MetadataGroup::VerifyRangeBits( for (ssize_t byte_index : llvm::seq(0, Size)) { if constexpr (!ByteEncoding) { if (byte_match(metadata_bytes[byte_index])) { - CARBON_CHECK(((range_bits >> byte_index) & 1) == 1) - << "Bit not set at matching byte index: " << byte_index; + CARBON_CHECK(((range_bits >> byte_index) & 1) == 1, + "Bit not set at matching byte index: {0}", byte_index); } else { - CARBON_CHECK(((range_bits >> byte_index) & 1) == 0) - << "Bit set at non-matching byte index: " << byte_index; + CARBON_CHECK(((range_bits >> byte_index) & 1) == 0, + "Bit set at non-matching byte index: {0}", byte_index); } } else { // `range_bits` is byte-encoded rather than bit encoded, so extract a // byte. uint8_t range_byte = (range_bits >> (byte_index * 8)) & 0xFF; if (byte_match(metadata_bytes[byte_index])) { - CARBON_CHECK(range_byte == 0x80) - << "Should just have the high bit set for a matching byte, found: " - << llvm::formatv("{0:x}", range_byte); + CARBON_CHECK(range_byte == 0x80, + "Should just have the high bit set for a matching byte, " + "found: {0:x}", + range_byte); } else { - CARBON_CHECK(range_byte == 0) - << "Should have no bits set for an unmatched byte, found: " - << llvm::formatv("{0:x}", range_byte); + CARBON_CHECK( + range_byte == 0, + "Should have no bits set for an unmatched byte, found: {0:x}", + range_byte); } } } @@ -730,7 +735,7 @@ inline auto MetadataGroup::PortableMatch(uint8_t tag) const -> MatchRange { // The caller should provide us with the present byte hash, and not set any // present bit tag on it so that this layer can manage tagging the high bit of // a present byte. - CARBON_DCHECK((tag & PresentMask) == 0) << llvm::formatv("{0:x}", tag); + CARBON_DCHECK((tag & PresentMask) == 0, "{0:x}", tag); // Use a simple fallback approach for sizes beyond 8. // TODO: Instead of a simple fallback, we should generalize the below @@ -783,8 +788,8 @@ inline auto MetadataGroup::PortableMatch(uint8_t tag) const -> MatchRange { // know that the add cannot carry, and this way it can be lowered using // combined multiply-add instructions if available. uint64_t broadcast = LSBs * tag + MSBs; - CARBON_DCHECK(broadcast == (LSBs * tag | MSBs)) - << "Unexpected carry from addition!"; + CARBON_DCHECK(broadcast == (LSBs * tag | MSBs), + "Unexpected carry from addition!"); // Xor the broadcast byte pattern. This makes bytes with matches become 0, and // clears the high-bits of non-matches. Note that if we are looking for a tag diff --git a/common/set.h b/common/set.h index 6116dae8e376..b85027eafde1 100644 --- a/common/set.h +++ b/common/set.h @@ -372,7 +372,7 @@ auto SetBase::Insert(LookupKeyT lookup_key, requires std::invocable { auto [entry, inserted] = this->InsertImpl(lookup_key, key_context); - CARBON_DCHECK(entry) << "Should always result in a valid index."; + CARBON_DCHECK(entry, "Should always result in a valid index."); if (LLVM_LIKELY(!inserted)) { return InsertResult(false, entry->key()); diff --git a/common/set_benchmark.cpp b/common/set_benchmark.cpp index 2702cb62e853..e3b4a36e5af7 100644 --- a/common/set_benchmark.cpp +++ b/common/set_benchmark.cpp @@ -336,12 +336,12 @@ static void BM_SetInsertSeq(benchmark::State& state) { SetWrapperT s; for (auto k : keys) { bool inserted = s.BenchInsert(k); - CARBON_DCHECK(inserted) << "Must be a successful insert!"; + CARBON_DCHECK(inserted, "Must be a successful insert!"); } // Now insert a final random repeated key. bool inserted = s.BenchInsert(lookup_keys[i]); - CARBON_DCHECK(!inserted) << "Must already be in the map!"; + CARBON_DCHECK(!inserted, "Must already be in the map!"); // Rotate through the shuffled keys. i = (i + static_cast(!inserted)) & (LookupKeysSize - 1); @@ -360,7 +360,7 @@ static void BM_SetInsertSeq(benchmark::State& state) { SetT s; for (auto k : keys) { bool inserted = s.Insert(k).is_inserted(); - CARBON_DCHECK(inserted) << "Must be a successful insert!"; + CARBON_DCHECK(inserted, "Must be a successful insert!"); } ReportTableMetrics(s, state); diff --git a/explorer/ast/bindings.cpp b/explorer/ast/bindings.cpp index 827b7a3e1223..d1c1d3a8ee61 100644 --- a/explorer/ast/bindings.cpp +++ b/explorer/ast/bindings.cpp @@ -25,15 +25,15 @@ void Bindings::Add(Nonnull binding, Nonnull value, std::optional> witness) { bool added_value = args_.insert({binding, value}).second; - CARBON_CHECK(added_value) << "Add of already-existing binding"; + CARBON_CHECK(added_value, "Add of already-existing binding"); if (witness) { // TODO: Eventually we should check that we have a witness if and only if // the binding has an impl binding. auto impl_binding = binding->impl_binding(); - CARBON_CHECK(impl_binding) << "Given witness but have no impl binding"; + CARBON_CHECK(impl_binding, "Given witness but have no impl binding"); bool added_witness = witnesses_.insert({*impl_binding, *witness}).second; - CARBON_CHECK(added_witness) << "Add of already-existing binding"; + CARBON_CHECK(added_witness, "Add of already-existing binding"); } } diff --git a/explorer/ast/clone_context.cpp b/explorer/ast/clone_context.cpp index f5b2eed35ee7..e24794713ccc 100644 --- a/explorer/ast/clone_context.cpp +++ b/explorer/ast/clone_context.cpp @@ -13,10 +13,10 @@ namespace Carbon { auto CloneContext::CloneBase(Nonnull node) -> Nonnull { auto [it, added] = nodes_.insert({node, nullptr}); - CARBON_CHECK(added) << (it->second - ? "node was cloned multiple times: " - : "node was remapped before it was cloned: ") - << *node; + CARBON_CHECK( + added, "node was {0}: {1}", + it->second ? "cloned multiple times" : "remapped before it was cloned", + *node); // TODO: Generate a Visit member on AstNode and use it here to avoid these // macros. @@ -34,7 +34,7 @@ auto CloneContext::CloneBase(Nonnull node) // Cloning may have invalidated our iterator; redo lookup. auto* result = nodes_[node]; - CARBON_CHECK(result) << "CloneImpl didn't set the result pointer"; + CARBON_CHECK(result, "CloneImpl didn't set the result pointer"); return result; } diff --git a/explorer/ast/clone_context.h b/explorer/ast/clone_context.h index 7be00a42d538..fce87adc3325 100644 --- a/explorer/ast/clone_context.h +++ b/explorer/ast/clone_context.h @@ -131,7 +131,7 @@ class CloneContext { template auto GetExistingClone(Nonnull node) -> Nonnull { AstNode* cloned = nodes_.lookup(node); - CARBON_CHECK(cloned) << "expected node to be cloned"; + CARBON_CHECK(cloned, "expected node to be cloned"); return llvm::cast(cloned); } diff --git a/explorer/ast/declaration.cpp b/explorer/ast/declaration.cpp index b04f18e8ddb0..7a0670fc862c 100644 --- a/explorer/ast/declaration.cpp +++ b/explorer/ast/declaration.cpp @@ -413,7 +413,7 @@ auto FunctionDeclaration::Create(Nonnull arena, void CallableDeclaration::PrintIndent(int indent_num_spaces, llvm::raw_ostream& out) const { auto name = GetName(*this); - CARBON_CHECK(name) << "Unexpected missing name for `" << *this << "`."; + CARBON_CHECK(name, "Unexpected missing name for `{0}`.", *this); out.indent(indent_num_spaces) << "fn " << *name << " "; if (!deduced_parameters_.empty() || self_pattern_) { out << "["; diff --git a/explorer/ast/declaration.h b/explorer/ast/declaration.h index d09013f338ff..7668cbc4f686 100644 --- a/explorer/ast/declaration.h +++ b/explorer/ast/declaration.h @@ -101,7 +101,7 @@ class Declaration : public AstNode { // Set that this node is declared. Should only be called once, by the // type-checker, once the node is ready to be named and used. void set_is_declared() { - CARBON_CHECK(!is_declared_) << "should not be declared twice"; + CARBON_CHECK(!is_declared_, "should not be declared twice"); is_declared_ = true; } @@ -111,7 +111,7 @@ class Declaration : public AstNode { // Set that this node is type-checked. Should only be called once, by the // type-checker, once full type-checking is complete. void set_is_type_checked() { - CARBON_CHECK(!is_type_checked_) << "should not be type-checked twice"; + CARBON_CHECK(!is_type_checked_, "should not be type-checked twice"); is_type_checked_ = true; } @@ -674,7 +674,7 @@ class VariableDeclaration : public Declaration { // Can only be called by type-checking, if a conversion was required. void set_initializer(Nonnull initializer) { - CARBON_CHECK(has_initializer()) << "should not add a new initializer"; + CARBON_CHECK(has_initializer(), "should not add a new initializer"); initializer_ = initializer; } diff --git a/explorer/ast/element_path.h b/explorer/ast/element_path.h index 74d834ac37e2..4ba019bcd08a 100644 --- a/explorer/ast/element_path.h +++ b/explorer/ast/element_path.h @@ -113,8 +113,8 @@ class ElementPath : public Printable { // Removes all trailing `BaseElement`s, errors if there are no base elements. auto RemoveTrailingBaseElements() -> void { CARBON_CHECK(!components_.empty() && components_.back().element()->kind() == - ElementKind::BaseElement) - << "No base elements to remove."; + ElementKind::BaseElement, + "No base elements to remove."); const auto r_it = std::find_if( components_.rbegin(), components_.rend(), [](const Component& c) { return c.element()->kind() != ElementKind::BaseElement; diff --git a/explorer/ast/expression.cpp b/explorer/ast/expression.cpp index 7b216e4a671b..60212bee8684 100644 --- a/explorer/ast/expression.cpp +++ b/explorer/ast/expression.cpp @@ -231,8 +231,7 @@ void Expression::Print(llvm::raw_ostream& out) const { << *op.arguments()[1]; break; default: - CARBON_FATAL() << "Unexpected argument count: " - << op.arguments().size(); + CARBON_FATAL("Unexpected argument count: {0}", op.arguments().size()); } out << ")"; break; diff --git a/explorer/ast/expression.h b/explorer/ast/expression.h index cb9206f11b79..791e41b8f2af 100644 --- a/explorer/ast/expression.h +++ b/explorer/ast/expression.h @@ -113,7 +113,7 @@ class RewritableMixin : public Base { // Set the rewritten form of this expression. Can only be called during type // checking. auto set_rewritten_form(Nonnull rewritten_form) -> void { - CARBON_CHECK(!rewritten_form_.has_value()) << "rewritten form set twice"; + CARBON_CHECK(!rewritten_form_.has_value(), "rewritten form set twice"); rewritten_form_ = rewritten_form; this->set_static_type(&rewritten_form->static_type()); this->set_expression_category(rewritten_form->expression_category()); @@ -660,8 +660,9 @@ class StructTypeLiteral : public ConstantValueLiteral { std::vector fields) : ConstantValueLiteral(AstNodeKind::StructTypeLiteral, loc), fields_(std::move(fields)) { - CARBON_CHECK(!fields_.empty()) - << "`{}` is represented as a StructLiteral, not a StructTypeLiteral."; + CARBON_CHECK( + !fields_.empty(), + "`{}` is represented as a StructLiteral, not a StructTypeLiteral."); } explicit StructTypeLiteral(CloneContext& context, diff --git a/explorer/ast/impl_binding.h b/explorer/ast/impl_binding.h index 89a9153e37ce..0ccbef791eca 100644 --- a/explorer/ast/impl_binding.h +++ b/explorer/ast/impl_binding.h @@ -49,14 +49,14 @@ class ImplBinding : public AstNode { // The constraint being implemented. // TODO: Rename this to `constraint`. auto interface() const -> Nonnull { - CARBON_CHECK(iface_) << "interface has not been set yet"; + CARBON_CHECK(iface_, "interface has not been set yet"); return *iface_; } // Set the interface being implemented, if not set by the constructor. Should // only be called by typechecking. void set_interface(Nonnull iface) { - CARBON_CHECK(!iface_) << "interface set twice"; + CARBON_CHECK(!iface_, "interface set twice"); iface_ = iface; } @@ -75,7 +75,7 @@ class ImplBinding : public AstNode { // These functions exist only so that an `ImplBinding` can be used as a // `ValueNodeView` as a key in a `StaticScope`. auto static_type() const -> const Value& { - CARBON_FATAL() << "an ImplBinding has no type"; + CARBON_FATAL("an ImplBinding has no type"); } auto expression_category() const -> ExpressionCategory { return ExpressionCategory::Value; diff --git a/explorer/ast/pattern.h b/explorer/ast/pattern.h index a81b1f919ecc..c1d3c42b73b1 100644 --- a/explorer/ast/pattern.h +++ b/explorer/ast/pattern.h @@ -79,7 +79,7 @@ class Pattern : public AstNode { // Sets the value of this pattern. Can only be called once, during // typechecking. void set_value(Nonnull value) { - CARBON_CHECK(!value_) << "set_value called more than once"; + CARBON_CHECK(!value_, "set_value called more than once"); value_ = value; } @@ -307,7 +307,7 @@ class GenericBinding : public Pattern { // Set the index of this binding. Should be called only during type-checking. void set_index(int index) { - CARBON_CHECK(!index_) << "should only set depth and index once"; + CARBON_CHECK(!index_, "should only set depth and index once"); index_ = index; } diff --git a/explorer/ast/statement.h b/explorer/ast/statement.h index e90504380205..efb194820d75 100644 --- a/explorer/ast/statement.h +++ b/explorer/ast/statement.h @@ -150,7 +150,7 @@ class Assign : public Statement { // Set the rewritten form of this statement. Can only be called during type // checking. auto set_rewritten_form(Nonnull rewritten_form) -> void { - CARBON_CHECK(!rewritten_form_.has_value()) << "rewritten form set twice"; + CARBON_CHECK(!rewritten_form_.has_value(), "rewritten form set twice"); rewritten_form_ = rewritten_form; } @@ -196,7 +196,7 @@ class IncrementDecrement : public Statement { // Set the rewritten form of this statement. Can only be called during type // checking. auto set_rewritten_form(Nonnull rewritten_form) -> void { - CARBON_CHECK(!rewritten_form_.has_value()) << "rewritten form set twice"; + CARBON_CHECK(!rewritten_form_.has_value(), "rewritten form set twice"); rewritten_form_ = rewritten_form; } @@ -256,7 +256,7 @@ class VariableDefinition : public Statement { // Can only be called by type-checking, if a conversion was required. void set_init(Nonnull init) { - CARBON_CHECK(has_init()) << "should not add a new initializer"; + CARBON_CHECK(has_init(), "should not add a new initializer"); init_ = init; } diff --git a/explorer/ast/static_scope.cpp b/explorer/ast/static_scope.cpp index f5d6b62964e1..480bdb061935 100644 --- a/explorer/ast/static_scope.cpp +++ b/explorer/ast/static_scope.cpp @@ -54,7 +54,7 @@ void StaticScope::PrintID(llvm::raw_ostream& out) const { void StaticScope::MarkDeclared(std::string_view name) { auto it = declared_names_.find(name); - CARBON_CHECK(it != declared_names_.end()) << name << " not found"; + CARBON_CHECK(it != declared_names_.end(), "{0} not found", name); if (it->second.status == NameStatus::KnownButNotDeclared) { it->second.status = NameStatus::DeclaredButNotUsable; if (trace_stream_->is_enabled()) { @@ -67,7 +67,7 @@ void StaticScope::MarkDeclared(std::string_view name) { void StaticScope::MarkUsable(std::string_view name) { auto it = declared_names_.find(name); - CARBON_CHECK(it != declared_names_.end()) << name << " not found"; + CARBON_CHECK(it != declared_names_.end(), "{0} not found", name); it->second.status = NameStatus::Usable; if (trace_stream_->is_enabled()) { trace_stream_->Result() diff --git a/explorer/ast/value.cpp b/explorer/ast/value.cpp index bbd87ab7c1dc..b17792bb24b2 100644 --- a/explorer/ast/value.cpp +++ b/explorer/ast/value.cpp @@ -159,8 +159,8 @@ static auto GetPositionalElement(Nonnull tuple, const ElementPath::Component& path_comp, SourceLocation source_loc) -> ErrorOr> { - CARBON_CHECK(path_comp.element()->kind() == ElementKind::PositionalElement) - << "Invalid non-tuple member"; + CARBON_CHECK(path_comp.element()->kind() == ElementKind::PositionalElement, + "Invalid non-tuple member"); const auto* tuple_element = cast(path_comp.element()); const size_t index = tuple_element->index(); if (index < 0 || index >= tuple->elements().size()) { @@ -175,8 +175,8 @@ static auto GetNamedElement(Nonnull arena, Nonnull v, SourceLocation source_loc, std::optional> me_value) -> ErrorOr> { - CARBON_CHECK(field.element()->kind() == ElementKind::NamedElement) - << "Invalid element, expecting NamedElement"; + CARBON_CHECK(field.element()->kind() == ElementKind::NamedElement, + "Invalid element, expecting NamedElement"); const auto* member = cast(field.element()); const auto f = member->name(); if (field.witness().has_value()) { @@ -186,7 +186,7 @@ static auto GetNamedElement(Nonnull arena, Nonnull v, if (const auto* assoc_const = dyn_cast_or_null( member->declaration().value_or(nullptr))) { - CARBON_CHECK(field.interface()) << "have witness but no interface"; + CARBON_CHECK(field.interface(), "have witness but no interface"); // TODO: Use witness to find the value of the constant. return arena->New(v, *field.interface(), assoc_const, witness); @@ -259,8 +259,8 @@ static auto GetNamedElement(Nonnull arena, Nonnull v, // Get class value matching the virtual method, and turn it into a // bound method. for (int i = 0; i < level_diff; ++i) { - CARBON_CHECK(m_class_value->base()) - << "Error trying to access function class value"; + CARBON_CHECK(m_class_value->base(), + "Error trying to access function class value"); m_class_value = *m_class_value->base(); } return arena->New( @@ -299,7 +299,7 @@ static auto GetNamedElement(Nonnull arena, Nonnull v, &class_type.bindings()); } default: - CARBON_FATAL() << "named element access not supported for value " << *v; + CARBON_FATAL("named element access not supported for value {0}", *v); } } @@ -315,7 +315,7 @@ static auto GetElement(Nonnull arena, Nonnull v, if (const auto* tuple = dyn_cast(v)) { return GetPositionalElement(tuple, path_comp, source_loc); } else { - CARBON_FATAL() << "Invalid value for positional element"; + CARBON_FATAL("Invalid value for positional element"); } } case ElementKind::BaseElement: @@ -328,7 +328,7 @@ static auto GetElement(Nonnull arena, Nonnull v, ptr->address().ElementAddress(path_comp.element())); } default: - CARBON_FATAL() << "Invalid value for base element"; + CARBON_FATAL("Invalid value for base element"); } } } @@ -404,9 +404,9 @@ static auto SetFieldImpl( } case Value::Kind::TupleType: case Value::Kind::TupleValue: { - CARBON_CHECK((*path_begin).element()->kind() == - ElementKind::PositionalElement) - << "Invalid non-positional member for tuple"; + CARBON_CHECK( + (*path_begin).element()->kind() == ElementKind::PositionalElement, + "Invalid non-positional member for tuple"); std::vector> elements = cast(*value).elements(); const size_t index = @@ -425,7 +425,7 @@ static auto SetFieldImpl( } } default: - CARBON_FATAL() << "field access not allowed for value " << *value; + CARBON_FATAL("field access not allowed for value {0}", *value); } } @@ -841,7 +841,7 @@ void IntrinsicConstraint::Print(llvm::raw_ostream& out) const { static auto BindingMapEqual( const BindingMap& map1, const BindingMap& map2, std::optional> equality_ctx) -> bool { - CARBON_CHECK(map1.size() == map2.size()) << "maps should have same keys"; + CARBON_CHECK(map1.size() == map2.size(), "maps should have same keys"); for (const auto& [key, value] : map1) { if (!ValueEqual(value, map2.at(key), equality_ctx)) { return false; @@ -1025,17 +1025,16 @@ auto TypeEqual(Nonnull t1, Nonnull t2, case Value::Kind::MixinPseudoType: case Value::Kind::TypeOfMixinPseudoType: case Value::Kind::TypeOfNamespaceName: - CARBON_FATAL() << "TypeEqual used to compare non-type values\n" - << *t1 << "\n" - << *t2; + CARBON_FATAL("TypeEqual used to compare non-type values\n{0}\n{1}", *t1, + *t2); case Value::Kind::ImplWitness: case Value::Kind::BindingWitness: case Value::Kind::ConstraintWitness: case Value::Kind::ConstraintImplWitness: - CARBON_FATAL() << "TypeEqual: unexpected Witness"; + CARBON_FATAL("TypeEqual: unexpected Witness"); break; case Value::Kind::AutoType: - CARBON_FATAL() << "TypeEqual: unexpected AutoType"; + CARBON_FATAL("TypeEqual: unexpected AutoType"); break; } } @@ -1123,8 +1122,8 @@ static auto ValueStructurallyEqual( GetName(cast(v1)->declaration()); std::optional name2 = GetName(cast(v2)->declaration()); - CARBON_CHECK(name1.has_value() && name2.has_value()) - << "parameterized name refers to unnamed declaration"; + CARBON_CHECK(name1.has_value() && name2.has_value(), + "parameterized name refers to unnamed declaration"); return *name1 == *name2; } case Value::Kind::AssociatedConstant: { @@ -1171,8 +1170,7 @@ static auto ValueStructurallyEqual( case Value::Kind::MemberName: // TODO: support pointer comparisons once we have a clearer distinction // between pointers and lvalues. - CARBON_FATAL() << "ValueEqual does not support this kind of value: " - << *v1; + CARBON_FATAL("ValueEqual does not support this kind of value: {0}", *v1); } } diff --git a/explorer/ast/value.h b/explorer/ast/value.h index 49211f9e164d..ed3e4b6b353e 100644 --- a/explorer/ast/value.h +++ b/explorer/ast/value.h @@ -924,8 +924,8 @@ class MixinPseudoType : public Value { public: explicit MixinPseudoType(Nonnull declaration) : Value(Kind::MixinPseudoType), declaration_(declaration) { - CARBON_CHECK(!declaration->params().has_value()) - << "missing arguments for parameterized mixin type"; + CARBON_CHECK(!declaration->params().has_value(), + "missing arguments for parameterized mixin type"); } explicit MixinPseudoType(Nonnull declaration, Nonnull bindings) @@ -982,8 +982,8 @@ class InterfaceType : public Value { public: explicit InterfaceType(Nonnull declaration) : Value(Kind::InterfaceType), declaration_(declaration) { - CARBON_CHECK(!declaration->params().has_value()) - << "missing arguments for parameterized interface type"; + CARBON_CHECK(!declaration->params().has_value(), + "missing arguments for parameterized interface type"); } explicit InterfaceType(Nonnull declaration, Nonnull bindings) @@ -1334,8 +1334,8 @@ class ConstraintImplWitness : public Witness { // element. static auto Make(Nonnull arena, Nonnull witness, int index) -> Nonnull { - CARBON_CHECK(!llvm::isa(witness)) - << "impl witness has no components to access"; + CARBON_CHECK(!llvm::isa(witness), + "impl witness has no components to access"); if (const auto* constraint_witness = llvm::dyn_cast(witness)) { return constraint_witness->witnesses()[index]; @@ -1348,8 +1348,8 @@ class ConstraintImplWitness : public Witness { : Witness(Kind::ConstraintImplWitness), constraint_witness_(constraint_witness), index_(index) { - CARBON_CHECK(!llvm::isa(constraint_witness)) - << "should have resolved element from constraint witness"; + CARBON_CHECK(!llvm::isa(constraint_witness), + "should have resolved element from constraint witness"); } static auto classof(const Value* value) -> bool { @@ -1480,8 +1480,8 @@ class MemberName : public Value, public Printable { base_type_(base_type), interface_(interface), member_(member) { - CARBON_CHECK(base_type || interface) - << "member name must be in a type, an interface, or both"; + CARBON_CHECK(base_type || interface, + "member name must be in a type, an interface, or both"); } static auto classof(const Value* value) -> bool { diff --git a/explorer/file_test.cpp b/explorer/file_test.cpp index 89f60d63c03a..90791dcb85be 100644 --- a/explorer/file_test.cpp +++ b/explorer/file_test.cpp @@ -23,8 +23,8 @@ class ExplorerFileTest : public FileTestBase { : FileTestBase(test_name), prelude_line_re_(R"(prelude.carbon:(\d+))"), timing_re_(R"((Time elapsed in \w+: )\d+(ms))") { - CARBON_CHECK(prelude_line_re_.ok()) << prelude_line_re_.error(); - CARBON_CHECK(timing_re_.ok()) << timing_re_.error(); + CARBON_CHECK(prelude_line_re_.ok(), "{0}", prelude_line_re_.error()); + CARBON_CHECK(timing_re_.ok(), "{0}", timing_re_.error()); } auto Run(const llvm::SmallVector& test_args, diff --git a/explorer/fuzzing/ast_to_proto.cpp b/explorer/fuzzing/ast_to_proto.cpp index 62e7ce0b6d1f..d02835936951 100644 --- a/explorer/fuzzing/ast_to_proto.cpp +++ b/explorer/fuzzing/ast_to_proto.cpp @@ -638,10 +638,10 @@ static auto DeclarationToProto(const Declaration& declaration) default: // Parser shouldn't allow self_pattern to be anything other than // AddrPattern or BindingPattern - CARBON_FATAL() - << "self_pattern in method declaration can be either " - "AddrPattern or BindingPattern. Actual pattern: " - << function.self_pattern(); + CARBON_FATAL( + "self_pattern in method declaration can be either AddrPattern " + "or BindingPattern. Actual pattern: {0}", + function.self_pattern()); break; } } @@ -674,10 +674,10 @@ static auto DeclarationToProto(const Declaration& declaration) default: // Parser shouldn't allow self_pattern to be anything other than // AddrPattern or BindingPattern - CARBON_FATAL() - << "self_pattern in method declaration can be either " - "AddrPattern or BindingPattern. Actual pattern: " - << function.self_pattern(); + CARBON_FATAL( + "self_pattern in method declaration can be either AddrPattern " + "or BindingPattern. Actual pattern: {0}", + function.self_pattern()); break; } } @@ -833,7 +833,7 @@ static auto DeclarationToProto(const Declaration& declaration) } case DeclarationKind::SelfDeclaration: { - CARBON_FATAL() << "Unreachable SelfDeclaration in DeclarationToProto()."; + CARBON_FATAL("Unreachable SelfDeclaration in DeclarationToProto()."); } case DeclarationKind::AliasDeclaration: { diff --git a/explorer/fuzzing/fuzzer_util.cpp b/explorer/fuzzing/fuzzer_util.cpp index 6f6fe713e360..13069e7acbc7 100644 --- a/explorer/fuzzing/fuzzer_util.cpp +++ b/explorer/fuzzing/fuzzer_util.cpp @@ -38,10 +38,10 @@ auto ParseAndExecuteProto(const Fuzzing::Carbon& carbon) -> ErrorOr { const ErrorOr prelude_path = GetRunfilesFile("carbon/explorer/data/prelude.carbon"); // Can't do anything without a prelude, so it's a fatal error. - CARBON_CHECK(prelude_path.ok()) << prelude_path.error(); + CARBON_CHECK(prelude_path.ok(), "{0}", prelude_path.error()); llvm::ErrorOr> prelude = llvm::MemoryBuffer::getFile(*prelude_path); - CARBON_CHECK(!prelude.getError()) << prelude.getError().message(); + CARBON_CHECK(!prelude.getError(), "{0}", prelude.getError().message()); CARBON_CHECK(fs.addFile("prelude.carbon", /*ModificationTime=*/0, std::move(*prelude))); diff --git a/explorer/interpreter/action.cpp b/explorer/interpreter/action.cpp index 0c0b0c2e3c2c..d29331116c54 100644 --- a/explorer/interpreter/action.cpp +++ b/explorer/interpreter/action.cpp @@ -56,19 +56,19 @@ void RuntimeScope::Bind(ValueNodeView value_node, Address address) { bool success = locals_.insert({value_node, heap_->arena().New(address)}) .second; - CARBON_CHECK(success) << "Duplicate definition of " << value_node.base(); + CARBON_CHECK(success, "Duplicate definition of {0}", value_node.base()); } void RuntimeScope::BindAndPin(ValueNodeView value_node, Address address) { Bind(value_node, address); bool success = bound_values_.insert(&value_node.base()).second; - CARBON_CHECK(success) << "Duplicate pinned node for " << value_node.base(); + CARBON_CHECK(success, "Duplicate pinned node for {0}", value_node.base()); heap_->BindValueToReference(value_node, address); } void RuntimeScope::BindLifetimeToScope(Address address) { - CARBON_CHECK(address.element_path_.IsEmpty()) - << "Cannot extend lifetime of a specific sub-element"; + CARBON_CHECK(address.element_path_.IsEmpty(), + "Cannot extend lifetime of a specific sub-element"); allocations_.push_back(address.allocation_); } @@ -77,7 +77,7 @@ void RuntimeScope::BindValue(ValueNodeView value_node, CARBON_CHECK(!value_node.constant_value().has_value()); CARBON_CHECK(value->kind() != Value::Kind::LocationValue); bool success = locals_.insert({value_node, value}).second; - CARBON_CHECK(success) << "Duplicate definition of " << value_node.base(); + CARBON_CHECK(success, "Duplicate definition of {0}", value_node.base()); } auto RuntimeScope::Initialize(ValueNodeView value_node, @@ -89,7 +89,7 @@ auto RuntimeScope::Initialize(ValueNodeView value_node, const auto* location = heap_->arena().New(Address(allocations_.back())); bool success = locals_.insert({value_node, location}).second; - CARBON_CHECK(success) << "Duplicate definition of " << value_node.base(); + CARBON_CHECK(success, "Duplicate definition of {0}", value_node.base()); return location; } @@ -97,11 +97,11 @@ void RuntimeScope::Merge(RuntimeScope other) { CARBON_CHECK(heap_ == other.heap_); for (auto& element : other.locals_) { bool success = locals_.insert(element).second; - CARBON_CHECK(success) << "Duplicate definition of " << element.first; + CARBON_CHECK(success, "Duplicate definition of {0}", element.first); } for (const auto* element : other.bound_values_) { bool success = bound_values_.insert(element).second; - CARBON_CHECK(success) << "Duplicate bound value."; + CARBON_CHECK(success, "Duplicate bound value."); } allocations_.insert(allocations_.end(), other.allocations_.begin(), other.allocations_.end()); diff --git a/explorer/interpreter/action.h b/explorer/interpreter/action.h index b6de1cf0c9cf..c826cd8e81ff 100644 --- a/explorer/interpreter/action.h +++ b/explorer/interpreter/action.h @@ -346,7 +346,7 @@ class StatementAction : public Action { // Sets the location provided to an initializing expression. auto set_location_created(AllocationId location_created) { - CARBON_CHECK(!location_created_) << "location created set twice"; + CARBON_CHECK(!location_created_, "location created set twice"); location_created_ = location_created; } // Returns the location provided to an initializing expression, if any. diff --git a/explorer/interpreter/action_stack.cpp b/explorer/interpreter/action_stack.cpp index c6ada2f77929..e60b81a43174 100644 --- a/explorer/interpreter/action_stack.cpp +++ b/explorer/interpreter/action_stack.cpp @@ -92,7 +92,7 @@ void ActionStack::MergeScope(RuntimeScope scope) { globals_->Merge(std::move(scope)); return; } - CARBON_FATAL() << "No current scope"; + CARBON_FATAL("No current scope"); } namespace { @@ -132,9 +132,9 @@ auto ActionStack::FinishAction() -> ErrorOr { std::unique_ptr act = Pop(); switch (FinishActionKindFor(act->kind())) { case FinishActionKind::Value: - CARBON_FATAL() << "This kind of action must produce a result: " << *act; + CARBON_FATAL("This kind of action must produce a result: {0}", *act); case FinishActionKind::NeverCalled: - CARBON_FATAL() << "Should not call FinishAction for: " << *act; + CARBON_FATAL("Should not call FinishAction for: {0}", *act); case FinishActionKind::NoValue: PopScopes(scopes_to_destroy); break; @@ -150,9 +150,9 @@ auto ActionStack::FinishAction(Nonnull result) std::unique_ptr act = Pop(); switch (FinishActionKindFor(act->kind())) { case FinishActionKind::NoValue: - CARBON_FATAL() << "This kind of action cannot produce results: " << *act; + CARBON_FATAL("This kind of action cannot produce results: {0}", *act); case FinishActionKind::NeverCalled: - CARBON_FATAL() << "Should not call FinishAction for: " << *act; + CARBON_FATAL("Should not call FinishAction for: {0}", *act); case FinishActionKind::Value: PopScopes(scopes_to_destroy); SetResult(result); @@ -183,8 +183,8 @@ auto ActionStack::ReplaceWith(std::unique_ptr replacement) -> ErrorOr { std::unique_ptr old = Pop(); CARBON_CHECK(FinishActionKindFor(old->kind()) == - FinishActionKindFor(replacement->kind())) - << "Can't replace action " << *old << " with " << *replacement; + FinishActionKindFor(replacement->kind()), + "Can't replace action {0} with {1}", *old, *replacement); Push(std::move(replacement)); return Success(); } diff --git a/explorer/interpreter/heap.cpp b/explorer/interpreter/heap.cpp index 2a35e8d59dab..1f8fad521e26 100644 --- a/explorer/interpreter/heap.cpp +++ b/explorer/interpreter/heap.cpp @@ -116,8 +116,8 @@ auto Heap::Deallocate(AllocationId allocation) -> ErrorOr { if (states_[allocation.index_] != ValueState::Dead) { states_[allocation.index_] = ValueState::Dead; } else { - CARBON_FATAL() << "deallocating an already dead value: " - << *values_[allocation.index_]; + CARBON_FATAL("deallocating an already dead value: {0}", + *values_[allocation.index_]); } if (trace_stream_->is_enabled()) { diff --git a/explorer/interpreter/impl_scope.cpp b/explorer/interpreter/impl_scope.cpp index e5e4e637cbd8..9d5b1c6559eb 100644 --- a/explorer/interpreter/impl_scope.cpp +++ b/explorer/interpreter/impl_scope.cpp @@ -28,8 +28,8 @@ void ImplScope::Add(Nonnull iface, const TypeChecker& type_checker, std::optional sort_key) { if (const auto* constraint = dyn_cast(iface)) { - CARBON_CHECK(!sort_key) - << "should only be given a sort key for an impl of an interface"; + CARBON_CHECK(!sort_key, + "should only be given a sort key for an impl of an interface"); // The caller should have substituted `.Self` for `type` already. Add(constraint->impls_constraints(), deduced, impl_bindings, witness, type_checker); @@ -85,8 +85,8 @@ static auto DiagnoseUnequalValues(SourceLocation source_loc, Nonnull b_evaluated, Nonnull equality_ctx) -> Error { - CARBON_CHECK(!ValueEqual(a_evaluated, b_evaluated, equality_ctx)) - << "expected unequal values"; + CARBON_CHECK(!ValueEqual(a_evaluated, b_evaluated, equality_ctx), + "expected unequal values"); auto error = ProgramError(source_loc); error << "constraint requires that " << *a_written; if (!ValueEqual(a_written, a_evaluated, std::nullopt)) { @@ -110,7 +110,7 @@ auto ImplScope::Resolve(Nonnull constraint_type, std::optional> witness, TryResolve(constraint_type, impl_type, source_loc, type_checker, bindings, /*diagnose_missing_impl=*/true)); - CARBON_CHECK(witness) << "should have diagnosed missing impl"; + CARBON_CHECK(witness, "should have diagnosed missing impl"); return *witness; } @@ -238,7 +238,7 @@ auto ImplScope::TryResolve(Nonnull constraint_type, } return {type_checker.MakeConstraintWitness(std::move(witnesses))}; } - CARBON_FATAL() << "expected a constraint, not " << *constraint_type; + CARBON_FATAL("expected a constraint, not {0}", *constraint_type); } auto ImplScope::VisitEqualValues( @@ -333,7 +333,7 @@ static auto CombineResults(Nonnull iface_type, return b; } } - CARBON_CHECK(impl_a && impl_b) << "non-final impl should not be symbolic"; + CARBON_CHECK(impl_a && impl_b, "non-final impl should not be symbolic"); // At this point, we're comparing two `impl` declarations, and either they're // both final or neither of them is. diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index bd3d057953d3..30d9f1d20405 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -292,8 +292,8 @@ auto Interpreter::EvalPrim(Operator op, Nonnull /*static_type*/, case Operator::BitShiftLeft: case Operator::BitShiftRight: case Operator::Complement: - CARBON_FATAL() << "operator " << OperatorToString(op) - << " should always be rewritten"; + CARBON_FATAL("operator {0} should always be rewritten", + OperatorToString(op)); } } @@ -320,7 +320,7 @@ auto Interpreter::StepLocation() -> ErrorOr { Nonnull value, todo_.ValueOfNode(cast(exp).value_node(), exp.source_loc())); - CARBON_CHECK(isa(value)) << *value; + CARBON_CHECK(isa(value), "{0}", *value); return todo_.FinishAction(value); } case ExpressionKind::SimpleMemberAccessExpression: { @@ -361,8 +361,8 @@ auto Interpreter::StepLocation() -> ErrorOr { if (constant_value) { return todo_.FinishAction(act.results().back()); } - CARBON_CHECK(!access.member().interface().has_value()) - << "unexpected location interface member"; + CARBON_CHECK(!access.member().interface().has_value(), + "unexpected location interface member"); CARBON_ASSIGN_OR_RETURN( Nonnull val, Convert(act.results()[0], *access.member().base_type(), @@ -411,8 +411,8 @@ auto Interpreter::StepLocation() -> ErrorOr { return todo_.ReplaceWith(std::make_unique(*rewrite)); } if (op.op() != Operator::Deref) { - CARBON_FATAL() - << "Can't treat primitive operator expression as location: " << exp; + CARBON_FATAL( + "Can't treat primitive operator expression as location: {0}", exp); } if (act.pos() == 0) { return todo_.Spawn( @@ -442,9 +442,9 @@ auto Interpreter::StepLocation() -> ErrorOr { case ExpressionKind::DotSelfExpression: case ExpressionKind::ArrayTypeLiteral: case ExpressionKind::BuiltinConvertExpression: - CARBON_FATAL() << "Can't treat expression as location: " << exp; + CARBON_FATAL("Can't treat expression as location: {0}", exp); case ExpressionKind::UnimplementedExpression: - CARBON_FATAL() << "Unimplemented: " << exp; + CARBON_FATAL("Unimplemented: {0}", exp); } } @@ -478,8 +478,8 @@ auto Interpreter::EvalAssociatedConstant( const auto* impl_witness = dyn_cast(witness); if (!impl_witness) { - CARBON_CHECK(phase() == Phase::CompileTime) - << "symbolic witnesses should only be formed at compile time"; + CARBON_CHECK(phase() == Phase::CompileTime, + "symbolic witnesses should only be formed at compile time"); CARBON_ASSIGN_OR_RETURN(Nonnull base, InstantiateType(&assoc->base(), source_loc)); return arena_->New(base, cast(interface), @@ -500,10 +500,11 @@ auto Interpreter::EvalAssociatedConstant( } } if (!result) { - CARBON_FATAL() << impl_witness->declaration() << " with constraint " - << *constraint - << " is missing value for associated constant " - << *interface << "." << assoc->constant().binding().name(); + CARBON_FATAL( + "{0} with constraint {1} is missing value for associated constant " + "{2}.{3}", + impl_witness->declaration(), *constraint, *interface, + assoc->constant().binding().name()); } return *result; } @@ -615,9 +616,9 @@ auto Interpreter::ConvertStructToClass( InstantiateType(class_type, source_loc)); for (const auto& field : init_struct->elements()) { if (field.name == NominalClassValue::BaseField) { - CARBON_CHECK(class_type->base().has_value()) - << "Invalid 'base' field for class '" - << class_type->declaration().name() << "' without base class."; + CARBON_CHECK(class_type->base().has_value(), + "Invalid 'base' field for class '{0}' without base class.", + class_type->declaration().name()); CARBON_ASSIGN_OR_RETURN( auto base, Convert(field.value, class_type->base().value(), source_loc)); @@ -626,8 +627,8 @@ auto Interpreter::ConvertStructToClass( struct_values.push_back(field); } } - CARBON_CHECK(!cast(inst_class)->base() || base_instance) - << "Invalid conversion for `" << *inst_class << "`: base class missing"; + CARBON_CHECK(!cast(inst_class)->base() || base_instance, + "Invalid conversion for `{0}`: base class missing", *inst_class); auto* converted_init_struct = arena_->New(std::move(struct_values)); Nonnull class_value_ptr = @@ -714,15 +715,15 @@ auto Interpreter::Convert(Nonnull value, case Value::Kind::ConstraintType: case Value::Kind::NamedConstraintType: case Value::Kind::InterfaceType: { - CARBON_CHECK(struct_val.elements().empty()) - << "only empty structs convert to `type`"; + CARBON_CHECK(struct_val.elements().empty(), + "only empty structs convert to `type`"); return arena_->New(); } default: { CARBON_CHECK(IsValueKindDependent(destination_type) || - isa(destination_type)) - << "Can't convert value " << *value << " to type " - << *destination_type; + (isa(destination_type)), + "Can't convert value {0} to type {1}", *value, + *destination_type); return value; } } @@ -757,9 +758,9 @@ auto Interpreter::Convert(Nonnull value, } default: { CARBON_CHECK(IsValueKindDependent(destination_type) || - isa(destination_type)) - << "Can't convert value " << *value << " to type " - << *destination_type; + (isa(destination_type)), + "Can't convert value {0} to type {1}", *value, + *destination_type); return value; } } @@ -832,8 +833,8 @@ auto Interpreter::Convert(Nonnull value, const auto* src_ptr = cast(value); CARBON_ASSIGN_OR_RETURN(const auto* pointee, heap_.Read(src_ptr->address(), source_loc)) - CARBON_CHECK(pointee->kind() == Value::Kind::NominalClassValue) - << "Unexpected pointer type"; + CARBON_CHECK(pointee->kind() == Value::Kind::NominalClassValue, + "Unexpected pointer type"); // Conversion logic for subtyping for function arguments only. // TODO: Drop when able to rewrite subtyping in TypeChecker for arguments. @@ -945,7 +946,7 @@ auto Interpreter::CallFunction(const CallExpression& call, ExpressionResult::Value(converted_args), call.source_loc(), &function_scope, generic_args, trace_stream_, this->arena_); - CARBON_CHECK(success) << "Failed to bind arguments to parameters"; + CARBON_CHECK(success, "Failed to bind arguments to parameters"); return todo_.Spawn(std::make_unique(*function.body(), location_received), std::move(function_scope)); @@ -977,7 +978,7 @@ auto Interpreter::CallFunction(const CallExpression& call, return todo_.FinishAction(arena_->New( &cast(decl), bindings)); default: - CARBON_FATAL() << "unknown kind of ParameterizedEntityName " << decl; + CARBON_FATAL("unknown kind of ParameterizedEntityName {0}", decl); } } default: @@ -997,8 +998,8 @@ auto Interpreter::CallDestructor(Nonnull fun, BindSelfIfPresent(fun, receiver, method_scope, generic_args, SourceLocation::DiagnosticsIgnored()); - CARBON_CHECK(method.body().has_value()) - << "Calling a method that's missing a body"; + CARBON_CHECK(method.body().has_value(), + "Calling a method that's missing a body"); auto act = std::make_unique(*method.body(), std::nullopt); return todo_.Spawn(std::unique_ptr(std::move(act)), @@ -1019,7 +1020,7 @@ void Interpreter::BindSelfIfPresent(Nonnull decl, bool success = PatternMatch(placeholder, receiver, source_location, &method_scope, generic_args, trace_stream_, this->arena_); - CARBON_CHECK(success) << "Failed to bind self"; + CARBON_CHECK(success, "Failed to bind self"); } } else { // Mutable self with `[addr self: Self*]` @@ -1036,7 +1037,7 @@ void Interpreter::BindSelfIfPresent(Nonnull decl, } bool success = PatternMatch(self_pattern, v, source_location, &method_scope, generic_args, trace_stream_, this->arena_); - CARBON_CHECK(success) << "Failed to bind addr self"; + CARBON_CHECK(success, "Failed to bind addr self"); } } @@ -1245,8 +1246,8 @@ auto Interpreter::StepExp() -> ErrorOr { dyn_cast(&access.static_type())) { // The result is a member name, such as in `Type.field_name`. Form a // suitable member name value. - CARBON_CHECK(phase() == Phase::CompileTime) - << "should not form MemberNames at runtime"; + CARBON_CHECK(phase() == Phase::CompileTime, + "should not form MemberNames at runtime"); auto found_in_interface = access.found_in_interface(); if (act.pos() == 1 && found_in_interface) { return todo_.Spawn(std::make_unique( @@ -1365,8 +1366,8 @@ auto Interpreter::StepExp() -> ErrorOr { return todo_.FinishAction(act.results().back()); } } else if (forming_member_name) { - CARBON_CHECK(phase() == Phase::CompileTime) - << "should not form MemberNames at runtime"; + CARBON_CHECK(phase() == Phase::CompileTime, + "should not form MemberNames at runtime"); if (auto found_in_interface = access.member().interface(); found_in_interface && act.pos() == 1) { return todo_.Spawn(std::make_unique( @@ -1378,9 +1379,9 @@ auto Interpreter::StepExp() -> ErrorOr { if (found_in_interface) { found_in_interface = cast(act.results().back()); } - CARBON_CHECK(!access.member().base_type().has_value()) - << "compound member access forming a member name should be " - "performing impl lookup"; + CARBON_CHECK(!access.member().base_type().has_value(), + "compound member access forming a member name should " + "be performing impl lookup"); auto* member_name = arena_->New(act.results()[0], found_in_interface, &access.member().member()); @@ -1427,8 +1428,8 @@ auto Interpreter::StepExp() -> ErrorOr { if (access.impl().has_value()) { witness = cast(act.results()[1]); } else { - CARBON_CHECK(access.member().base_type().has_value()) - << "compound access should have base type or impl"; + CARBON_CHECK(access.member().base_type().has_value(), + "compound access should have base type or impl"); CARBON_ASSIGN_OR_RETURN( object, Convert(object, *access.member().base_type(), exp.source_loc())); @@ -1582,7 +1583,7 @@ auto Interpreter::StepExp() -> ErrorOr { return todo_.FinishAction(act.results()[function_call_pos]); } } else { - CARBON_FATAL() << "in StepValueExp with Call pos " << act.pos(); + CARBON_FATAL("in StepValueExp with Call pos {0}", act.pos()); } } case ExpressionKind::IntrinsicExpression: { @@ -1622,7 +1623,7 @@ auto Interpreter::StepExp() -> ErrorOr { break; } default: - CARBON_FATAL() << "Too many format args: " << num_format_args; + CARBON_FATAL("Too many format args: {0}", num_format_args); } // Implicit newline; currently no way to disable it. *print_stream_ << "\n"; @@ -1712,9 +1713,9 @@ auto Interpreter::StepExp() -> ErrorOr { // reproducible across builds/platforms. int64_t r = (generator() % range) + low; CARBON_CHECK(r >= std::numeric_limits::min() && - r <= std::numeric_limits::max()) - << "Non-int32 result: " << r; - CARBON_CHECK(r >= low && r <= high) << "Out-of-range result: " << r; + r <= std::numeric_limits::max(), + "Non-int32 result: {0}", r); + CARBON_CHECK(r >= low && r <= high, "Out-of-range result: {0}", r); return todo_.FinishAction(arena_->New(r)); } case IntrinsicExpression::Intrinsic::ImplicitAs: { @@ -1747,8 +1748,8 @@ auto Interpreter::StepExp() -> ErrorOr { return todo_.FinishAction(result); } case IntrinsicExpression::Intrinsic::ImplicitAsConvert: { - CARBON_FATAL() - << "__intrinsic_implicit_as_convert should have been rewritten"; + CARBON_FATAL( + "__intrinsic_implicit_as_convert should have been rewritten"); } case IntrinsicExpression::Intrinsic::IntEq: { CARBON_CHECK(args.size() == 2); @@ -1891,7 +1892,7 @@ auto Interpreter::StepExp() -> ErrorOr { } case ExpressionKind::WhereExpression: { auto rewrite = cast(exp).rewritten_form(); - CARBON_CHECK(rewrite) << "where expression should be rewritten"; + CARBON_CHECK(rewrite, "where expression should be rewritten"); return todo_.ReplaceWith(std::make_unique( *rewrite, act.preserve_nested_categories(), act.location_received())); } @@ -1919,7 +1920,7 @@ auto Interpreter::StepExp() -> ErrorOr { } } case ExpressionKind::UnimplementedExpression: - CARBON_FATAL() << "Unimplemented: " << exp; + CARBON_FATAL("Unimplemented: {0}", exp); } // switch (exp->kind) } @@ -1982,7 +1983,7 @@ auto Interpreter::StepWitness() -> ErrorOr { } default: - CARBON_FATAL() << "unexpected kind of witness " << *witness; + CARBON_FATAL("unexpected kind of witness {0}", *witness); } } @@ -2183,11 +2184,12 @@ auto Interpreter::StepStmt() -> ErrorOr { const auto init_location = act.location_created(); v = v_expr ? (*v_expr)->value() : result; if (expr_category == ExpressionCategory::Reference) { - CARBON_CHECK(v_expr) << "Expecting ReferenceExpressionValue from " - "reference expression"; + CARBON_CHECK( + v_expr, + "Expecting ReferenceExpressionValue from reference expression"); v_location = (*v_expr)->address(); - CARBON_CHECK(v_location) - << "Expecting a valid address from reference expression"; + CARBON_CHECK(v_location, + "Expecting a valid address from reference expression"); } else if (has_initializing_expr && init_location && heap_.is_initialized(*init_location)) { // Bind even if a conversion is necessary. @@ -2228,9 +2230,10 @@ auto Interpreter::StepStmt() -> ErrorOr { PatternMatch(p, ExpressionResult(v, v_location, expr_category), stmt.source_loc(), &scope, generic_args, trace_stream_, this->arena_); - CARBON_CHECK(matched) - << stmt.source_loc() - << ": internal error in variable definition, match failed"; + CARBON_CHECK( + matched, + "{0}: internal error in variable definition, match failed", + stmt.source_loc()); } todo_.MergeScope(std::move(scope)); return todo_.FinishAction(); @@ -2435,9 +2438,8 @@ auto Interpreter::StepDestroy() -> ErrorOr { const Address var_addr = object.ElementAddress(arena_->New(var)); const auto v = heap_.Read(var_addr, var->source_loc()); - CARBON_CHECK(v.ok()) - << "Failed to read member `" << var->binding().name() - << "` from class `" << class_decl.name() << "`"; + CARBON_CHECK(v.ok(), "Failed to read member `{0}` from class `{1}`", + var->binding().name(), class_decl.name()); return todo_.Spawn(std::make_unique( arena_->New(var_addr), *v)); } else { @@ -2487,7 +2489,7 @@ auto Interpreter::StepDestroy() -> ErrorOr { todo_.Pop(); return Success(); } - CARBON_FATAL() << "Unreachable"; + CARBON_FATAL("Unreachable"); } auto Interpreter::StepCleanUp() -> ErrorOr { @@ -2577,9 +2579,9 @@ auto Interpreter::Step() -> ErrorOr { CARBON_RETURN_IF_ERROR(StepInstantiateType()); break; case Action::Kind::ScopeAction: - CARBON_FATAL() << "ScopeAction escaped ActionStack"; + CARBON_FATAL("ScopeAction escaped ActionStack"); case Action::Kind::RecursiveAction: - CARBON_FATAL() << "Tried to step a RecursiveAction"; + CARBON_FATAL("Tried to step a RecursiveAction"); } // switch return Success(); } diff --git a/explorer/interpreter/matching_impl_set.cpp b/explorer/interpreter/matching_impl_set.cpp index a3b2bf4dac2b..c27b29d27afd 100644 --- a/explorer/interpreter/matching_impl_set.cpp +++ b/explorer/interpreter/matching_impl_set.cpp @@ -118,7 +118,7 @@ MatchingImplSet::Match::Match(Nonnull parent, } MatchingImplSet::Match::~Match() { - CARBON_CHECK(parent_->matches_.back() == this) << "match stack broken"; + CARBON_CHECK(parent_->matches_.back() == this, "match stack broken"); parent_->matches_.pop_back(); } diff --git a/explorer/interpreter/pattern_match.cpp b/explorer/interpreter/pattern_match.cpp index 7fb6979034b2..ac6e68653060 100644 --- a/explorer/interpreter/pattern_match.cpp +++ b/explorer/interpreter/pattern_match.cpp @@ -30,8 +30,8 @@ static auto InitializePlaceholderValue(const ValueNodeView& value_node, } else { // Location initialized by initializing expression, bind node to // address. - CARBON_CHECK(v.address()) - << "Missing location from initializing expression"; + CARBON_CHECK(v.address(), + "Missing location from initializing expression"); bindings->Bind(value_node, *v.address()); } break; @@ -41,19 +41,18 @@ static auto InitializePlaceholderValue(const ValueNodeView& value_node, bindings->BindValue(value_node, v.value()); } else if (v.expression_category() == ExpressionCategory::Reference) { // Bind the reference expression value directly. - CARBON_CHECK(v.address()) - << "Missing location from reference expression"; + CARBON_CHECK(v.address(), "Missing location from reference expression"); bindings->BindAndPin(value_node, *v.address()); } else { // Location initialized by initializing expression, bind node to // address. - CARBON_CHECK(v.address()) - << "Missing location from initializing expression"; + CARBON_CHECK(v.address(), + "Missing location from initializing expression"); bindings->Bind(value_node, *v.address()); } break; case ExpressionCategory::Initializing: - CARBON_FATAL() << "Cannot pattern match an initializing expression"; + CARBON_FATAL("Cannot pattern match an initializing expression"); break; } } @@ -135,8 +134,8 @@ auto PatternMatch(Nonnull p, ExpressionResult v, return true; } default: - CARBON_FATAL() << "expected a tuple value in pattern, not " - << *v.value(); + CARBON_FATAL("expected a tuple value in pattern, not {0}", + *v.value()); } case Value::Kind::StructValue: { const auto& p_struct = cast(*p); @@ -172,12 +171,12 @@ auto PatternMatch(Nonnull p, ExpressionResult v, source_loc, bindings, generic_args, trace_stream, arena); } default: - CARBON_FATAL() << "expected a choice alternative in pattern, not " - << *v.value(); + CARBON_FATAL("expected a choice alternative in pattern, not {0}", + *v.value()); } case Value::Kind::UninitializedValue: - CARBON_FATAL() << "uninitialized value is not allowed in pattern " - << *v.value(); + CARBON_FATAL("uninitialized value is not allowed in pattern {0}", + *v.value()); case Value::Kind::FunctionType: switch (v.value()->kind()) { case Value::Kind::FunctionType: { diff --git a/explorer/interpreter/resolve_names.cpp b/explorer/interpreter/resolve_names.cpp index 9fbb2df592c7..0012c2ede61f 100644 --- a/explorer/interpreter/resolve_names.cpp +++ b/explorer/interpreter/resolve_names.cpp @@ -325,8 +325,8 @@ auto NameResolver::ResolveNamesImpl(Expression& expression, } if (const auto* namespace_decl = dyn_cast(base)) { auto ns_it = namespace_scopes_.find(namespace_decl); - CARBON_CHECK(ns_it != namespace_scopes_.end()) - << "name resolved to undeclared namespace"; + CARBON_CHECK(ns_it != namespace_scopes_.end(), + "name resolved to undeclared namespace"); CARBON_ASSIGN_OR_RETURN( const auto value_node, ns_it->second.ResolveHere(scope, access.member_name(), @@ -459,7 +459,7 @@ auto NameResolver::ResolveNamesImpl(Expression& expression, case ExpressionKind::ValueLiteral: case ExpressionKind::BuiltinConvertExpression: case ExpressionKind::BaseAccessExpression: - CARBON_FATAL() << "should not exist before type checking"; + CARBON_FATAL("should not exist before type checking"); case ExpressionKind::UnimplementedExpression: return ProgramError(expression.source_loc()) << "Unimplemented"; } @@ -603,9 +603,9 @@ auto NameResolver::ResolveNamesImpl(Statement& statement, } CARBON_RETURN_IF_ERROR(ResolveNames(def.pattern(), enclosing_scope)); if (def.is_returned()) { - CARBON_CHECK(def.pattern().kind() == PatternKind::BindingPattern) - << def.pattern().source_loc() - << "returned var definition can only be a binding pattern"; + CARBON_CHECK(def.pattern().kind() == PatternKind::BindingPattern, + "{0}returned var definition can only be a binding pattern", + def.pattern().source_loc()); CARBON_RETURN_IF_ERROR(enclosing_scope.AddReturnedVar( ValueNodeView(&cast(def.pattern())))); } @@ -924,7 +924,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, } case DeclarationKind::SelfDeclaration: { - CARBON_FATAL() << "Unreachable: resolving names for `Self` declaration"; + CARBON_FATAL("Unreachable: resolving names for `Self` declaration"); } case DeclarationKind::AliasDeclaration: { diff --git a/explorer/interpreter/resolve_unformed.cpp b/explorer/interpreter/resolve_unformed.cpp index 9b091b5989d0..e5ee55f1ccce 100644 --- a/explorer/interpreter/resolve_unformed.cpp +++ b/explorer/interpreter/resolve_unformed.cpp @@ -140,8 +140,8 @@ static auto ResolveUnformedImpl(Nonnull trace_stream, case ExpressionKind::OperatorExpression: { const auto& opt_exp = cast(*expression); if (opt_exp.op() == Operator::AddressOf) { - CARBON_CHECK(opt_exp.arguments().size() == 1) - << "OperatorExpression with op & can only have 1 argument"; + CARBON_CHECK(opt_exp.arguments().size() == 1, + "OperatorExpression with op & can only have 1 argument"); CARBON_RETURN_IF_ERROR( // When a variable is taken address of, defer the unformed check to // runtime. A more sound analysis can be implemented when a diff --git a/explorer/interpreter/stack.h b/explorer/interpreter/stack.h index 79803a14bd63..3cc35810faad 100644 --- a/explorer/interpreter/stack.h +++ b/explorer/interpreter/stack.h @@ -32,7 +32,7 @@ struct Stack { // // - Requires: !this->IsEmpty() auto Pop() -> T { - CARBON_CHECK(!empty()) << "Can't pop from empty stack."; + CARBON_CHECK(!empty(), "Can't pop from empty stack."); auto r = std::move(elements_.back()); elements_.pop_back(); return r; @@ -42,9 +42,9 @@ struct Stack { // // - Requires: n >= 0 && n <= Count() void Pop(int n) { - CARBON_CHECK(n >= 0) << "Negative pop count disallowed."; - CARBON_CHECK(static_cast(n) <= elements_.size()) - << "Can only pop as many elements as stack has."; + CARBON_CHECK(n >= 0, "Negative pop count disallowed."); + CARBON_CHECK(static_cast(n) <= elements_.size(), + "Can only pop as many elements as stack has."); elements_.erase(elements_.end() - n, elements_.end()); } @@ -52,7 +52,7 @@ struct Stack { // // - Requires: !this->IsEmpty() auto Top() const -> const T& { - CARBON_CHECK(!empty()) << "Empty stack has no Top()."; + CARBON_CHECK(!empty(), "Empty stack has no Top()."); return elements_.back(); } diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index da09149cd843..fa2ab103d404 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -109,7 +109,7 @@ static auto ExpectCompleteType(SourceLocation source_loc, case Value::Kind::ParameterizedEntityName: case Value::Kind::MemberName: case Value::Kind::MixinPseudoType: - CARBON_FATAL() << "should not see non-type values"; + CARBON_FATAL("should not see non-type values"); case Value::Kind::IntType: case Value::Kind::BoolType: @@ -195,7 +195,7 @@ static auto ExpectConcreteType(SourceLocation source_loc, // Returns whether `type` is a placeholder type, which is a second-class type // that cannot be the type of a binding but can be the type of an expression. static auto IsPlaceholderType(Nonnull type) -> bool { - CARBON_CHECK(IsType(type)) << "expected a type, but found " << *type; + CARBON_CHECK(IsType(type), "expected a type, but found {0}", *type); return isa(type); } @@ -568,14 +568,14 @@ auto TypeChecker::BuildSubtypeConversion(Nonnull source, while (!TypeEqual(cur_class, dest_class, std::nullopt)) { const auto src = src_class->declaration().name(); const auto base_class = cur_class->base(); - CARBON_CHECK(base_class) << "Invalid subtyping conversion"; + CARBON_CHECK(base_class, "Invalid subtyping conversion"); auto* base_expr = arena_->New( source->source_loc(), last_expr, arena_->New(arena_->New(*base_class))); last_expr = base_expr; cur_class = *base_class; } - CARBON_CHECK(last_expr) << "Error, no conversion was needed"; + CARBON_CHECK(last_expr, "Error, no conversion was needed"); return last_expr; } @@ -758,7 +758,7 @@ auto TypeChecker::BuildBuiltinConversion(Nonnull source, return conversion_failed(); } - CARBON_FATAL() << "unreachable"; + CARBON_FATAL("unreachable"); } auto TypeChecker::ImplicitlyConvert(std::string_view context, @@ -892,8 +892,8 @@ auto TypeChecker::IsIntrinsicConstraintSatisfied( // TODO: Check to see if this constraint is known in the current impl scope. switch (constraint.kind) { case IntrinsicConstraint::ImplicitAs: - CARBON_CHECK(constraint.arguments.size() == 1) - << "wrong number of arguments for `__intrinsic_implicit_as`"; + CARBON_CHECK(constraint.arguments.size() == 1, + "wrong number of arguments for `__intrinsic_implicit_as`"); CARBON_ASSIGN_OR_RETURN( bool convertible, IsBuiltinConversion(source_loc, constraint.type, @@ -1007,7 +1007,7 @@ auto TypeChecker::ExpectNonPlaceholderType(SourceLocation source_loc, return ProgramError(source_loc) << "expected `.member_name` after name of " << *namespace_type; } - CARBON_FATAL() << "unknown kind of placeholder type " << *type; + CARBON_FATAL("unknown kind of placeholder type {0}", *type); } // Argument deduction matches two values and attempts to find a set of @@ -1204,8 +1204,9 @@ auto TypeChecker::ArgumentDeduction::Deduce(Nonnull param, return diagnose_missing_field(param_struct, arg_field, false); } } - CARBON_FATAL() << "field count mismatch but no missing field; " - << "duplicate field name?"; + CARBON_FATAL( + "field count mismatch but no missing field; duplicate field " + "name?"); } } else { for (const auto [param_field, arg_field] : @@ -1350,7 +1351,7 @@ auto TypeChecker::ArgumentDeduction::Deduce(Nonnull param, } case Value::Kind::MixinPseudoType: case Value::Kind::TypeOfMixinPseudoType: - CARBON_CHECK(false) << "Type expression must not contain Mixin types"; + CARBON_CHECK(false, "Type expression must not contain Mixin types"); } } @@ -2515,13 +2516,13 @@ auto TypeChecker::DeduceCallBindings( /*allow_implicit_conversion=*/true)); } } - CARBON_CHECK(generic_params.empty()) - << "did not find all generic parameters in parameter list"; + CARBON_CHECK(generic_params.empty(), + "did not find all generic parameters in parameter list"); CARBON_ASSIGN_OR_RETURN( std::optional bindings, deduction.Finish(*this, impl_scope, /*diagnose_deduction_failure=*/true)); - CARBON_CHECK(bindings) << "should have diagnosed deduction failure"; + CARBON_CHECK(bindings, "should have diagnosed deduction failure"); call.set_bindings(std::move(*bindings)); // Convert the arguments to the deduced and substituted parameter type. @@ -2791,8 +2792,9 @@ auto TypeChecker::TypeCheckExpImpl(Nonnull e, case ExpressionKind::ValueLiteral: case ExpressionKind::BuiltinConvertExpression: case ExpressionKind::BaseAccessExpression: - CARBON_FATAL() << "attempting to type check node " << *e - << " generated during type checking"; + CARBON_FATAL( + "attempting to type check node {0} generated during type checking", + *e); case ExpressionKind::IndexExpression: { auto& index = cast(*e); CARBON_RETURN_IF_ERROR(TypeCheckExp(&index.object(), impl_scope)); @@ -2943,8 +2945,8 @@ auto TypeChecker::TypeCheckExpImpl(Nonnull e, return ProgramError(access.source_loc()) << "Member access to aliases is not yet supported."; default: - CARBON_FATAL() << "member " << access.member_name() - << " is not a field or method"; + CARBON_FATAL("member {0} is not a field or method", + access.member_name()); break; } return Success(); @@ -3344,8 +3346,8 @@ auto TypeChecker::TypeCheckExpImpl(Nonnull e, // This should not be possible: the name of a static member // function should have function type not member name type. CARBON_CHECK(!has_instance || is_instance_member || - !member_name.base_type().has_value()) - << "vacuous compound member access"; + !member_name.base_type().has_value(), + "vacuous compound member access"); // If this is instance access, remove self bound from function type if (has_instance && is_instance_member) { CARBON_RETURN_IF_ERROR(set_static_type_remove_self()); @@ -3365,8 +3367,7 @@ auto TypeChecker::TypeCheckExpImpl(Nonnull e, access.set_expression_category(access.object().expression_category()); return Success(); default: - CARBON_FATAL() << "member " << member_name - << " is not a field or method"; + CARBON_FATAL("member {0} is not a field or method", member_name); break; } @@ -3674,10 +3675,11 @@ auto TypeChecker::TypeCheckExpImpl(Nonnull e, // Currently the only kinds of parameterized entities we support are // types. - CARBON_CHECK( - isa(param_name.declaration())) - << "unknown type of ParameterizedEntityName for " << param_name; + CARBON_CHECK((isa( + param_name.declaration())), + "unknown type of ParameterizedEntityName for {0}", + param_name); call.set_static_type(arena_->New()); call.set_expression_category(ExpressionCategory::Value); return Success(); @@ -4109,7 +4111,7 @@ auto TypeChecker::TypeCheckExpImpl(Nonnull e, return Success(); } case ExpressionKind::UnimplementedExpression: - CARBON_FATAL() << "Unimplemented: " << *e; + CARBON_FATAL("Unimplemented: {0}", *e); case ExpressionKind::ArrayTypeLiteral: { auto& array_literal = cast(*e); CARBON_ASSIGN_OR_RETURN( @@ -4200,18 +4202,18 @@ auto TypeChecker::TypeCheckTypeExp(Nonnull type_expression, arena_->New())); CARBON_ASSIGN_OR_RETURN(Nonnull type, InterpExp(type_expression)); - CARBON_CHECK(IsType(type)) - << "type expression did not produce a type, got " << *type; + CARBON_CHECK(IsType(type), "type expression did not produce a type, got {0}", + *type); if (concrete) { if (TypeIsDeduceable(type)) { return ProgramError(type_expression->source_loc()) << "`auto` is not permitted in this context"; } - CARBON_CHECK(IsNonDeduceableType(type)) - << "unknown kind of non-concrete type " << *type; + CARBON_CHECK(IsNonDeduceableType(type), + "unknown kind of non-concrete type {0}", *type); } - CARBON_CHECK(!IsPlaceholderType(type)) - << "should be no way to write a placeholder type"; + CARBON_CHECK(!IsPlaceholderType(type), + "should be no way to write a placeholder type"); return type; } @@ -4325,9 +4327,10 @@ auto TypeChecker::TypeCheckPattern( arena_->New())); CARBON_ASSIGN_OR_RETURN(type, InterpExp(converted)); } - CARBON_CHECK(IsType(type)) - << "conversion to type succeeded but didn't produce a type, got " - << *type; + CARBON_CHECK( + IsType(type), + "conversion to type succeeded but didn't produce a type, got {0}", + *type); if (expected) { // TODO: Per proposal #2188, we should be performing conversions at // this level rather than on the overall initializer. @@ -4348,11 +4351,11 @@ auto TypeChecker::TypeCheckPattern( CARBON_RETURN_IF_ERROR(ExpectResolvedBindingType(binding, type)); } - CARBON_CHECK(IsNonDeduceableType(type)) - << "did not resolve " << binding << " to concrete type, got " - << *type; - CARBON_CHECK(!IsPlaceholderType(type)) - << "should be no way to write a placeholder type"; + CARBON_CHECK(IsNonDeduceableType(type), + "did not resolve {0} to concrete type, got {1}", binding, + *type); + CARBON_CHECK(!IsPlaceholderType(type), + "should be no way to write a placeholder type"); binding.set_static_type(type); binding.set_value(binding.name() != AnonymousName ? arena_->New(&binding) @@ -4897,7 +4900,7 @@ auto TypeChecker::DeclareCallableDeclaration(Nonnull f, const ScopeInfo& scope_info) -> ErrorOr { const auto name = GetName(*f); - CARBON_CHECK(name) << "Unexpected missing name for `" << *f << "`."; + CARBON_CHECK(name, "Unexpected missing name for `{0}`.", *f); if (trace_stream_->is_enabled()) { trace_stream_->Start() << "declaring function `" << *name << "` (" << f->source_loc() << ")\n"; @@ -4997,7 +5000,7 @@ auto TypeChecker::DeclareCallableDeclaration(Nonnull f, arena_->New(cast(f))); break; default: - CARBON_FATAL() << "f is not a callable declaration"; + CARBON_FATAL("f is not a callable declaration"); } if (name == "Main") { @@ -5027,7 +5030,7 @@ auto TypeChecker::TypeCheckCallableDeclaration(Nonnull f, const ImplScope& impl_scope) -> ErrorOr { auto name = GetName(*f); - CARBON_CHECK(name) << "Unexpected missing name for `" << *f << "`."; + CARBON_CHECK(name, "Unexpected missing name for `{0}`.", *f); if (trace_stream_->is_enabled()) { trace_stream_->Start() << "checking function `" << *name << "` (" << f->source_loc() << ")\n"; @@ -5165,8 +5168,8 @@ auto TypeChecker::DeclareClassDeclaration(Nonnull class_decl, << "Error declaring `" << fun->name() << "`" << ": class functions cannot be virtual."; } - CARBON_CHECK(!fun->name().is_qualified()) - << "qualified function name not permitted in class scope"; + CARBON_CHECK(!fun->name().is_qualified(), + "qualified function name not permitted in class scope"); if (fun->virt_override() == VirtualOverride::Abstract && fun->body().has_value()) { @@ -5312,8 +5315,8 @@ auto TypeChecker::TypeCheckClassDeclaration( } auto [it, inserted] = collected_members_.insert({class_decl, CollectedMembersMap()}); - CARBON_CHECK(inserted) << "Adding class " << class_decl->name() - << " to collected_members_ must not fail"; + CARBON_CHECK(inserted, "Adding class {0} to collected_members_ must not fail", + class_decl->name()); for (Nonnull m : class_decl->members()) { CARBON_RETURN_IF_ERROR(TypeCheckDeclaration(m, class_scope, class_decl)); CARBON_RETURN_IF_ERROR(CollectMember(class_decl, m)); @@ -5459,8 +5462,8 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( Nonnull constraint_decl, const ScopeInfo& scope_info) -> ErrorOr { CARBON_CHECK( - isa(constraint_decl)) - << "unexpected kind of constraint type declaration"; + (isa(constraint_decl)), + "unexpected kind of constraint type declaration"); bool is_interface = isa(constraint_decl); if (trace_stream_->is_enabled()) { @@ -5635,9 +5638,8 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( } default: { - CARBON_FATAL() - << "unexpected declaration in constraint type declaration:\n" - << *m; + CARBON_FATAL( + "unexpected declaration in constraint type declaration:\n{0}", *m); break; } } @@ -5728,7 +5730,7 @@ auto TypeChecker::CheckImplIsComplete(Nonnull iface_type, } else { // Every member function must be declared. std::optional mem_name = GetName(*m); - CARBON_CHECK(mem_name.has_value()) << "unnamed interface member " << *m; + CARBON_CHECK(mem_name.has_value(), "unnamed interface member {0}", *m); std::optional> mem = FindMember(*mem_name, impl_decl->members()); @@ -6129,11 +6131,11 @@ static auto IsValidTypeForAliasTarget(Nonnull type) -> bool { case Value::Kind::AlternativeConstructorValue: case Value::Kind::StringValue: case Value::Kind::UninitializedValue: - CARBON_FATAL() << "type of alias target is not a type: " << *type; + CARBON_FATAL("type of alias target is not a type: {0}", *type); case Value::Kind::AutoType: case Value::Kind::VariableType: - CARBON_FATAL() << "pattern type in alias target: " << *type; + CARBON_FATAL("pattern type in alias target: {0}", *type); case Value::Kind::IntType: case Value::Kind::BoolType: @@ -6291,7 +6293,7 @@ auto TypeChecker::TypeCheckDeclaration( break; } case DeclarationKind::SelfDeclaration: { - CARBON_FATAL() << "Unreachable TypeChecker `Self` declaration"; + CARBON_FATAL("Unreachable TypeChecker `Self` declaration"); } case DeclarationKind::AliasDeclaration: { break; @@ -6418,7 +6420,7 @@ auto TypeChecker::DeclareDeclaration(Nonnull d, } case DeclarationKind::SelfDeclaration: { - CARBON_FATAL() << "Unreachable TypeChecker declare `Self` declaration"; + CARBON_FATAL("Unreachable TypeChecker declare `Self` declaration"); } case DeclarationKind::AliasDeclaration: { @@ -6490,8 +6492,8 @@ auto TypeChecker::CollectMember(Nonnull enclosing_decl, Nonnull member_decl) -> ErrorOr { CARBON_CHECK(isa(enclosing_decl) || - isa(enclosing_decl)) - << "Can't collect members for " << *enclosing_decl; + isa(enclosing_decl), + "Can't collect members for {0}", *enclosing_decl); auto member_name = GetName(*member_decl); if (!member_name.has_value()) { // No need to collect members without a name @@ -6532,7 +6534,7 @@ auto TypeChecker::FindCollectedMembers(Nonnull decl) return it->second; } default: - CARBON_FATAL() << "Can't collect members for " << *decl; + CARBON_FATAL("Can't collect members for {0}", *decl); } } @@ -6585,8 +6587,8 @@ auto TypeChecker::InstantiateImplDeclaration( std::optional> witness; if (auto impl = param->impl_binding()) { auto it = bindings->witnesses().find(*impl); - CARBON_CHECK(it != bindings->witnesses().end()) - << "no witness for generic binding"; + CARBON_CHECK(it != bindings->witnesses().end(), + "no witness for generic binding"); witness = it->second; } new_bindings.Add(clone, value, witness); @@ -6604,8 +6606,8 @@ auto TypeChecker::InstantiateImplDeclaration( // TODO: It's probably not correct to use the top-level impl scope here. It's // not obvious what we should use, though -- which impls are in scope in // template instantiation? - CARBON_CHECK(top_level_impl_scope_) - << "can't perform template instantiation with no top-level scope"; + CARBON_CHECK(top_level_impl_scope_, + "can't perform template instantiation with no top-level scope"); ImplScope scope(*top_level_impl_scope_); // Bring all impls from any checked generic bindings in the template diff --git a/explorer/interpreter/type_utils.cpp b/explorer/interpreter/type_utils.cpp index 2b7d731adc5c..456c57dde94f 100644 --- a/explorer/interpreter/type_utils.cpp +++ b/explorer/interpreter/type_utils.cpp @@ -81,7 +81,7 @@ auto IsType(Nonnull value) -> bool { } auto TypeIsDeduceable(Nonnull type) -> bool { - CARBON_CHECK(IsType(type)) << "expected a type, but found " << *type; + CARBON_CHECK(IsType(type), "expected a type, but found {0}", *type); switch (type->kind()) { case Value::Kind::IntValue: @@ -108,7 +108,7 @@ auto TypeIsDeduceable(Nonnull type) -> bool { case Value::Kind::ParameterizedEntityName: case Value::Kind::MemberName: case Value::Kind::MixinPseudoType: - CARBON_FATAL() << "non-type value"; + CARBON_FATAL("non-type value"); case Value::Kind::IntType: case Value::Kind::BoolType: case Value::Kind::TypeType: diff --git a/explorer/syntax/parse.cpp b/explorer/syntax/parse.cpp index 91882c63ec0a..0a20599a7358 100644 --- a/explorer/syntax/parse.cpp +++ b/explorer/syntax/parse.cpp @@ -36,8 +36,8 @@ static auto ParseImpl(yyscan_t scanner, Nonnull arena, } // Return parse results. - CARBON_CHECK(ast != std::nullopt) - << "parser validated syntax yet didn't produce an AST."; + CARBON_CHECK(ast != std::nullopt, + "parser validated syntax yet didn't produce an AST."); return *ast; } diff --git a/explorer/syntax/prelude.cpp b/explorer/syntax/prelude.cpp index 1ab9cd08194b..d815c0dbf3c6 100644 --- a/explorer/syntax/prelude.cpp +++ b/explorer/syntax/prelude.cpp @@ -19,8 +19,7 @@ void AddPrelude(llvm::vfs::FileSystem& fs, std::string_view prelude_file_name, // Try again with tracing, to help diagnose the problem. ErrorOr trace_parse_result = Parse(fs, arena, prelude_file_name, FileKind::Prelude, true); - CARBON_FATAL() << "Failed to parse prelude:\n" - << trace_parse_result.error(); + CARBON_FATAL("Failed to parse prelude:\n{0}", trace_parse_result.error()); } const auto& prelude = *parse_result; declarations->insert(declarations->begin(), prelude.declarations.begin(), diff --git a/migrate_cpp/rewriter_test.cpp b/migrate_cpp/rewriter_test.cpp index e4dcbb8e76f2..f60569f4cc10 100644 --- a/migrate_cpp/rewriter_test.cpp +++ b/migrate_cpp/rewriter_test.cpp @@ -27,8 +27,8 @@ class Annotations { } start_ = index; end_ = annotated_source.find("]]$", index); - CARBON_CHECK(end_ != llvm::StringRef::npos) - << "Found `$[[` but no matching `]]$`"; + CARBON_CHECK(end_ != llvm::StringRef::npos, + "Found `$[[` but no matching `]]$`"); source_code_ = (llvm::Twine(annotated_source.substr(0, start_)) + annotated_source.substr(start_ + 3, end_ - start_ - 3) + annotated_source.substr(end_ + 3)) diff --git a/testing/base/global_exe_path.cpp b/testing/base/global_exe_path.cpp index ebeb0d99c5c2..1a0349e7156f 100644 --- a/testing/base/global_exe_path.cpp +++ b/testing/base/global_exe_path.cpp @@ -14,13 +14,14 @@ static constinit std::optional exe_path = {}; namespace Carbon::Testing { auto GetExePath() -> llvm::StringRef { - CARBON_CHECK(exe_path) - << "Must not query the executable path until after it has been set!"; + CARBON_CHECK( + exe_path, + "Must not query the executable path until after it has been set!"); return *exe_path; } auto SetExePath(const char* argv_zero) -> void { - CARBON_CHECK(!exe_path) << "Must not call `SetExePath` more than once!"; + CARBON_CHECK(!exe_path, "Must not call `SetExePath` more than once!"); exe_path.emplace(Carbon::FindExecutablePath(argv_zero)); } diff --git a/testing/base/source_gen.cpp b/testing/base/source_gen.cpp index 5fcba45afb08..673225320d81 100644 --- a/testing/base/source_gen.cpp +++ b/testing/base/source_gen.cpp @@ -152,10 +152,11 @@ auto SourceGen::ClassGenState::GetValidTypeName() -> llvm::StringRef { return type_names_.pop_back_val(); } - CARBON_CHECK(last_type_name_index_ != initial_last_type_name_index) - << "Failed to find a valid type name with " << type_names_.size() - << " candidates, an initial index of " << initial_last_type_name_index - << ", and with " << class_names_.size() << " classes left to emit!"; + CARBON_CHECK(last_type_name_index_ != initial_last_type_name_index, + "Failed to find a valid type name with {0} candidates, an " + "initial index of {1}, and with {2} classes left to emit!", + type_names_.size(), initial_last_type_name_index, + class_names_.size()); } } @@ -319,8 +320,8 @@ auto SourceGen::GenAPIFileDenseDecls(int target_lines, // needs a blank line. constexpr int NumFileCommentLines = 4; double avg_class_lines = EstimateAvgClassDefLines(params.class_params); - CARBON_CHECK(target_lines > NumFileCommentLines + avg_class_lines) - << "Not enough target lines to generate a single class!"; + CARBON_CHECK(target_lines > NumFileCommentLines + avg_class_lines, + "Not enough target lines to generate a single class!"); int num_classes = static_cast(target_lines - NumFileCommentLines) / (avg_class_lines + 1); int expected_lines = @@ -372,9 +373,9 @@ auto SourceGen::GetShuffledIdentifiers(int number, int min_length, auto SourceGen::GetShuffledUniqueIdentifiers(int number, int min_length, int max_length, bool uniform) -> llvm::SmallVector { - CARBON_CHECK(min_length >= 4) - << "Cannot trivially guarantee enough distinct, unique identifiers for " - "lengths <= 3"; + CARBON_CHECK(min_length >= 4, + "Cannot trivially guarantee enough distinct, unique identifiers " + "for lengths <= 3"); llvm::SmallVector idents = GetUniqueIdentifiers(number, min_length, max_length, uniform); std::shuffle(idents.begin(), idents.end(), rng_); @@ -398,9 +399,9 @@ auto SourceGen::GetIdentifiers(int number, int min_length, int max_length, auto SourceGen::GetUniqueIdentifiers(int number, int min_length, int max_length, bool uniform) -> llvm::SmallVector { - CARBON_CHECK(min_length >= 4) - << "Cannot trivially guarantee enough distinct, unique identifiers for " - "lengths <= 3"; + CARBON_CHECK(min_length >= 4, + "Cannot trivially guarantee enough distinct, unique identifiers " + "for lengths <= 3"); llvm::SmallVector idents = GetIdentifiersImpl(number, min_length, max_length, uniform, [this](int length, int length_count, @@ -634,10 +635,10 @@ auto SourceGen::GetIdentifiersImpl(int number, int min_length, int max_length, llvm::function_ref append) -> llvm::SmallVector { CARBON_CHECK(min_length <= max_length); - CARBON_CHECK(uniform || max_length <= 64) - << "Cannot produce a meaningful non-uniform distribution of lengths " - "longer than 64 as those are exceedingly rare in our observed data " - "sets."; + CARBON_CHECK( + uniform || max_length <= 64, + "Cannot produce a meaningful non-uniform distribution of lengths longer " + "than 64 as those are exceedingly rare in our observed data sets."); llvm::SmallVector idents; idents.reserve(number); @@ -667,11 +668,10 @@ auto SourceGen::GetIdentifiersImpl(int number, int min_length, int max_length, } append(length, length_count, idents); } - CARBON_CHECK(number_rem == 0) - << "Unexpected number remaining: " << number_rem; - CARBON_CHECK(static_cast(idents.size()) == number) - << "Ended up with " << idents.size() - << " identifiers instead of the requested " << number; + CARBON_CHECK(number_rem == 0, "Unexpected number remaining: {0}", number_rem); + CARBON_CHECK(static_cast(idents.size()) == number, + "Ended up with {0} identifiers instead of the requested {1}", + idents.size(), number); return idents; } diff --git a/testing/file_test/autoupdate.cpp b/testing/file_test/autoupdate.cpp index e5eff253ce21..34b7c50e46a5 100644 --- a/testing/file_test/autoupdate.cpp +++ b/testing/file_test/autoupdate.cpp @@ -21,8 +21,8 @@ static auto ParseLineNumber(absl::string_view matched_line_number) -> int { trimmed = trimmed.trim(); // NOLINTNEXTLINE(google-runtime-int): API requirement. long long val; - CARBON_CHECK(!llvm::getAsSignedInteger(trimmed, 10, val)) - << matched_line_number; + CARBON_CHECK(!llvm::getAsSignedInteger(trimmed, 10, val), "{0}", + matched_line_number); return val; } @@ -60,7 +60,7 @@ auto FileTestAutoupdater::CheckLine::RemapLineNumbers( RE2::PartialMatch(line_cursor, *replacement_->re, &matched_line_number); } if (matched_line_number.empty()) { - CARBON_CHECK(found_one) << line_; + CARBON_CHECK(found_one, "{0}", line_); return; } found_one = true; @@ -195,9 +195,9 @@ auto FileTestAutoupdater::BuildCheckLines(llvm::StringRef output, absl::string_view filename; if (RE2::PartialMatch(line, *default_file_re_, &filename)) { auto it = file_to_number_map.find(filename); - CARBON_CHECK(it != file_to_number_map.end()) - << "default_file_re had unexpected match in '" << line << "' (`" - << default_file_re_->pattern() << "`)"; + CARBON_CHECK(it != file_to_number_map.end(), + "default_file_re had unexpected match in '{0}' (`{1}`)", + line, default_file_re_->pattern()); default_file_number = it->second; } } @@ -218,7 +218,7 @@ auto FileTestAutoupdater::AddRemappedNonCheckLine() -> void { } auto FileTestAutoupdater::AddTips() -> void { - CARBON_CHECK(tips_.empty()) << "Should only add tips once"; + CARBON_CHECK(tips_.empty(), "Should only add tips once"); tips_.reserve(4); // This puts commands on a single line so that they can be easily copied. @@ -278,12 +278,12 @@ auto FileTestAutoupdater::StartSplitFile() -> void { // Advance the file. ++output_file_number_; output_line_number_ = 0; - CARBON_CHECK(output_file_number_ == non_check_line_->file_number()) - << "Non-sequential file: " << non_check_line_->file_number(); + CARBON_CHECK(output_file_number_ == non_check_line_->file_number(), + "Non-sequential file: {0}", non_check_line_->file_number()); // Each following file has precisely one split line. - CARBON_CHECK(non_check_line_->line_number() < 1) - << "Expected a split line, got " << *non_check_line_; + CARBON_CHECK(non_check_line_->line_number() < 1, + "Expected a split line, got {0}", *non_check_line_); // The split line is ignored when calculating line counts. new_lines_.push_back(non_check_line_); @@ -300,8 +300,8 @@ auto FileTestAutoupdater::Run(bool dry_run) -> bool { // Print everything until the autoupdate line. while (non_check_line_->line_number() != autoupdate_line_number_) { CARBON_CHECK(non_check_line_ != non_check_lines_.end() && - non_check_line_->file_number() == 0) - << "Missed autoupdate?"; + non_check_line_->file_number() == 0, + "Missed autoupdate?"); AddRemappedNonCheckLine(); ++non_check_line_; } diff --git a/testing/file_test/autoupdate.h b/testing/file_test/autoupdate.h index 4c5d00f1746a..15ad07c769f4 100644 --- a/testing/file_test/autoupdate.h +++ b/testing/file_test/autoupdate.h @@ -62,11 +62,12 @@ class FileTestAutoupdater { [&](const CheckLine& line) { return line.line_number() != -1; })), non_check_line_(non_check_lines_.begin()) { for (const auto& replacement : line_number_replacements_) { - CARBON_CHECK(replacement.has_file || default_file_re_) - << "For replacement with pattern `" << replacement.re->pattern() - << "` to have has_file=false, override GetDefaultFileRE."; - CARBON_CHECK(replacement.re->ok()) - << "Invalid line replacement RE2: " << replacement.re->error(); + CARBON_CHECK(replacement.has_file || default_file_re_, + "For replacement with pattern `{0}` to have has_file=false, " + "override GetDefaultFileRE.", + replacement.re->pattern()); + CARBON_CHECK(replacement.re->ok(), "Invalid line replacement RE2: {0}", + replacement.re->error()); } } diff --git a/testing/file_test/file_test_base.cpp b/testing/file_test/file_test_base.cpp index d6777b483e7b..a12588eb525d 100644 --- a/testing/file_test/file_test_base.cpp +++ b/testing/file_test/file_test_base.cpp @@ -900,10 +900,10 @@ static auto GetTests() -> llvm::SmallVector { } // Extracts tests from the target file. - CARBON_CHECK(!absl::GetFlag(FLAGS_test_targets_file).empty()) - << "Missing --test_targets_file."; + CARBON_CHECK(!absl::GetFlag(FLAGS_test_targets_file).empty(), + "Missing --test_targets_file."); auto content = ReadFile(absl::GetFlag(FLAGS_test_targets_file)); - CARBON_CHECK(content.ok()) << content.error(); + CARBON_CHECK(content.ok(), "{0}", content.error()); llvm::SmallVector all_tests; for (llvm::StringRef file_ref : llvm::split(*content, "\n")) { if (file_ref.empty()) { diff --git a/toolchain/base/value_store.h b/toolchain/base/value_store.h index 5c0a5c1e209e..31c7008a26e5 100644 --- a/toolchain/base/value_store.h +++ b/toolchain/base/value_store.h @@ -151,7 +151,7 @@ class ValueStore // Stores the value and returns an ID to reference it. auto Add(ValueType value) -> IdT { IdT id(values_.size()); - CARBON_CHECK(id.index >= 0) << "Id overflow"; + CARBON_CHECK(id.index >= 0, "Id overflow"); values_.push_back(std::move(value)); return id; } @@ -165,13 +165,13 @@ class ValueStore // Returns a mutable value for an ID. auto Get(IdT id) -> RefType { - CARBON_DCHECK(id.index >= 0) << id; + CARBON_DCHECK(id.index >= 0, "{0}", id); return values_[id.index]; } // Returns the value for an ID. auto Get(IdT id) const -> ConstRefType { - CARBON_DCHECK(id.index >= 0) << id; + CARBON_DCHECK(id.index >= 0, "{0}", id); return values_[id.index]; } diff --git a/toolchain/base/yaml.h b/toolchain/base/yaml.h index 86496836a4d9..0e4997970366 100644 --- a/toolchain/base/yaml.h +++ b/toolchain/base/yaml.h @@ -94,7 +94,7 @@ struct llvm::yaml::ScalarTraits { } static auto input(StringRef /*scalar*/, void* /*ctxt*/, Carbon::Yaml::OutputScalar& /*value*/) -> StringRef { - CARBON_FATAL() << "Input is unsupported."; + CARBON_FATAL("Input is unsupported."); } static auto mustQuote(StringRef /*value*/) -> QuotingType { return QuotingType::None; diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index 0aede2417540..2d25b0a263a3 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -555,8 +555,8 @@ class DeferredDefinitionWorklist { // CHECK that the work list has no further work. auto VerifyEmpty() { - CARBON_CHECK(worklist_.empty() && entered_scopes_.empty()) - << "Tasks left behind on worklist."; + CARBON_CHECK(worklist_.empty() && entered_scopes_.empty(), + "Tasks left behind on worklist."); } private: @@ -627,8 +627,8 @@ auto DeferredDefinitionWorklist::SuspendFinishedScopeAndPush(Context& context) // worklist. We stay in that scope rather than suspending then immediately // resuming it. CARBON_CHECK( - holds_alternative(worklist_.back())) - << "Unexpected task in worklist."; + holds_alternative(worklist_.back()), + "Unexpected task in worklist."); worklist_.pop_back(); CARBON_VLOG("{0}Handle EnterDeferredDefinitionScope (non-nested)\n", VlogPrefix); @@ -690,8 +690,8 @@ class NodeIdTraversal { auto PerformTask( DeferredDefinitionWorklist::EnterDeferredDefinitionScope&& enter) -> void { - CARBON_CHECK(enter.suspended_name) - << "Entering a scope with no suspension information."; + CARBON_CHECK(enter.suspended_name, + "Entering a scope with no suspension information."); context_.decl_name_stack().Restore(std::move(*enter.suspended_name)); } @@ -815,12 +815,10 @@ static auto DiagnoseMissingDefinitions(Context& context, case SemIR::InterfaceDecl::Kind: { // TODO: handle `interface` as well, once we can test it without // triggering https://github.com/carbon-language/carbon-lang/issues/4071 - CARBON_FATAL() - << "TODO: Support interfaces in DiagnoseMissingDefinitions"; + CARBON_FATAL("TODO: Support interfaces in DiagnoseMissingDefinitions"); } default: { - CARBON_FATAL() << "Unexpected inst in definitions_required: " - << decl_inst; + CARBON_FATAL("Unexpected inst in definitions_required: {0}", decl_inst); } } } @@ -851,14 +849,15 @@ static auto ProcessNodeIds(Context& context, llvm::raw_ostream* vlog_stream, auto parse_kind = context.parse_tree().node_kind(node_id); switch (parse_kind) { -#define CARBON_PARSE_NODE_KIND(Name) \ - case Parse::NodeKind::Name: { \ - if (!HandleParseNode(context, Parse::Name##Id(node_id))) { \ - CARBON_CHECK(err_tracker.seen_error()) \ - << "Handle" #Name " returned false without printing a diagnostic"; \ - return false; \ - } \ - break; \ +#define CARBON_PARSE_NODE_KIND(Name) \ + case Parse::NodeKind::Name: { \ + if (!HandleParseNode(context, Parse::Name##Id(node_id))) { \ + CARBON_CHECK(err_tracker.seen_error(), \ + "Handle" #Name \ + " returned false without printing a diagnostic"); \ + return false; \ + } \ + break; \ } #include "toolchain/parse/node_kind.def" } @@ -919,8 +918,8 @@ static auto CheckParseTree( #ifndef NDEBUG if (auto verify = sem_ir.Verify(); !verify.ok()) { - CARBON_FATAL() << sem_ir << "Built invalid semantics IR: " << verify.error() - << "\n"; + CARBON_FATAL("{0}Built invalid semantics IR: {1}\n", sem_ir, + verify.error()); } #endif } diff --git a/toolchain/check/check_fuzzer.cpp b/toolchain/check/check_fuzzer.cpp index fd435f80bc66..0921c901c344 100644 --- a/toolchain/check/check_fuzzer.cpp +++ b/toolchain/check/check_fuzzer.cpp @@ -15,7 +15,7 @@ static const InstallPaths* install_paths = nullptr; // NOLINTNEXTLINE(readability-non-const-parameter): External API required types. extern "C" auto LLVMFuzzerInitialize(int* argc, char*** argv) -> int { - CARBON_CHECK(*argc >= 1) << "Need the `argv[0]` value to initialize!"; + CARBON_CHECK(*argc >= 1, "Need the `argv[0]` value to initialize!"); install_paths = new InstallPaths( InstallPaths::MakeForBazelRunfiles(FindExecutablePath((*argv)[0]))); return 0; diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index f706aa19ef95..0d8e8e191c45 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -142,9 +142,10 @@ auto Context::CheckCompatibleImportedNodeKind( auto& import_ir_inst = import_ir_insts().Get(imported_loc_id); const auto* import_ir = import_irs().Get(import_ir_inst.ir_id).sem_ir; auto imported_kind = import_ir->insts().Get(import_ir_inst.inst_id).kind(); - CARBON_CHECK(HasCompatibleImportedNodeKind(imported_kind, kind)) - << "Node of kind " << kind - << " created with location of imported node of kind " << imported_kind; + CARBON_CHECK( + HasCompatibleImportedNodeKind(imported_kind, kind), + "Node of kind {0} created with location of imported node of kind {1}", + kind, imported_kind); } auto Context::AddInstInNoBlock(SemIR::LocIdAndInst loc_id_and_inst) @@ -218,7 +219,7 @@ auto Context::DiagnoseNameNotFound(SemIRLoc loc, SemIR::NameId name_id) auto Context::NoteIncompleteClass(SemIR::ClassId class_id, DiagnosticBuilder& builder) -> void { const auto& class_info = classes().Get(class_id); - CARBON_CHECK(!class_info.is_defined()) << "Class is not incomplete"; + CARBON_CHECK(!class_info.is_defined(), "Class is not incomplete"); if (class_info.definition_id.is_valid()) { CARBON_DIAGNOSTIC(ClassIncompleteWithinDefinition, Note, "Class is incomplete within its definition."); @@ -233,7 +234,7 @@ auto Context::NoteIncompleteClass(SemIR::ClassId class_id, auto Context::NoteUndefinedInterface(SemIR::InterfaceId interface_id, DiagnosticBuilder& builder) -> void { const auto& interface_info = interfaces().Get(interface_id); - CARBON_CHECK(!interface_info.is_defined()) << "Interface is not incomplete"; + CARBON_CHECK(!interface_info.is_defined(), "Interface is not incomplete"); if (interface_info.is_being_defined()) { CARBON_DIAGNOSTIC(InterfaceUndefinedWithinDefinition, Note, "Interface is currently being defined."); @@ -389,7 +390,7 @@ static auto DiagnoseInvalidQualifiedNameAccess(Context& context, SemIRLoc loc, class_info.adapt_id)) { parent_type_id = adapt_decl->adapted_type_id; } else { - CARBON_FATAL() << "Expected parent for parent access"; + CARBON_FATAL("Expected parent for parent access"); } } @@ -615,7 +616,7 @@ auto Context::AddDominatedBlockAndBranchIf(Parse::NodeId node_id, auto Context::AddConvergenceBlockAndPush(Parse::NodeId node_id, int num_blocks) -> void { - CARBON_CHECK(num_blocks >= 2) << "no convergence"; + CARBON_CHECK(num_blocks >= 2, "no convergence"); SemIR::InstBlockId new_block_id = SemIR::InstBlockId::Unreachable; for ([[maybe_unused]] auto _ : llvm::seq(num_blocks)) { @@ -633,7 +634,7 @@ auto Context::AddConvergenceBlockAndPush(Parse::NodeId node_id, int num_blocks) auto Context::AddConvergenceBlockWithArgAndPush( Parse::NodeId node_id, std::initializer_list block_args) -> SemIR::InstId { - CARBON_CHECK(block_args.size() >= 2) << "no convergence"; + CARBON_CHECK(block_args.size() >= 2, "no convergence"); SemIR::InstBlockId new_block_id = SemIR::InstBlockId::Unreachable; for (auto arg_id : block_args) { @@ -671,8 +672,8 @@ auto Context::SetBlockArgResultBeforeConstantUse(SemIR::InstId select_id, const_id = constant_values().Get(literal.value().value.ToBool() ? if_true : if_false); } else { - CARBON_CHECK(cond_const_id == SemIR::ConstantId::Error) - << "Unexpected constant branch condition."; + CARBON_CHECK(cond_const_id == SemIR::ConstantId::Error, + "Unexpected constant branch condition."); const_id = SemIR::ConstantId::Error; } @@ -684,11 +685,11 @@ auto Context::SetBlockArgResultBeforeConstantUse(SemIR::InstId select_id, } auto Context::AddCurrentCodeBlockToFunction(Parse::NodeId node_id) -> void { - CARBON_CHECK(!inst_block_stack().empty()) << "no current code block"; + CARBON_CHECK(!inst_block_stack().empty(), "no current code block"); if (return_scope_stack().empty()) { - CARBON_CHECK(node_id.is_valid()) - << "No current function, but node_id not provided"; + CARBON_CHECK(node_id.is_valid(), + "No current function, but node_id not provided"); TODO(node_id, "Control flow expressions are currently only supported inside " "functions."); @@ -798,16 +799,16 @@ class TypeCompleter { if (!AddNestedIncompleteTypes(inst)) { return false; } - CARBON_CHECK(work_list_.size() >= old_work_list_size) - << "AddNestedIncompleteTypes should not remove work items"; + CARBON_CHECK(work_list_.size() >= old_work_list_size, + "AddNestedIncompleteTypes should not remove work items"); work_list_[old_work_list_size - 1].phase = Phase::BuildValueRepr; break; case Phase::BuildValueRepr: { auto value_rep = BuildValueRepr(type_id, inst); context_.types().SetValueRepr(type_id, value_rep); - CARBON_CHECK(old_work_list_size == work_list_.size()) - << "BuildValueRepr should not change work items"; + CARBON_CHECK(old_work_list_size == work_list_.size(), + "BuildValueRepr should not change work items"); work_list_.pop_back(); // Also complete the value representation type, if necessary. This @@ -919,11 +920,11 @@ class TypeCompleter { // Gets the value representation of a nested type, which should already be // complete. auto GetNestedValueRepr(SemIR::TypeId nested_type_id) const { - CARBON_CHECK(context_.types().IsComplete(nested_type_id)) - << "Nested type should already be complete"; + CARBON_CHECK(context_.types().IsComplete(nested_type_id), + "Nested type should already be complete"); auto value_rep = context_.types().GetValueRepr(nested_type_id); - CARBON_CHECK(value_rep.kind != SemIR::ValueRepr::Unknown) - << "Complete type should have a value representation"; + CARBON_CHECK(value_rep.kind != SemIR::ValueRepr::Unknown, + "Complete type should have a value representation"); return value_rep; } @@ -1105,7 +1106,7 @@ class TypeCompleter { requires(InstT::Kind.is_type() == SemIR::InstIsType::Never) auto BuildValueReprForInst(SemIR::TypeId /*type_id*/, InstT inst) const -> SemIR::ValueRepr { - CARBON_FATAL() << "Type refers to non-type inst " << inst; + CARBON_FATAL("Type refers to non-type inst {0}", inst); } // Builds and returns the value representation for the given type. All nested @@ -1173,16 +1174,16 @@ auto Context::TryToDefineType(SemIR::TypeId type_id, auto Context::GetTypeIdForTypeConstant(SemIR::ConstantId constant_id) -> SemIR::TypeId { - CARBON_CHECK(constant_id.is_constant()) - << "Canonicalizing non-constant type: " << constant_id; + CARBON_CHECK(constant_id.is_constant(), + "Canonicalizing non-constant type: {0}", constant_id); auto type_id = insts().Get(constant_values().GetInstId(constant_id)).type_id(); // TODO: For now, we allow values of facet type to be used as types. CARBON_CHECK(type_id == SemIR::TypeId::TypeType || - types().Is(type_id) || - constant_id == SemIR::ConstantId::Error) - << "Forming type ID for non-type constant of type " - << types().GetAsInst(type_id); + types().Is(type_id) || + constant_id == SemIR::ConstantId::Error, + "Forming type ID for non-type constant of type {0}", + types().GetAsInst(type_id)); return SemIR::TypeId::ForTypeConstant(constant_id); } @@ -1205,7 +1206,7 @@ static auto GetCompleteTypeImpl(Context& context, EachArgT... each_arg) -> SemIR::TypeId { auto type_id = GetTypeImpl(context, each_arg...); bool complete = context.TryToCompleteType(type_id); - CARBON_CHECK(complete) << "Type completion should not fail"; + CARBON_CHECK(complete, "Type completion should not fail"); return type_id; } @@ -1231,7 +1232,7 @@ auto Context::GetBuiltinType(SemIR::BuiltinInstKind kind) -> SemIR::TypeId { auto type_id = GetTypeIdForTypeInst(SemIR::InstId::ForBuiltin(kind)); // To keep client code simpler, complete builtin types before returning them. bool complete = TryToCompleteType(type_id); - CARBON_CHECK(complete) << "Failed to complete builtin type"; + CARBON_CHECK(complete, "Failed to complete builtin type"); return type_id; } diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 0ad0c2752475..557846d796c5 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -363,8 +363,7 @@ class Context { // Sets the total number of IRs which exist. This is used to prepare a map // from IR to imported IR. auto SetTotalIRCount(int num_irs) -> void { - CARBON_CHECK(check_ir_map_.empty()) - << "SetTotalIRCount is only called once"; + CARBON_CHECK(check_ir_map_.empty(), "SetTotalIRCount is only called once"); check_ir_map_.resize(num_irs, SemIR::ImportIRId::Invalid); } diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 4351885df105..37e7f85277f9 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -66,8 +66,7 @@ static auto FindReturnSlotForInitializer(SemIR::File& sem_ir, return sem_ir.inst_blocks().Get(call.args_id).back(); } default: - CARBON_FATAL() << "Initialization from unexpected inst " - << init_untyped; + CARBON_FATAL("Initialization from unexpected inst {0}", init_untyped); } } } @@ -80,10 +79,10 @@ static auto MarkInitializerFor(SemIR::File& sem_ir, SemIR::InstId init_id, if (return_slot_id.is_valid()) { // Replace the temporary in the return slot with a reference to our target. CARBON_CHECK(sem_ir.insts().Get(return_slot_id).kind() == - SemIR::TemporaryStorage::Kind) - << "Return slot for initializer does not contain a temporary; " - << "initialized multiple times? Have " - << sem_ir.insts().Get(return_slot_id); + SemIR::TemporaryStorage::Kind, + "Return slot for initializer does not contain a temporary; " + "initialized multiple times? Have {0}", + sem_ir.insts().Get(return_slot_id)); target_block.MergeReplacing(return_slot_id, target_id); } } @@ -100,10 +99,10 @@ static auto FinalizeTemporary(Context& context, SemIR::InstId init_id, if (return_slot_id.is_valid()) { // The return slot should already have a materialized temporary in it. CARBON_CHECK(sem_ir.insts().Get(return_slot_id).kind() == - SemIR::TemporaryStorage::Kind) - << "Return slot for initializer does not contain a temporary; " - << "initialized multiple times? Have " - << sem_ir.insts().Get(return_slot_id); + SemIR::TemporaryStorage::Kind, + "Return slot for initializer does not contain a temporary; " + "initialized multiple times? Have {0}", + sem_ir.insts().Get(return_slot_id)); auto init = sem_ir.insts().Get(init_id); return context.AddInst(sem_ir.insts().GetLocId(init_id), {.type_id = init.type_id(), @@ -423,8 +422,7 @@ static auto ConvertStructToStructOrClass(Context& context, for (auto [i, field_id] : llvm::enumerate(src_elem_fields)) { auto result = src_field_indexes.Insert( context.insts().GetAs(field_id).name_id, i); - CARBON_CHECK(result.is_inserted()) - << "Duplicate field in source structure"; + CARBON_CHECK(result.is_inserted(), "Duplicate field in source structure"); } } @@ -496,8 +494,8 @@ static auto ConvertStructToStructOrClass(Context& context, if (is_class) { target.init_block->InsertHere(); - CARBON_CHECK(is_init) - << "Converting directly to a class value is not supported"; + CARBON_CHECK(is_init, + "Converting directly to a class value is not supported"); return context.AddInst(value_loc_id, {.type_id = target.type_id, .elements_id = new_block.id(), @@ -1004,8 +1002,7 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, switch (SemIR::GetExprCategory(sem_ir, expr_id)) { case SemIR::ExprCategory::NotExpr: case SemIR::ExprCategory::Mixed: - CARBON_FATAL() << "Unexpected expression " << expr - << " after builtin conversions"; + CARBON_FATAL("Unexpected expression {0} after builtin conversions", expr); case SemIR::ExprCategory::Error: return SemIR::InstId::BuiltinError; diff --git a/toolchain/check/decl_introducer_state.h b/toolchain/check/decl_introducer_state.h index 193223a5126c..6e4e3728c593 100644 --- a/toolchain/check/decl_introducer_state.h +++ b/toolchain/check/decl_introducer_state.h @@ -74,9 +74,8 @@ class DeclIntroducerStateStack { template requires(IsDeclIntroducer()) auto Pop() -> DeclIntroducerState { - CARBON_CHECK(stack_.back().kind == Kind) - << "Found: " << stack_.back().kind - << " expected: " << Lex::TokenKind::Make(Kind); + CARBON_CHECK(stack_.back().kind == Kind, "Found: {0} expected: {1}", + stack_.back().kind, Lex::TokenKind::Make(Kind)); return stack_.pop_back_val(); } diff --git a/toolchain/check/decl_name_stack.cpp b/toolchain/check/decl_name_stack.cpp index 1bff4f3398e7..cb8eeeed51dd 100644 --- a/toolchain/check/decl_name_stack.cpp +++ b/toolchain/check/decl_name_stack.cpp @@ -23,9 +23,9 @@ auto DeclNameStack::NameContext::prev_inst_id() -> SemIR::InstId { return SemIR::InstId::Invalid; case NameContext::State::Empty: - CARBON_FATAL() - << "Name is missing, not expected to call existing_inst_id (but " - "that may change based on error handling)."; + CARBON_FATAL( + "Name is missing, not expected to call existing_inst_id (but that " + "may change based on error handling)."); case NameContext::State::Resolved: return resolved_inst_id; @@ -34,7 +34,7 @@ auto DeclNameStack::NameContext::prev_inst_id() -> SemIR::InstId { return SemIR::InstId::Invalid; case NameContext::State::Finished: - CARBON_FATAL() << "Finished state should only be used internally"; + CARBON_FATAL("Finished state should only be used internally"); } } @@ -59,8 +59,8 @@ auto DeclNameStack::PushScopeAndStartName() -> void { } auto DeclNameStack::FinishName(const NameComponent& name) -> NameContext { - CARBON_CHECK(decl_name_stack_.back().state != NameContext::State::Finished) - << "Finished name twice"; + CARBON_CHECK(decl_name_stack_.back().state != NameContext::State::Finished, + "Finished name twice"); ApplyAndLookupName(decl_name_stack_.back(), name.name_loc_id, name.name_id); @@ -70,8 +70,8 @@ auto DeclNameStack::FinishName(const NameComponent& name) -> NameContext { } auto DeclNameStack::FinishImplName() -> NameContext { - CARBON_CHECK(decl_name_stack_.back().state == NameContext::State::Empty) - << "Impl has a name"; + CARBON_CHECK(decl_name_stack_.back().state == NameContext::State::Empty, + "Impl has a name"); NameContext result = decl_name_stack_.back(); decl_name_stack_.back().state = NameContext::State::Finished; @@ -79,15 +79,15 @@ auto DeclNameStack::FinishImplName() -> NameContext { } auto DeclNameStack::PopScope() -> void { - CARBON_CHECK(decl_name_stack_.back().state == NameContext::State::Finished) - << "Missing call to FinishName before PopScope"; + CARBON_CHECK(decl_name_stack_.back().state == NameContext::State::Finished, + "Missing call to FinishName before PopScope"); context_->scope_stack().PopTo(decl_name_stack_.back().initial_scope_index); decl_name_stack_.pop_back(); } auto DeclNameStack::Suspend() -> SuspendedName { - CARBON_CHECK(decl_name_stack_.back().state == NameContext::State::Finished) - << "Missing call to FinishName before Suspend"; + CARBON_CHECK(decl_name_stack_.back().state == NameContext::State::Finished, + "Missing call to FinishName before Suspend"); SuspendedName result = {.name_context = decl_name_stack_.pop_back_val(), .scopes = {}}; auto scope_index = result.name_context.initial_scope_index; @@ -95,17 +95,17 @@ auto DeclNameStack::Suspend() -> SuspendedName { while (scope_stack.PeekIndex() > scope_index) { result.scopes.push_back(scope_stack.Suspend()); } - CARBON_CHECK(scope_stack.PeekIndex() == scope_index) - << "Scope index " << scope_index << " does not enclose the current scope " - << scope_stack.PeekIndex(); + CARBON_CHECK(scope_stack.PeekIndex() == scope_index, + "Scope index {0} does not enclose the current scope {1}", + scope_index, scope_stack.PeekIndex()); return result; } auto DeclNameStack::Restore(SuspendedName sus) -> void { // The parent state must be the same when a name is restored. CARBON_CHECK(context_->scope_stack().PeekIndex() == - sus.name_context.initial_scope_index) - << "Name restored at the wrong position in the name stack."; + sus.name_context.initial_scope_index, + "Name restored at the wrong position in the name stack."); // clang-tidy warns that the `std::move` below has no effect. While that's // true, this `move` defends against `NameContext` growing more state later. @@ -164,15 +164,15 @@ auto DeclNameStack::AddName(NameContext name_context, SemIR::InstId target_id, }; auto result = name_scope.name_map.Insert( name_context.unresolved_name_id, add_scope); - CARBON_CHECK(result.is_inserted()) - << "Duplicate names should have been resolved previously: " - << name_context.unresolved_name_id << " in " - << name_context.parent_scope_id; + CARBON_CHECK( + result.is_inserted(), + "Duplicate names should have been resolved previously: {0} in {1}", + name_context.unresolved_name_id, name_context.parent_scope_id); } break; default: - CARBON_FATAL() << "Should not be calling AddName"; + CARBON_FATAL("Should not be calling AddName"); break; } } @@ -284,7 +284,7 @@ static auto CheckQualifierIsResolved( Context& context, const DeclNameStack::NameContext& name_context) -> bool { switch (name_context.state) { case DeclNameStack::NameContext::State::Empty: - CARBON_FATAL() << "No qualifier to resolve"; + CARBON_FATAL("No qualifier to resolve"); case DeclNameStack::NameContext::State::Resolved: return true; @@ -297,7 +297,7 @@ static auto CheckQualifierIsResolved( return false; case DeclNameStack::NameContext::State::Finished: - CARBON_FATAL() << "Added a qualifier after calling FinishName"; + CARBON_FATAL("Added a qualifier after calling FinishName"); case DeclNameStack::NameContext::State::Error: // Already in an error state, so return without examining. diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index e2887d4557af..44ac3c8c1f52 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -156,10 +156,10 @@ auto DeduceGenericCallArguments( auto& entity_name = context.entity_names().Get(bind.entity_name_id); auto index = entity_name.bind_index; if (index.is_valid() && index >= first_deduced_index) { - CARBON_CHECK(static_cast(index.index) < result_arg_ids.size()) - << "Deduced value for unexpected index " << index - << "; expected to deduce " << result_arg_ids.size() - << " arguments."; + CARBON_CHECK(static_cast(index.index) < result_arg_ids.size(), + "Deduced value for unexpected index {0}; expected to " + "deduce {1} arguments.", + index, result_arg_ids.size()); auto arg_const_inst_id = context.constant_values().GetConstantInstId(arg_id); if (arg_const_inst_id.is_valid()) { diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index c48bc18b05e0..6b1d6e41be54 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -77,9 +77,10 @@ class EvalContext { specifics().Get(specific_id_).generic_id && symbolic_info.index.region() == specific_eval_info_->region) { auto inst_id = specific_eval_info_->values[symbolic_info.index.index()]; - CARBON_CHECK(inst_id.is_valid()) - << "Forward reference in eval block: index " - << symbolic_info.index.index() << " referenced before evaluation"; + CARBON_CHECK(inst_id.is_valid(), + "Forward reference in eval block: index {0} referenced " + "before evaluation", + symbolic_info.index.index()); return constant_values().Get(inst_id); } } @@ -464,14 +465,14 @@ static auto PerformAggregateAccess(EvalContext& eval_context, SemIR::Inst inst) aggregate_id)) { auto elements = eval_context.inst_blocks().Get(aggregate->elements_id); auto index = static_cast(access_inst.index.index); - CARBON_CHECK(index < elements.size()) << "Access out of bounds."; + CARBON_CHECK(index < elements.size(), "Access out of bounds."); // `Phase` is not used here. If this element is a template constant, then // so is the result of indexing, even if the aggregate also contains a // symbolic context. return eval_context.GetConstantValue(elements[index]); } else { - CARBON_CHECK(phase != Phase::Template) - << "Failed to evaluate template constant " << inst; + CARBON_CHECK(phase != Phase::Template, + "Failed to evaluate template constant {0}", inst); } } return MakeNonConstantResult(phase); @@ -490,8 +491,8 @@ static auto PerformAggregateIndex(EvalContext& eval_context, SemIR::Inst inst) } auto index = eval_context.insts().TryGetAs(index_id); if (!index) { - CARBON_CHECK(phase != Phase::Template) - << "Template constant integer should be a literal"; + CARBON_CHECK(phase != Phase::Template, + "Template constant integer should be a literal"); return MakeNonConstantResult(phase); } @@ -529,15 +530,15 @@ static auto PerformAggregateIndex(EvalContext& eval_context, SemIR::Inst inst) auto aggregate = eval_context.insts().TryGetAs(aggregate_id); if (!aggregate) { - CARBON_CHECK(phase != Phase::Template) - << "Unexpected representation for template constant aggregate"; + CARBON_CHECK(phase != Phase::Template, + "Unexpected representation for template constant aggregate"); return MakeNonConstantResult(phase); } auto elements = eval_context.inst_blocks().Get(aggregate->elements_id); // We checked this for the array case above. - CARBON_CHECK(index_val.ult(elements.size())) - << "Index out of bounds in tuple indexing"; + CARBON_CHECK(index_val.ult(elements.size()), + "Index out of bounds in tuple indexing"); return eval_context.GetConstantValue(elements[index_val.getZExtValue()]); } @@ -649,7 +650,7 @@ static auto PerformBuiltinUnaryIntOp(Context& context, SemIRLoc loc, op_val.flipAllBits(); break; default: - CARBON_FATAL() << "Unexpected builtin kind"; + CARBON_FATAL("Unexpected builtin kind"); } return MakeIntResult(context, op.type_id, std::move(op_val)); @@ -774,7 +775,7 @@ static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc, break; default: - CARBON_FATAL() << "Unexpected operation kind."; + CARBON_FATAL("Unexpected operation kind."); } if (overflow) { @@ -823,7 +824,7 @@ static auto PerformBuiltinIntComparison(Context& context, result = is_signed ? lhs_val.sge(rhs_val) : lhs_val.sge(rhs_val); break; default: - CARBON_FATAL() << "Unexpected operation kind."; + CARBON_FATAL("Unexpected operation kind."); } return MakeBoolResult(context, bool_type_id, result); @@ -842,7 +843,7 @@ static auto PerformBuiltinUnaryFloatOp(Context& context, op_val.changeSign(); break; default: - CARBON_FATAL() << "Unexpected builtin kind"; + CARBON_FATAL("Unexpected builtin kind"); } return MakeFloatResult(context, op.type_id, std::move(op_val)); @@ -875,7 +876,7 @@ static auto PerformBuiltinBinaryFloatOp(Context& context, result_val = lhs_val / rhs_val; break; default: - CARBON_FATAL() << "Unexpected operation kind."; + CARBON_FATAL("Unexpected operation kind."); } return MakeFloatResult(context, lhs.type_id, std::move(result_val)); @@ -912,7 +913,7 @@ static auto PerformBuiltinFloatComparison( result = lhs_val >= rhs_val; break; default: - CARBON_FATAL() << "Unexpected operation kind."; + CARBON_FATAL("Unexpected operation kind."); } return MakeBoolResult(context, bool_type_id, result); @@ -926,7 +927,7 @@ static auto MakeConstantForBuiltinCall(Context& context, SemIRLoc loc, Phase phase) -> SemIR::ConstantId { switch (builtin_kind) { case SemIR::BuiltinFunctionKind::None: - CARBON_FATAL() << "Not a builtin function."; + CARBON_FATAL("Not a builtin function."); case SemIR::BuiltinFunctionKind::PrintInt: { // Providing a constant result would allow eliding the function call. @@ -1483,8 +1484,8 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id, break; case SemIR::ImportRefUnloaded::Kind: - CARBON_FATAL() - << "ImportRefUnloaded should be loaded before TryEvalInst: " << inst; + CARBON_FATAL("ImportRefUnloaded should be loaded before TryEvalInst: {0}", + inst); } return SemIR::ConstantId::NotConstant; } diff --git a/toolchain/check/generic.cpp b/toolchain/check/generic.cpp index 594b8d558209..5ef082aa7c4a 100644 --- a/toolchain/check/generic.cpp +++ b/toolchain/check/generic.cpp @@ -73,9 +73,10 @@ class RebuildGenericConstantInEvalBlockCallbacks final if (!const_id.is_valid()) { // An unloaded import ref should never contain anything we need to // substitute into. Don't trigger loading it here. - CARBON_CHECK(context_.insts().Is(inst_id)) - << "Substituting into instruction with invalid constant ID: " - << context_.insts().Get(inst_id); + CARBON_CHECK( + context_.insts().Is(inst_id), + "Substituting into instruction with invalid constant ID: {0}", + context_.insts().Get(inst_id)); return true; } if (!const_id.is_symbolic()) { @@ -174,9 +175,9 @@ static auto AddGenericConstantToEvalBlock( SubstInst(context, const_inst_id, RebuildGenericConstantInEvalBlockCallbacks( context, generic_id, region, constants_in_generic)); - CARBON_CHECK(new_inst_id != const_inst_id) - << "Did not apply any substitutions to symbolic constant " - << context.insts().Get(const_inst_id); + CARBON_CHECK(new_inst_id != const_inst_id, + "Did not apply any substitutions to symbolic constant {0}", + context.insts().Get(const_inst_id)); return context.constant_values().Get(new_inst_id); } @@ -192,9 +193,9 @@ static auto PopulateConstantsFromDeclaration( for (auto inst_id : decl_eval_block) { auto const_inst_id = context.constant_values().GetConstantInstId(inst_id); auto result = constants_in_generic.Insert(const_inst_id, inst_id); - CARBON_CHECK(result.is_inserted()) - << "Duplicate constant in generic decl eval block: " - << context.insts().Get(const_inst_id); + CARBON_CHECK(result.is_inserted(), + "Duplicate constant in generic decl eval block: {0}", + context.insts().Get(const_inst_id)); } } @@ -252,12 +253,13 @@ static auto MakeGenericEvalBlock(Context& context, SemIR::GenericId generic_id, } } - CARBON_CHECK(num_dependent_insts == - context.generic_region_stack().PeekDependentInsts().size()) - << "Building eval block added new dependent insts, for example " - << context.insts().Get(context.generic_region_stack() - .PeekDependentInsts()[num_dependent_insts] - .inst_id); + CARBON_CHECK( + num_dependent_insts == + context.generic_region_stack().PeekDependentInsts().size(), + "Building eval block added new dependent insts, for example {0}", + context.insts().Get(context.generic_region_stack() + .PeekDependentInsts()[num_dependent_insts] + .inst_id)); return context.inst_block_stack().Pop(); } @@ -283,11 +285,11 @@ auto RebuildGenericEvalBlock(Context& context, SemIR::GenericId generic_id, // Build a constant in the inst block. AddGenericConstantToEvalBlock(context, generic_id, region, constants_in_generic, inst_id); - CARBON_CHECK(context.inst_block_stack().PeekCurrentBlockContents().size() == - i + 1) - << "Produced " - << (context.inst_block_stack().PeekCurrentBlockContents().size() - i) - << " instructions when importing " << context.insts().Get(inst_id); + CARBON_CHECK( + context.inst_block_stack().PeekCurrentBlockContents().size() == i + 1, + "Produced {0} instructions when importing {1}", + (context.inst_block_stack().PeekCurrentBlockContents().size() - i), + context.insts().Get(inst_id)); } return context.inst_block_stack().Pop(); @@ -299,9 +301,9 @@ auto FinishGenericDecl(Context& context, SemIR::InstId decl_id) context.scope_stack().compile_time_bindings_stack().PeekAllValues(); if (all_bindings.empty()) { - CARBON_CHECK(context.generic_region_stack().PeekDependentInsts().empty()) - << "Have dependent instructions but no compile time bindings are in " - "scope."; + CARBON_CHECK(context.generic_region_stack().PeekDependentInsts().empty(), + "Have dependent instructions but no compile time bindings are " + "in scope."); context.generic_region_stack().Pop(); return SemIR::GenericId::Invalid; } @@ -396,7 +398,7 @@ auto ResolveSpecificDefinition(Context& context, SemIR::SpecificId specific_id) -> bool { auto& specific = context.specifics().Get(specific_id); auto generic_id = specific.generic_id; - CARBON_CHECK(generic_id.is_valid()) << "Specific with no generic ID"; + CARBON_CHECK(generic_id.is_valid(), "Specific with no generic ID"); if (!specific.definition_block_id.is_valid()) { // Evaluate the eval block for the definition of the generic. diff --git a/toolchain/check/handle_binding_pattern.cpp b/toolchain/check/handle_binding_pattern.cpp index 3843e9cc09df..d69395a0d73e 100644 --- a/toolchain/check/handle_binding_pattern.cpp +++ b/toolchain/check/handle_binding_pattern.cpp @@ -108,8 +108,8 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id, cast_type_id); }); if (parent_class_decl) { - CARBON_CHECK(context_node_kind == Parse::NodeKind::VariableIntroducer) - << "`returned var` at class scope"; + CARBON_CHECK(context_node_kind == Parse::NodeKind::VariableIntroducer, + "`returned var` at class scope"); auto& class_info = context.classes().Get(parent_class_decl->class_id); auto field_type_id = context.GetUnboundElementType( class_info.self_type_id, cast_type_id); @@ -185,8 +185,8 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id, } default: - CARBON_FATAL() << "Found a pattern binding in unexpected context " - << context_node_kind; + CARBON_FATAL("Found a pattern binding in unexpected context {0}", + context_node_kind); } return true; } diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index e6e6f505c8dd..c532817d277b 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -408,8 +408,8 @@ auto HandleParseNode(Context& context, Parse::AdaptDeclId node_id) -> bool { } else if (auto* adapted_class_info = TryGetAsClass(context, adapted_type_id)) { extended_scope_id = adapted_class_info->scope_id; - CARBON_CHECK(adapted_class_info->scope_id.is_valid()) - << "Complete class should have a scope"; + CARBON_CHECK(adapted_class_info->scope_id.is_valid(), + "Complete class should have a scope"); } else { // TODO: Accept any type that has a scope. context.TODO(node_id, "extending non-class type"); @@ -489,8 +489,8 @@ static auto CheckBaseType(Context& context, Parse::NodeId node_id, DiagnoseBaseIsFinal(context, node_id, base_type_id); } - CARBON_CHECK(base_class_info->scope_id.is_valid()) - << "Complete class should have a scope"; + CARBON_CHECK(base_class_info->scope_id.is_valid(), + "Complete class should have a scope"); return {.type_id = base_type_id, .scope_id = base_class_info->scope_id}; } diff --git a/toolchain/check/handle_if_statement.cpp b/toolchain/check/handle_if_statement.cpp index 2db260a31921..f1f034f74614 100644 --- a/toolchain/check/handle_if_statement.cpp +++ b/toolchain/check/handle_if_statement.cpp @@ -68,7 +68,7 @@ auto HandleParseNode(Context& context, Parse::IfStatementId node_id) -> bool { } default: { - CARBON_FATAL() << "Unexpected parse node at start of `if`: " << kind; + CARBON_FATAL("Unexpected parse node at start of `if`: {0}", kind); } } diff --git a/toolchain/check/handle_interface.cpp b/toolchain/check/handle_interface.cpp index dfd6e2019df1..ce338e9d36fd 100644 --- a/toolchain/check/handle_interface.cpp +++ b/toolchain/check/handle_interface.cpp @@ -137,8 +137,8 @@ auto HandleParseNode(Context& context, auto& interface_info = context.interfaces().Get(interface_id); // Track that this declaration is the definition. - CARBON_CHECK(!interface_info.is_defined()) - << "Can't merge with defined interfaces."; + CARBON_CHECK(!interface_info.is_defined(), + "Can't merge with defined interfaces."); interface_info.definition_id = interface_decl_id; interface_info.scope_id = context.name_scopes().Add(interface_decl_id, SemIR::NameId::Invalid, diff --git a/toolchain/check/handle_let_and_var.cpp b/toolchain/check/handle_let_and_var.cpp index 3d9c8f024959..5b35f07daff2 100644 --- a/toolchain/check/handle_let_and_var.cpp +++ b/toolchain/check/handle_let_and_var.cpp @@ -237,8 +237,8 @@ auto HandleParseNode(Context& context, Parse::LetDeclId node_id) -> bool { // the computation of the value. // TODO: Support other kinds of pattern here. auto bind_name = pattern.inst.As(); - CARBON_CHECK(!bind_name.value_id.is_valid()) - << "Binding should not already have a value!"; + CARBON_CHECK(!bind_name.value_id.is_valid(), + "Binding should not already have a value!"); bind_name.value_id = decl_info->init_id ? *decl_info->init_id : SemIR::InstId::BuiltinError; context.ReplaceInstBeforeConstantUse(decl_info->pattern_id, bind_name); diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index a3f679185755..2e6057166b94 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -104,7 +104,7 @@ static auto HandleNameAsExpr(Context& context, Parse::NodeId node_id, auto value = context.insts().Get(result.inst_id); auto type_id = SemIR::GetTypeInSpecific(context.sem_ir(), result.specific_id, value.type_id()); - CARBON_CHECK(type_id.is_valid()) << "Missing type for " << value; + CARBON_CHECK(type_id.is_valid(), "Missing type for {0}", value); // If the named entity has a constant value that depends on its specific, // store the specific too. diff --git a/toolchain/check/handle_noop.cpp b/toolchain/check/handle_noop.cpp index 48ff804a34e5..251db60e7ab2 100644 --- a/toolchain/check/handle_noop.cpp +++ b/toolchain/check/handle_noop.cpp @@ -29,8 +29,8 @@ auto HandleParseNode(Context& context, Parse::InvalidParseSubtreeId node_id) auto HandleParseNode(Context& /*context*/, Parse::PlaceholderId /*node_id*/) -> bool { - CARBON_FATAL() - << "Placeholder node should always be replaced before parse completes"; + CARBON_FATAL( + "Placeholder node should always be replaced before parse completes"); } } // namespace Carbon::Check diff --git a/toolchain/check/handle_struct.cpp b/toolchain/check/handle_struct.cpp index 63788b7e662f..fa1583445124 100644 --- a/toolchain/check/handle_struct.cpp +++ b/toolchain/check/handle_struct.cpp @@ -125,8 +125,8 @@ auto HandleParseNode(Context& context, Parse::StructTypeLiteralId node_id) context.node_stack() .PopAndDiscardSoloNodeId(); - CARBON_CHECK(refs_id != SemIR::InstBlockId::Empty) - << "{} is handled by StructLiteral."; + CARBON_CHECK(refs_id != SemIR::InstBlockId::Empty, + "{{}} is handled by StructLiteral."); if (DiagnoseDuplicateNames(context, refs_id, "struct type literal")) { context.node_stack().Push(node_id, SemIR::InstId::BuiltinError); diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 9c5a9e4c4dc7..bc1844349b77 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -54,12 +54,12 @@ static auto GetSelfSpecificForInterfaceMemberWithSelfType( // Add the `Self` argument. CARBON_CHECK( context.entity_names() - .Get(context.insts() - .GetAs(bindings[arg_ids.size()]) - .entity_name_id) - .name_id == SemIR::NameId::SelfType) - << "Expected a Self binding, found " - << context.insts().Get(bindings[arg_ids.size()]); + .Get(context.insts() + .GetAs(bindings[arg_ids.size()]) + .entity_name_id) + .name_id == SemIR::NameId::SelfType, + "Expected a Self binding, found {0}", + context.insts().Get(bindings[arg_ids.size()])); arg_ids.push_back(context.types().GetInstId(self_type_id)); // Take any trailing argument values from the self specific. @@ -150,7 +150,7 @@ static auto BuildInterfaceWitness( decl_id = context.constant_values().GetInstId(SemIR::GetConstantValueInSpecific( context.sem_ir(), interface_type.specific_id, decl_id)); - CARBON_CHECK(decl_id.is_valid()) << "Non-constant associated entity"; + CARBON_CHECK(decl_id.is_valid(), "Non-constant associated entity"); auto decl = context.insts().Get(decl_id); CARBON_KIND_SWITCH(decl) { case CARBON_KIND(SemIR::StructValue struct_value): { @@ -160,7 +160,7 @@ static auto BuildInterfaceWitness( auto type_inst = context.types().GetAsInst(struct_value.type_id); auto fn_type = type_inst.TryAs(); if (!fn_type) { - CARBON_FATAL() << "Unexpected type: " << type_inst; + CARBON_FATAL("Unexpected type: {0}", type_inst); } auto& fn = context.functions().Get(fn_type->function_id); auto [impl_decl_id, _] = context.LookupNameInExactScope( @@ -190,8 +190,8 @@ static auto BuildInterfaceWitness( "impl of interface with associated constant"); return SemIR::InstId::BuiltinError; default: - CARBON_CHECK(decl_id == SemIR::InstId::BuiltinError) - << "Unexpected kind of associated entity " << decl; + CARBON_CHECK(decl_id == SemIR::InstId::BuiltinError, + "Unexpected kind of associated entity {0}", decl); table.push_back(SemIR::InstId::BuiltinError); break; } diff --git a/toolchain/check/import.cpp b/toolchain/check/import.cpp index b5fe10812a26..7429968f32fd 100644 --- a/toolchain/check/import.cpp +++ b/toolchain/check/import.cpp @@ -63,7 +63,7 @@ static auto GetImportName(const SemIR::File& import_sem_ir, } default: - CARBON_FATAL() << "Unsupported export kind: " << import_inst; + CARBON_FATAL("Unsupported export kind: {0}", import_inst); } } @@ -152,9 +152,9 @@ static auto CacheCopiedNamespace( SemIR::NameScopeId import_scope_id, SemIR::NameScopeId to_scope_id) -> void { auto result = copied_namespaces.Insert(import_scope_id, to_scope_id); - CARBON_CHECK(result.is_inserted() || result.value() == to_scope_id) - << "Copy result for namespace changed from " << import_scope_id << " to " - << to_scope_id; + CARBON_CHECK(result.is_inserted() || result.value() == to_scope_id, + "Copy result for namespace changed from {0} to {1}", + import_scope_id, to_scope_id); } // Copies a namespace from the import IR, returning its ID. This may diagnose @@ -431,8 +431,8 @@ auto ImportLibrariesFromOtherPackage(Context& context, IdentifierId package_id, llvm::ArrayRef import_irs, bool has_load_error) -> void { - CARBON_CHECK(has_load_error || !import_irs.empty()) - << "There should be either a load error or at least one IR."; + CARBON_CHECK(has_load_error || !import_irs.empty(), + "There should be either a load error or at least one IR."); auto name_id = SemIR::NameId::ForIdentifier(package_id); diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index ece423c882e2..8f83579a25e0 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -36,8 +36,8 @@ auto SetApiImportIR(Context& context, SemIR::ImportIR import_ir) -> void { // We don't have a check_ir_id, so add without touching check_ir_map. ir_id = InternalAddImportIR(context, import_ir); } - CARBON_CHECK(ir_id == SemIR::ImportIRId::ApiForImpl) - << "ApiForImpl must be the first IR"; + CARBON_CHECK(ir_id == SemIR::ImportIRId::ApiForImpl, + "ApiForImpl must be the first IR"); } auto AddImportIR(Context& context, SemIR::ImportIR import_ir) @@ -244,9 +244,9 @@ class ImportRefResolver { auto [new_const_id, retry] = TryResolveInst(work.inst_id, existing.const_id); - CARBON_CHECK(!existing.const_id.is_valid() || - existing.const_id == new_const_id) - << "Constant value changed in third phase."; + CARBON_CHECK( + !existing.const_id.is_valid() || existing.const_id == new_const_id, + "Constant value changed in third phase."); if (!existing.const_id.is_valid()) { SetResolvedConstId(work.inst_id, existing.indirect_insts, new_const_id); } @@ -394,8 +394,8 @@ class ImportRefResolver { } cursor_inst_id = ir_inst.inst_id; - CARBON_CHECK(cursor_ir != prev_ir || cursor_inst_id != prev_inst_id) - << cursor_ir->insts().Get(cursor_inst_id); + CARBON_CHECK(cursor_ir != prev_ir || cursor_inst_id != prev_inst_id, + "{0}", cursor_ir->insts().Get(cursor_inst_id)); if (auto const_id = context_.import_ir_constant_values()[cursor_ir_id.index].Get( @@ -426,8 +426,8 @@ class ImportRefResolver { // Returns true if new unresolved constants were found as part of this // `Resolve` step. auto HasNewWork() -> bool { - CARBON_CHECK(initial_work_ <= work_stack_.size()) - << "Work shouldn't decrease"; + CARBON_CHECK(initial_work_ <= work_stack_.size(), + "Work shouldn't decrease"); return initial_work_ < work_stack_.size(); } @@ -586,7 +586,7 @@ class ImportRefResolver { .generic_id; } default: { - CARBON_FATAL() << "Unexpected type for generic declaration: " << type; + CARBON_FATAL("Unexpected type for generic declaration: {0}", type); } } } @@ -736,7 +736,7 @@ class ImportRefResolver { break; } default: { - CARBON_FATAL() << "Unexpected kind: " << bind_inst->kind; + CARBON_FATAL("Unexpected kind: {0}", bind_inst->kind); } } } @@ -829,8 +829,8 @@ class ImportRefResolver { break; } } - CARBON_FATAL() << "Unexpected instruction kind for name scope: " - << name_scope_inst; + CARBON_FATAL("Unexpected instruction kind for name scope: {0}", + name_scope_inst); } // Given an imported entity base, returns an incomplete, local version of it. @@ -961,8 +961,8 @@ class ImportRefResolver { } else { // Third phase: perform a consistency check and produce the constant we // created in the second phase. - CARBON_CHECK(result.const_id == inner_const_id) - << "Constant value changed in third phase."; + CARBON_CHECK(result.const_id == inner_const_id, + "Constant value changed in third phase."); result.const_id = const_id; } @@ -1104,7 +1104,7 @@ class ImportRefResolver { auto ResolveAsUntyped(SemIR::Inst inst) -> ResolveResult { CARBON_CHECK(!HasNewWork()); auto result = TryEvalInst(context_, SemIR::InstId::Invalid, inst); - CARBON_CHECK(result.is_constant()) << inst << " is not constant"; + CARBON_CHECK(result.is_constant(), "{0} is not constant", inst); return {.const_id = result}; } @@ -1602,8 +1602,8 @@ class ImportRefResolver { new_interface.body_block_id = context_.inst_block_stack().Pop(); new_interface.self_param_id = self_param_id; - CARBON_CHECK(import_scope.extended_scopes.empty()) - << "Interfaces don't currently have extended scopes to support."; + CARBON_CHECK(import_scope.extended_scopes.empty(), + "Interfaces don't currently have extended scopes to support."); } auto TryResolveTypedInst(SemIR::InterfaceDecl inst, diff --git a/toolchain/check/inst_block_stack.cpp b/toolchain/check/inst_block_stack.cpp index b9b7edbb662b..d225c05383cb 100644 --- a/toolchain/check/inst_block_stack.cpp +++ b/toolchain/check/inst_block_stack.cpp @@ -12,8 +12,8 @@ namespace Carbon::Check { auto InstBlockStack::Push(SemIR::InstBlockId id) -> void { CARBON_VLOG("{0} Push {1}\n", name_, id_stack_.size()); - CARBON_CHECK(id_stack_.size() < (1 << 20)) - << "Excessive stack size: likely infinite loop"; + CARBON_CHECK(id_stack_.size() < (1 << 20), + "Excessive stack size: likely infinite loop"); id_stack_.push_back(id); insts_stack_.PushArray(); } @@ -25,7 +25,7 @@ auto InstBlockStack::Push(SemIR::InstBlockId id, } auto InstBlockStack::PeekOrAdd(int depth) -> SemIR::InstBlockId { - CARBON_CHECK(static_cast(id_stack_.size()) > depth) << "no such block"; + CARBON_CHECK(static_cast(id_stack_.size()) > depth, "no such block"); int index = id_stack_.size() - depth - 1; auto& slot = id_stack_[index]; if (!slot.is_valid()) { @@ -35,7 +35,7 @@ auto InstBlockStack::PeekOrAdd(int depth) -> SemIR::InstBlockId { } auto InstBlockStack::Pop() -> SemIR::InstBlockId { - CARBON_CHECK(!empty()) << "no current block"; + CARBON_CHECK(!empty(), "no current block"); auto id = id_stack_.pop_back_val(); auto insts = insts_stack_.PeekArray(); @@ -55,7 +55,7 @@ auto InstBlockStack::Pop() -> SemIR::InstBlockId { } auto InstBlockStack::PopAndDiscard() -> void { - CARBON_CHECK(!empty()) << "no current block"; + CARBON_CHECK(!empty(), "no current block"); id_stack_.pop_back(); insts_stack_.PopArray(); CARBON_VLOG("{0} PopAndDiscard {1}\n", name_, id_stack_.size()); diff --git a/toolchain/check/inst_block_stack.h b/toolchain/check/inst_block_stack.h index 0115861d4bcf..df718a099a92 100644 --- a/toolchain/check/inst_block_stack.h +++ b/toolchain/check/inst_block_stack.h @@ -54,7 +54,7 @@ class InstBlockStack { // Adds the given instruction ID to the block at the top of the stack. auto AddInstId(SemIR::InstId inst_id) -> void { - CARBON_CHECK(!empty()) << "no current block"; + CARBON_CHECK(!empty(), "no current block"); insts_stack_.AppendToTop(inst_id); } @@ -65,7 +65,7 @@ class InstBlockStack { // Returns a view of the contents of the top instruction block on the stack. auto PeekCurrentBlockContents() const -> llvm::ArrayRef { - CARBON_CHECK(!empty()) << "no current block"; + CARBON_CHECK(!empty(), "no current block"); return insts_stack_.PeekArray(); } @@ -75,7 +75,7 @@ class InstBlockStack { // Runs verification that the processing cleanly finished. auto VerifyOnFinish() const -> void { - CARBON_CHECK(empty()) << id_stack_.size(); + CARBON_CHECK(empty(), "{0}", id_stack_.size()); } auto empty() const -> bool { return id_stack_.empty(); } diff --git a/toolchain/check/lexical_lookup.h b/toolchain/check/lexical_lookup.h index 60ce5a94e8d6..3a0ee1cc691f 100644 --- a/toolchain/check/lexical_lookup.h +++ b/toolchain/check/lexical_lookup.h @@ -43,13 +43,14 @@ class LexicalLookup { // Returns the lexical lookup results for a name. auto Get(SemIR::NameId name_id) -> llvm::SmallVector& { auto index = GetLookupIndex(name_id); - CARBON_CHECK(index < lookup_.size()) - << "An identifier was added after the Context was initialized. " - "Currently, we expect that new identifiers will never be used with " - "lexical lookup (they're added for things like detecting name " - "collisions in imports). That might change with metaprogramming: if " - "it does, we may need to start resizing `lookup_`, either on each " - "identifier addition or in Get` where this CHECK currently fires."; + CARBON_CHECK( + index < lookup_.size(), + "An identifier was added after the Context was initialized. Currently, " + "we expect that new identifiers will never be used with lexical lookup " + "(they're added for things like detecting name collisions in imports). " + "That might change with metaprogramming: if it does, we may need to " + "start resizing `lookup_`, either on each identifier addition or in " + "Get` where this CHECK currently fires."); return lookup_[index]; } @@ -57,10 +58,10 @@ class LexicalLookup { auto Suspend(SemIR::NameId name_id) -> SuspendedResult { auto index = GetLookupIndex(name_id); auto& results = lookup_[index]; - CARBON_CHECK(!results.empty()) - << "Suspending a nonexistent result for " << name_id << "."; - CARBON_CHECK(index <= std::numeric_limits::max()) - << "Unexpectedly large index " << index << " for name ID"; + CARBON_CHECK(!results.empty(), "Suspending a nonexistent result for {0}.", + name_id); + CARBON_CHECK(index <= std::numeric_limits::max(), + "Unexpectedly large index {0} for name ID", index); return {.index = static_cast(index), .inst_id = results.pop_back_val().inst_id}; } diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index 7020fabf6578..d6e5a5f5cad9 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -80,8 +80,7 @@ static auto GetClassElementIndex(Context& context, SemIR::InstId element_id) if (auto base = element_inst.TryAs()) { return base->index; } - CARBON_FATAL() << "Unexpected value " << element_inst - << " in class element name"; + CARBON_FATAL("Unexpected value {0} in class element name", element_inst); } // Returns whether `function_id` is an instance method, that is, whether it has @@ -321,7 +320,7 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, auto inst = context.insts().Get(result.inst_id); auto type_id = SemIR::GetTypeInSpecific(context.sem_ir(), result.specific_id, inst.type_id()); - CARBON_CHECK(type_id.is_valid()) << "Missing type for member " << inst; + CARBON_CHECK(type_id.is_valid(), "Missing type for member {0}", inst); // If the named entity has a constant value that depends on its specific, // store the specific too. @@ -372,9 +371,9 @@ static auto PerformInstanceBinding(Context& context, SemIR::LocId loc_id, // Find the specified element, which could be either a field or a base // class, and build an element access expression. auto element_id = context.constant_values().GetConstantInstId(member_id); - CARBON_CHECK(element_id.is_valid()) - << "Non-constant value " << context.insts().Get(member_id) - << " of unbound element type"; + CARBON_CHECK(element_id.is_valid(), + "Non-constant value {0} of unbound element type", + context.insts().Get(member_id)); auto index = GetClassElementIndex(context, element_id); auto access_id = context.AddInst( loc_id, {.type_id = unbound_element_type.element_type_id, diff --git a/toolchain/check/merge.cpp b/toolchain/check/merge.cpp index a93059a3fa47..ae00a8f7b5f4 100644 --- a/toolchain/check/merge.cpp +++ b/toolchain/check/merge.cpp @@ -348,12 +348,12 @@ static auto CheckRedeclParamSyntax(Context& context, !prev_first_param_node_id.is_valid()) { return true; } - CARBON_CHECK(new_last_param_node_id.is_valid()) - << "new_last_param_node_id.is_valid should match " - "new_first_param_node_id.is_valid"; - CARBON_CHECK(prev_last_param_node_id.is_valid()) - << "prev_last_param_node_id.is_valid should match " - "prev_first_param_node_id.is_valid"; + CARBON_CHECK(new_last_param_node_id.is_valid(), + "new_last_param_node_id.is_valid should match " + "new_first_param_node_id.is_valid"); + CARBON_CHECK(prev_last_param_node_id.is_valid(), + "prev_last_param_node_id.is_valid should match " + "prev_first_param_node_id.is_valid"); auto new_range = Parse::Tree::PostorderIterator::MakeRange( new_first_param_node_id, new_last_param_node_id); diff --git a/toolchain/check/node_stack.cpp b/toolchain/check/node_stack.cpp index 8b28e0707d78..3d7ca19cecdd 100644 --- a/toolchain/check/node_stack.cpp +++ b/toolchain/check/node_stack.cpp @@ -14,7 +14,7 @@ auto NodeStack::PrintForStackDump(SemIR::Formatter& formatter, int indent, if constexpr (Kind == Id::Kind::None) { output << "no value\n"; } else if constexpr (Kind == Id::Kind::Invalid) { - CARBON_FATAL() << "Should not be in node stack"; + CARBON_FATAL("Should not be in node stack"); } else if constexpr (Kind == Id::KindFor()) { output << "\n"; formatter.PrintInst(id.As()>(), indent + 4, diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index fd1db507e030..02c68da70583 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -79,11 +79,11 @@ class NodeStack { // IR generated by the node. auto Push(Parse::NodeId node_id) -> void { auto kind = parse_tree_->node_kind(node_id); - CARBON_CHECK(NodeKindToIdKind(kind) == Id::Kind::None) - << "Parse kind expects an Id: " << kind; + CARBON_CHECK(NodeKindToIdKind(kind) == Id::Kind::None, + "Parse kind expects an Id: {0}", kind); CARBON_VLOG("Node Push {0}: {1} -> \n", stack_.size(), kind); - CARBON_CHECK(stack_.size() < (1 << 20)) - << "Excessive stack size: likely infinite loop"; + CARBON_CHECK(stack_.size() < (1 << 20), + "Excessive stack size: likely infinite loop"); stack_.push_back({.node_id = node_id, .id = Id()}); } @@ -91,14 +91,13 @@ class NodeStack { template auto Push(Parse::NodeId node_id, IdT id) -> void { auto kind = parse_tree_->node_kind(node_id); - CARBON_CHECK(NodeKindToIdKind(kind) == Id::KindFor()) - << "Parse kind expected a different IdT: " << kind << " -> " << id - << "\n"; - CARBON_CHECK(id.is_valid()) - << "Push called with invalid id: " << parse_tree_->node_kind(node_id); + CARBON_CHECK(NodeKindToIdKind(kind) == Id::KindFor(), + "Parse kind expected a different IdT: {0} -> {1}\n", kind, id); + CARBON_CHECK(id.is_valid(), "Push called with invalid id: {0}", + parse_tree_->node_kind(node_id)); CARBON_VLOG("Node Push {0}: {1} -> {2}\n", stack_.size(), kind, id); - CARBON_CHECK(stack_.size() < (1 << 20)) - << "Excessive stack size: likely infinite loop"; + CARBON_CHECK(stack_.size() < (1 << 20), + "Excessive stack size: likely infinite loop"); stack_.push_back({.node_id = node_id, .id = Id(id)}); } @@ -690,27 +689,27 @@ class NodeStack { // Require a Parse::NodeKind be mapped to a particular Id::Kind. auto RequireIdKind(Parse::NodeKind parse_kind, Id::Kind id_kind) const -> void { - CARBON_CHECK(NodeKindToIdKind(parse_kind) == id_kind) - << "Unexpected Id::Kind mapping for " << parse_kind << ": expected " - << static_cast(id_kind) << ", found " - << static_cast(NodeKindToIdKind(parse_kind)); + CARBON_CHECK(NodeKindToIdKind(parse_kind) == id_kind, + "Unexpected Id::Kind mapping for {0}: expected {1}, found {2}", + parse_kind, static_cast(id_kind), + static_cast(NodeKindToIdKind(parse_kind))); } // Require an entry to have the given Parse::NodeKind. template auto RequireParseKind(Parse::NodeId node_id) const -> void { auto actual_kind = parse_tree_->node_kind(node_id); - CARBON_CHECK(RequiredParseKind == actual_kind) - << "Expected " << RequiredParseKind << ", found " << actual_kind; + CARBON_CHECK(RequiredParseKind == actual_kind, "Expected {0}, found {1}", + RequiredParseKind, actual_kind); } // Require an entry to have the given Parse::NodeCategory. template auto RequireParseCategory(Parse::NodeId node_id) const -> void { auto kind = parse_tree_->node_kind(node_id); - CARBON_CHECK(kind.category().HasAnyOf(RequiredParseCategory)) - << "Expected " << RequiredParseCategory << ", found " << kind - << " with category " << kind.category(); + CARBON_CHECK(kind.category().HasAnyOf(RequiredParseCategory), + "Expected {0}, found {1} with category {2}", + RequiredParseCategory, kind, kind.category()); } // The file's parse tree. diff --git a/toolchain/check/return.cpp b/toolchain/check/return.cpp index b12adf40067b..aa3c495efea8 100644 --- a/toolchain/check/return.cpp +++ b/toolchain/check/return.cpp @@ -11,8 +11,8 @@ namespace Carbon::Check { // Gets the function that lexically encloses the current location. static auto GetCurrentFunction(Context& context) -> SemIR::Function& { - CARBON_CHECK(!context.return_scope_stack().empty()) - << "Handling return but not in a function"; + CARBON_CHECK(!context.return_scope_stack().empty(), + "Handling return but not in a function"); auto function_id = context.insts() .GetAs( context.return_scope_stack().back().decl_id) @@ -23,8 +23,8 @@ static auto GetCurrentFunction(Context& context) -> SemIR::Function& { // Gets the currently in scope `returned var`, if any, that would be returned // by a `return var;`. static auto GetCurrentReturnedVar(Context& context) -> SemIR::InstId { - CARBON_CHECK(!context.return_scope_stack().empty()) - << "Handling return but not in a function"; + CARBON_CHECK(!context.return_scope_stack().empty(), + "Handling return but not in a function"); return context.return_scope_stack().back().returned_var; } diff --git a/toolchain/check/scope_stack.cpp b/toolchain/check/scope_stack.cpp index 8df737f512e3..a7a1119e2a1e 100644 --- a/toolchain/check/scope_stack.cpp +++ b/toolchain/check/scope_stack.cpp @@ -10,7 +10,7 @@ namespace Carbon::Check { auto ScopeStack::VerifyOnFinish() -> void { - CARBON_CHECK(scope_stack_.empty()) << scope_stack_.size(); + CARBON_CHECK(scope_stack_.empty(), "{0}", scope_stack_.size()); } auto ScopeStack::Push(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id, @@ -41,13 +41,13 @@ auto ScopeStack::Push(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id, // For lexical lookups, unqualified lookup doesn't know how to find the // associated specific, so if we start adding lexical scopes associated with // specifics, we'll need to somehow track them in lookup. - CARBON_CHECK(!specific_id.is_valid()) - << "Lexical scope should not have an associated specific."; + CARBON_CHECK(!specific_id.is_valid(), + "Lexical scope should not have an associated specific."); } // TODO: Handle this case more gracefully. - CARBON_CHECK(next_scope_index_.index != std::numeric_limits::max()) - << "Ran out of scopes"; + CARBON_CHECK(next_scope_index_.index != std::numeric_limits::max(), + "Ran out of scopes"); ++next_scope_index_.index; } @@ -56,8 +56,8 @@ auto ScopeStack::Pop() -> void { scope.names.ForEach([&](SemIR::NameId str_id) { auto& lexical_results = lexical_lookup_.Get(str_id); - CARBON_CHECK(lexical_results.back().scope_index == scope.index) - << "Inconsistent scope index for name " << str_id; + CARBON_CHECK(lexical_results.back().scope_index == scope.index, + "Inconsistent scope index for name {0}", str_id); lexical_results.pop_back(); }); @@ -74,10 +74,11 @@ auto ScopeStack::Pop() -> void { CARBON_CHECK( scope.next_compile_time_bind_index.index == - static_cast(compile_time_binding_stack_.all_values_size())) - << "Wrong number of entries in compile-time binding stack, have " - << compile_time_binding_stack_.all_values_size() << ", expected " - << scope.next_compile_time_bind_index.index; + static_cast(compile_time_binding_stack_.all_values_size()), + "Wrong number of entries in compile-time binding stack, have {0}, " + "expected {1}", + compile_time_binding_stack_.all_values_size(), + scope.next_compile_time_bind_index.index); compile_time_binding_stack_.PopArray(); } @@ -85,9 +86,9 @@ auto ScopeStack::PopTo(ScopeIndex index) -> void { while (PeekIndex() > index) { Pop(); } - CARBON_CHECK(PeekIndex() == index) - << "Scope index " << index << " does not enclose the current scope " - << PeekIndex(); + CARBON_CHECK(PeekIndex() == index, + "Scope index {0} does not enclose the current scope {1}", index, + PeekIndex()); } auto ScopeStack::LookupInCurrentScope(SemIR::NameId name_id) -> SemIR::InstId { @@ -135,8 +136,8 @@ auto ScopeStack::LookupOrAddName(SemIR::NameId name_id, SemIR::InstId target_id) -> SemIR::InstId { if (!scope_stack_.back().names.Insert(name_id).is_inserted()) { auto existing = lexical_lookup_.Get(name_id).back().inst_id; - CARBON_CHECK(existing.is_valid()) - << "Name in scope but not in lexical lookups"; + CARBON_CHECK(existing.is_valid(), + "Name in scope but not in lexical lookups"); return existing; } ++scope_stack_.back().num_names; @@ -144,24 +145,25 @@ auto ScopeStack::LookupOrAddName(SemIR::NameId name_id, SemIR::InstId target_id) // TODO: Reject if we previously performed a failed lookup for this name // in this scope or a scope nested within it. auto& lexical_results = lexical_lookup_.Get(name_id); - CARBON_CHECK(lexical_results.empty() || - lexical_results.back().scope_index < PeekIndex()) - << "Failed to clean up after scope nested within the current scope"; + CARBON_CHECK( + lexical_results.empty() || + lexical_results.back().scope_index < PeekIndex(), + "Failed to clean up after scope nested within the current scope"); lexical_results.push_back({.inst_id = target_id, .scope_index = PeekIndex()}); return SemIR::InstId::Invalid; } auto ScopeStack::SetReturnedVarOrGetExisting(SemIR::InstId inst_id) -> SemIR::InstId { - CARBON_CHECK(!return_scope_stack_.empty()) << "`returned var` in no function"; + CARBON_CHECK(!return_scope_stack_.empty(), "`returned var` in no function"); auto& returned_var = return_scope_stack_.back().returned_var; if (returned_var.is_valid()) { return returned_var; } returned_var = inst_id; - CARBON_CHECK(!scope_stack_.back().has_returned_var) - << "Scope has returned var but none is set"; + CARBON_CHECK(!scope_stack_.back().has_returned_var, + "Scope has returned var but none is set"); if (inst_id.is_valid()) { scope_stack_.back().has_returned_var = true; } @@ -169,7 +171,7 @@ auto ScopeStack::SetReturnedVarOrGetExisting(SemIR::InstId inst_id) } auto ScopeStack::Suspend() -> SuspendedScope { - CARBON_CHECK(!scope_stack_.empty()) << "No scope to suspend"; + CARBON_CHECK(!scope_stack_.empty(), "No scope to suspend"); SuspendedScope result = {.entry = scope_stack_.pop_back_val(), .suspended_items = {}}; if (result.entry.scope_id.is_valid()) { @@ -198,8 +200,8 @@ auto ScopeStack::Suspend() -> SuspendedScope { compile_time_binding_stack_.PopArray(); // This would be easy to support if we had a need, but currently we do not. - CARBON_CHECK(!result.entry.has_returned_var) - << "Should not suspend a scope with a returned var."; + CARBON_CHECK(!result.entry.has_returned_var, + "Should not suspend a scope with a returned var."); return result; } @@ -216,11 +218,11 @@ auto ScopeStack::Restore(SuspendedScope scope) -> void { CARBON_CHECK( scope.entry.next_compile_time_bind_index.index == - static_cast(compile_time_binding_stack_.all_values_size())) - << "Wrong number of entries in compile-time binding stack " - "when restoring, have " - << compile_time_binding_stack_.all_values_size() << ", expected " - << scope.entry.next_compile_time_bind_index.index; + static_cast(compile_time_binding_stack_.all_values_size()), + "Wrong number of entries in compile-time binding stack when restoring, " + "have {0}, expected {1}", + compile_time_binding_stack_.all_values_size(), + scope.entry.next_compile_time_bind_index.index); if (scope.entry.scope_id.is_valid()) { non_lexical_scope_stack_.push_back( diff --git a/toolchain/check/sem_ir_diagnostic_converter.cpp b/toolchain/check/sem_ir_diagnostic_converter.cpp index 4a029665276e..74c2be1d5456 100644 --- a/toolchain/check/sem_ir_diagnostic_converter.cpp +++ b/toolchain/check/sem_ir_diagnostic_converter.cpp @@ -18,9 +18,9 @@ auto SemIRDiagnosticConverter::ConvertLoc(SemIRLoc loc, auto follow_import_ref = [&](SemIR::ImportIRInstId import_ir_inst_id) { auto import_ir_inst = cursor_ir->import_ir_insts().Get(import_ir_inst_id); const auto& import_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id); - CARBON_CHECK(import_ir.decl_id.is_valid()) - << "If we get invalid locations here, we may need to more thoroughly " - "track ImportDecls."; + CARBON_CHECK(import_ir.decl_id.is_valid(), + "If we get invalid locations here, we may need to more " + "thoroughly track ImportDecls."); DiagnosticLoc in_import_loc; auto import_loc_id = cursor_ir->insts().GetLocId(import_ir.decl_id); @@ -37,8 +37,8 @@ auto SemIRDiagnosticConverter::ConvertLoc(SemIRLoc loc, cursor_ir->import_irs().Get(implicit_import_ir_inst.ir_id); auto implicit_loc_id = implicit_ir.sem_ir->insts().GetLocId(implicit_import_ir_inst.inst_id); - CARBON_CHECK(implicit_loc_id.is_node_id()) - << "Should only be one layer of implicit imports"; + CARBON_CHECK(implicit_loc_id.is_node_id(), + "Should only be one layer of implicit imports"); in_import_loc = ConvertLocInFile(implicit_ir.sem_ir, implicit_loc_id.node_id(), loc.token_only, context_fn); @@ -75,7 +75,7 @@ auto SemIRDiagnosticConverter::ConvertLoc(SemIRLoc loc, if (auto diag_loc = handle_loc(loc.loc_id)) { return *diag_loc; } - CARBON_CHECK(cursor_inst_id.is_valid()) << "Should have been set"; + CARBON_CHECK(cursor_inst_id.is_valid(), "Should have been set"); } while (true) { diff --git a/toolchain/check/subst.cpp b/toolchain/check/subst.cpp index adff7307b9f0..ffa32d74a117 100644 --- a/toolchain/check/subst.cpp +++ b/toolchain/check/subst.cpp @@ -45,7 +45,7 @@ class Worklist { worklist_.push_back({.inst_id = inst_id, .is_expanded = false, .next_index = static_cast(worklist_.size() + 1)}); - CARBON_CHECK(worklist_.back().next_index > 0) << "Constant too large."; + CARBON_CHECK(worklist_.back().next_index > 0, "Constant too large."); } auto Pop() -> SemIR::InstId { return worklist_.pop_back_val().inst_id; } @@ -240,8 +240,8 @@ auto SubstInst(Context& context, SemIR::InstId inst_id, } } - CARBON_CHECK(worklist.size() == 1) - << "Unexpected data left behind in work list"; + CARBON_CHECK(worklist.size() == 1, + "Unexpected data left behind in work list"); return worklist.back().inst_id; } @@ -288,8 +288,8 @@ class SubstConstantCallbacks final : public SubstInstCallbacks { auto Rebuild(SemIR::InstId /*old_inst_id*/, SemIR::Inst new_inst) const -> SemIR::InstId override { auto result_id = TryEvalInst(context_, SemIR::InstId::Invalid, new_inst); - CARBON_CHECK(result_id.is_constant()) - << "Substitution into constant produced non-constant"; + CARBON_CHECK(result_id.is_constant(), + "Substitution into constant produced non-constant"); return context_.constant_values().GetInstId(result_id); } @@ -301,7 +301,7 @@ class SubstConstantCallbacks final : public SubstInstCallbacks { auto SubstConstant(Context& context, SemIR::ConstantId const_id, Substitutions substitutions) -> SemIR::ConstantId { - CARBON_CHECK(const_id.is_constant()) << "Substituting into non-constant"; + CARBON_CHECK(const_id.is_constant(), "Substituting into non-constant"); if (substitutions.empty()) { // Nothing to substitute. diff --git a/toolchain/diagnostics/diagnostic_emitter.h b/toolchain/diagnostics/diagnostic_emitter.h index 6cfaf6e147be..8222678dcefd 100644 --- a/toolchain/diagnostics/diagnostic_emitter.h +++ b/toolchain/diagnostics/diagnostic_emitter.h @@ -63,8 +63,8 @@ class DiagnosticEmitter { auto Note(LocT loc, const Internal::DiagnosticBase& diagnostic_base, Internal::NoTypeDeduction... args) -> DiagnosticBuilder& { - CARBON_CHECK(diagnostic_base.Level == DiagnosticLevel::Note) - << static_cast(diagnostic_base.Level); + CARBON_CHECK(diagnostic_base.Level == DiagnosticLevel::Note, "{0}", + static_cast(diagnostic_base.Level)); AddMessage(loc, diagnostic_base, {emitter_->MakeAny(args)...}); return *this; } @@ -137,9 +137,9 @@ class DiagnosticEmitter { static auto FormatFn(const DiagnosticMessage& message, std::index_sequence /*indices*/) -> std::string { static_assert(sizeof...(Args) == sizeof...(N), "Invalid template args"); - CARBON_CHECK(message.format_args.size() == sizeof...(Args)) - << "Argument count mismatch on " << message.kind << ": " - << message.format_args.size() << " != " << sizeof...(Args); + CARBON_CHECK(message.format_args.size() == sizeof...(Args), + "Argument count mismatch on {0}: {1} != {2}", message.kind, + message.format_args.size(), sizeof...(Args)); return llvm::formatv( message.format.data(), llvm::any_cast< @@ -189,9 +189,10 @@ class DiagnosticEmitter { auto MakeAny(Arg arg) -> llvm::Any { llvm::Any converted = converter_->ConvertArg(arg); using Storage = Internal::DiagnosticTypeForArg::StorageType; - CARBON_CHECK(llvm::any_cast(&converted)) - << "Failed to convert argument of type " << typeid(Arg).name() - << " to its storage type " << typeid(Storage).name(); + CARBON_CHECK( + llvm::any_cast(&converted), + "Failed to convert argument of type {0} to its storage type {1}", + typeid(Arg).name(), typeid(Storage).name()); return converted; } diff --git a/toolchain/diagnostics/sorting_diagnostic_consumer.h b/toolchain/diagnostics/sorting_diagnostic_consumer.h index 35a307a97b74..9aa6c00c42ef 100644 --- a/toolchain/diagnostics/sorting_diagnostic_consumer.h +++ b/toolchain/diagnostics/sorting_diagnostic_consumer.h @@ -22,8 +22,8 @@ class SortingDiagnosticConsumer : public DiagnosticConsumer { // likely to refer to data that gets destroyed before the diagnostics // consumer is destroyed, because the diagnostics consumer is typically // created before the objects that diagnostics refer into are created. - CARBON_CHECK(diagnostics_.empty()) - << "Must flush diagnostics consumer before destroying it"; + CARBON_CHECK(diagnostics_.empty(), + "Must flush diagnostics consumer before destroying it"); } // Buffers the diagnostic. diff --git a/toolchain/docs/idioms.md b/toolchain/docs/idioms.md index a8d6fb9bbe4b..cf93efb1f61f 100644 --- a/toolchain/docs/idioms.md +++ b/toolchain/docs/idioms.md @@ -289,7 +289,7 @@ CARBON_DCHECK([&] { return complicated && multiple_parts; // finish defining the lambda, and then immediately invoke it -}()) << "Complicated things went wrong"; +}(), "Complicated things went wrong"); ``` See a description of this technique on diff --git a/toolchain/driver/clang_runner.cpp b/toolchain/driver/clang_runner.cpp index df33d6e6d937..5c1b3a2c92db 100644 --- a/toolchain/driver/clang_runner.cpp +++ b/toolchain/driver/clang_runner.cpp @@ -118,7 +118,7 @@ auto ClangRunner::Run(llvm::ArrayRef args) -> bool { // driver.CC1Main = [](llvm::SmallVectorImpl& argv) {}; std::unique_ptr compilation( driver.BuildCompilation(cstr_args)); - CARBON_CHECK(compilation) << "Should always successfully allocate!"; + CARBON_CHECK(compilation, "Should always successfully allocate!"); if (compilation->containsError()) { // These should have been diagnosed by the driver. return false; diff --git a/toolchain/driver/clang_runner_test.cpp b/toolchain/driver/clang_runner_test.cpp index 09d6a4b42c14..edaa951e5b7d 100644 --- a/toolchain/driver/clang_runner_test.cpp +++ b/toolchain/driver/clang_runner_test.cpp @@ -106,7 +106,7 @@ static auto WriteTestFile(llvm::StringRef name_suffix, llvm::Twine contents) { std::error_code ec; llvm::raw_fd_ostream test_file_stream(test_file.string(), ec); - CARBON_CHECK(!ec) << "Test file error: " << ec.message(); + CARBON_CHECK(!ec, "Test file error: {0}", ec.message()); test_file_stream << contents; } return test_file; diff --git a/toolchain/driver/driver.cpp b/toolchain/driver/driver.cpp index b2e4ba8d1003..3f27f77611a9 100644 --- a/toolchain/driver/driver.cpp +++ b/toolchain/driver/driver.cpp @@ -946,8 +946,8 @@ auto Driver::Compile(const CompileOptions& options, if (options.phase == CompileOptions::Phase::Lower) { return make_result(); } - CARBON_CHECK(options.phase == CompileOptions::Phase::CodeGen) - << "CodeGen should be the last stage"; + CARBON_CHECK(options.phase == CompileOptions::Phase::CodeGen, + "CodeGen should be the last stage"); // Codegen. for (auto& unit : units) { diff --git a/toolchain/driver/driver_fuzzer.cpp b/toolchain/driver/driver_fuzzer.cpp index 9f8deb5abf3f..4cb9b7b6a252 100644 --- a/toolchain/driver/driver_fuzzer.cpp +++ b/toolchain/driver/driver_fuzzer.cpp @@ -20,7 +20,7 @@ static const InstallPaths* install_paths = nullptr; // NOLINTNEXTLINE(readability-non-const-parameter): External API required types. extern "C" auto LLVMFuzzerInitialize(int* argc, char*** argv) -> int { - CARBON_CHECK(*argc >= 1) << "Need the `argv[0]` value to initialize!"; + CARBON_CHECK(*argc >= 1, "Need the `argv[0]` value to initialize!"); install_paths = new InstallPaths( InstallPaths::MakeForBazelRunfiles(FindExecutablePath((*argv)[0]))); return 0; diff --git a/toolchain/driver/driver_test.cpp b/toolchain/driver/driver_test.cpp index 009835081fce..2fbe05cdf046 100644 --- a/toolchain/driver/driver_test.cpp +++ b/toolchain/driver/driver_test.cpp @@ -65,7 +65,7 @@ class DriverTest : public testing::Test { // Save our current working directory. std::error_code ec; auto original_dir = std::filesystem::current_path(ec); - CARBON_CHECK(!ec) << ec.message(); + CARBON_CHECK(!ec, "{0}", ec.message()); const auto* unit_test = ::testing::UnitTest::GetInstance(); const auto* test_info = unit_test->current_test_info(); @@ -74,19 +74,20 @@ class DriverTest : public testing::Test { test_info->name()) .str()); std::filesystem::create_directory(test_dir, ec); - CARBON_CHECK(!ec) << "Could not create test working dir '" << test_dir - << "': " << ec.message(); + CARBON_CHECK(!ec, "Could not create test working dir '{0}': {1}", test_dir, + ec.message()); std::filesystem::current_path(test_dir, ec); - CARBON_CHECK(!ec) << "Could not change the current working dir to '" - << test_dir << "': " << ec.message(); + CARBON_CHECK(!ec, "Could not change the current working dir to '{0}': {1}", + test_dir, ec.message()); return llvm::make_scope_exit([original_dir, test_dir] { std::error_code ec; std::filesystem::current_path(original_dir, ec); - CARBON_CHECK(!ec) << "Could not change the current working dir to '" - << original_dir << "': " << ec.message(); + CARBON_CHECK(!ec, + "Could not change the current working dir to '{0}': {1}", + original_dir, ec.message()); std::filesystem::remove_all(test_dir, ec); - CARBON_CHECK(!ec) << "Could not remove the test working dir '" << test_dir - << "': " << ec.message(); + CARBON_CHECK(!ec, "Could not remove the test working dir '{0}': {1}", + test_dir, ec.message()); }); } diff --git a/toolchain/install/install_paths.cpp b/toolchain/install/install_paths.cpp index 820d4d164625..7e8e88dc87a3 100644 --- a/toolchain/install/install_paths.cpp +++ b/toolchain/install/install_paths.cpp @@ -54,8 +54,8 @@ auto InstallPaths::MakeForBazelRunfiles(llvm::StringRef exe_path) std::string runtimes_error; std::unique_ptr runfiles( Runfiles::Create(exe_path.str(), &runtimes_error)); - CARBON_CHECK(runfiles != nullptr) - << "Failed to find runtimes tree: " << runtimes_error; + CARBON_CHECK(runfiles != nullptr, "Failed to find runtimes tree: {0}", + runtimes_error); std::string relative_marker_path = (PrefixRoot.str() + MarkerPath).str(); std::string runtimes_marker_path = runfiles->Rlocation(relative_marker_path); @@ -68,7 +68,7 @@ auto InstallPaths::MakeForBazelRunfiles(llvm::StringRef exe_path) "../../"); paths.CheckMarkerFile(); - CARBON_CHECK(!paths.error()) << *paths.error(); + CARBON_CHECK(!paths.error(), "{0}", *paths.error()); return paths; } diff --git a/toolchain/install/install_paths_test.cpp b/toolchain/install/install_paths_test.cpp index b3c980417bc5..79668fae0489 100644 --- a/toolchain/install/install_paths_test.cpp +++ b/toolchain/install/install_paths_test.cpp @@ -29,7 +29,7 @@ class InstallPathsTest : public ::testing::Test { InstallPathsTest() { std::string error; test_runfiles_.reset(Runfiles::Create(Testing::GetExePath().str(), &error)); - CARBON_CHECK(test_runfiles_ != nullptr) << error; + CARBON_CHECK(test_runfiles_ != nullptr, "{0}", error); } // Test the install paths found with the given `exe_path`. Will check that @@ -92,8 +92,8 @@ TEST_F(InstallPathsTest, PrefixRootExplicit) { "carbon/toolchain/install/prefix_root/lib/carbon/carbon_install.txt"); llvm::StringRef prefix_path = marker_path; - CARBON_CHECK(prefix_path.consume_back("lib/carbon/carbon_install.txt")) - << "Unexpected suffix of the marker path: " << marker_path; + CARBON_CHECK(prefix_path.consume_back("lib/carbon/carbon_install.txt"), + "Unexpected suffix of the marker path: {0}", marker_path); auto paths = InstallPaths::Make(prefix_path); ASSERT_THAT(paths.error(), Eq(std::nullopt)) << *paths.error(); @@ -109,8 +109,8 @@ TEST_F(InstallPathsTest, TestRunfiles) { TEST_F(InstallPathsTest, BinaryRunfiles) { std::string test_binary_path = test_runfiles_->Rlocation("carbon/toolchain/install/test_binary"); - CARBON_CHECK(llvm::sys::fs::can_execute(test_binary_path)) - << test_binary_path; + CARBON_CHECK(llvm::sys::fs::can_execute(test_binary_path), "{0}", + test_binary_path); auto paths = InstallPaths::MakeForBazelRunfiles(test_binary_path); ASSERT_THAT(paths.error(), Eq(std::nullopt)) << *paths.error(); diff --git a/toolchain/install/install_paths_test_helpers.cpp b/toolchain/install/install_paths_test_helpers.cpp index acdda8a6050e..30a1e7506f19 100644 --- a/toolchain/install/install_paths_test_helpers.cpp +++ b/toolchain/install/install_paths_test_helpers.cpp @@ -15,14 +15,14 @@ auto AddPreludeFilesToVfs(InstallPaths install_paths, // Load the prelude into the test VFS. auto real_fs = llvm::vfs::getRealFileSystem(); auto prelude = install_paths.ReadPreludeManifest(); - CARBON_CHECK(prelude.ok()) << prelude.error(); + CARBON_CHECK(prelude.ok(), "{0}", prelude.error()); for (const auto& path : *prelude) { llvm::ErrorOr> file = real_fs->getBufferForFile(path); - CARBON_CHECK(file) << "Error getting file: " << file.getError().message(); + CARBON_CHECK(file, "Error getting file: {0}", file.getError().message()); bool added = vfs->addFile(path, /*ModificationTime=*/0, std::move(*file)); - CARBON_CHECK(added) << "Duplicate file: " << path; + CARBON_CHECK(added, "Duplicate file: {0}", path); } } diff --git a/toolchain/lex/lex.cpp b/toolchain/lex/lex.cpp index a04a77813fd5..c7461d8817c3 100644 --- a/toolchain/lex/lex.cpp +++ b/toolchain/lex/lex.cpp @@ -508,7 +508,7 @@ static auto DispatchNext(Lexer& lexer, llvm::StringRef source_text, static auto Dispatch##LexMethod(Lexer& lexer, llvm::StringRef source_text, \ ssize_t position) -> void { \ Lexer::LexResult result = lexer.LexMethod(source_text, position); \ - CARBON_CHECK(result) << "Failed to form a token!"; \ + CARBON_CHECK(result, "Failed to form a token!"); \ [[clang::musttail]] return DispatchNext(lexer, source_text, position); \ } CARBON_DISPATCH_LEX_TOKEN(LexError) @@ -527,7 +527,7 @@ CARBON_DISPATCH_LEX_TOKEN(LexStringLiteral) OneCharTokenKindTable[static_cast( \ source_text[position])], \ position); \ - CARBON_CHECK(result) << "Failed to form a token!"; \ + CARBON_CHECK(result, "Failed to form a token!"); \ [[clang::musttail]] return DispatchNext(lexer, source_text, position); \ } CARBON_DISPATCH_LEX_SYMBOL_TOKEN(LexOneChar) @@ -855,7 +855,7 @@ auto Lexer::LexCommentOrSlash(llvm::StringRef source_text, ssize_t& position) // This code path should produce a token, make sure that happens. LexResult result = LexSymbolToken(source_text, position); - CARBON_CHECK(result) << "Failed to form a token!"; + CARBON_CHECK(result, "Failed to form a token!"); } auto Lexer::LexComment(llvm::StringRef source_text, ssize_t& position) -> void { @@ -1063,10 +1063,10 @@ auto Lexer::LexOneCharSymbolToken(llvm::StringRef source_text, TokenKind kind, // Verify in a debug build that the incoming token kind is correct. CARBON_DCHECK(kind != TokenKind::Error); CARBON_DCHECK(kind.fixed_spelling().size() == 1); - CARBON_DCHECK(source_text[position] == kind.fixed_spelling().front()) - << "Source text starts with '" << source_text[position] - << "' instead of the spelling '" << kind.fixed_spelling() - << "' of the incoming token kind '" << kind << "'"; + CARBON_DCHECK(source_text[position] == kind.fixed_spelling().front(), + "Source text starts with '{0}' instead of the spelling '{1}' " + "of the incoming token kind '{2}'", + source_text[position], kind.fixed_spelling(), kind); TokenIndex token = LexToken(kind, position); ++position; @@ -1077,10 +1077,10 @@ auto Lexer::LexOpeningSymbolToken(llvm::StringRef source_text, TokenKind kind, ssize_t& position) -> LexResult { CARBON_DCHECK(kind.is_opening_symbol()); CARBON_DCHECK(kind.fixed_spelling().size() == 1); - CARBON_DCHECK(source_text[position] == kind.fixed_spelling().front()) - << "Source text starts with '" << source_text[position] - << "' instead of the spelling '" << kind.fixed_spelling() - << "' of the incoming token kind '" << kind << "'"; + CARBON_DCHECK(source_text[position] == kind.fixed_spelling().front(), + "Source text starts with '{0}' instead of the spelling '{1}' " + "of the incoming token kind '{2}'", + source_text[position], kind.fixed_spelling(), kind); int32_t byte_offset = position; ++position; @@ -1096,10 +1096,10 @@ auto Lexer::LexClosingSymbolToken(llvm::StringRef source_text, TokenKind kind, ssize_t& position) -> LexResult { CARBON_DCHECK(kind.is_closing_symbol()); CARBON_DCHECK(kind.fixed_spelling().size() == 1); - CARBON_DCHECK(source_text[position] == kind.fixed_spelling().front()) - << "Source text starts with '" << source_text[position] - << "' instead of the spelling '" << kind.fixed_spelling() - << "' of the incoming token kind '" << kind << "'"; + CARBON_DCHECK(source_text[position] == kind.fixed_spelling().front(), + "Source text starts with '{0}' instead of the spelling '{1}' " + "of the incoming token kind '{2}'", + source_text[position], kind.fixed_spelling(), kind); int32_t byte_offset = position; ++position; @@ -1204,7 +1204,7 @@ auto Lexer::LexKeywordOrIdentifier(llvm::StringRef source_text, // Take the valid characters off the front of the source buffer. llvm::StringRef identifier_text = ScanForIdentifierPrefix(source_text.substr(position)); - CARBON_CHECK(!identifier_text.empty()) << "Must have at least one character!"; + CARBON_CHECK(!identifier_text.empty(), "Must have at least one character!"); position += identifier_text.size(); // Check if the text is a type literal, and if so form such a literal. @@ -1255,7 +1255,7 @@ auto Lexer::LexHash(llvm::StringRef source_text, ssize_t& position) // Take the valid characters off the front of the source buffer. llvm::StringRef identifier_text = ScanForIdentifierPrefix(source_text.substr(position + 1)); - CARBON_CHECK(!identifier_text.empty()) << "Must have at least one character!"; + CARBON_CHECK(!identifier_text.empty(), "Must have at least one character!"); position += 1 + identifier_text.size(); // Replace the `r` identifier's value with the raw identifier. @@ -1359,14 +1359,14 @@ class Lexer::ErrorRecoveryBuffer { // currently require insertions to be specified in source order, but this // restriction would be easy to relax. auto InsertBefore(TokenIndex insert_before, TokenKind kind) -> void { - CARBON_CHECK(insert_before.index > 0) - << "Cannot insert before the start of file token."; - CARBON_CHECK(insert_before.index < - static_cast(buffer_.token_infos_.size())) - << "Cannot insert after the end of file token."; - CARBON_CHECK(new_tokens_.empty() || - new_tokens_.back().first <= insert_before) - << "Insertions performed out of order."; + CARBON_CHECK(insert_before.index > 0, + "Cannot insert before the start of file token."); + CARBON_CHECK( + insert_before.index < static_cast(buffer_.token_infos_.size()), + "Cannot insert after the end of file token."); + CARBON_CHECK( + new_tokens_.empty() || new_tokens_.back().first <= insert_before, + "Insertions performed out of order."); // If the `insert_before` token has leading whitespace, mark the // inserted token as also having leading whitespace. This avoids changing @@ -1423,12 +1423,12 @@ class Lexer::ErrorRecoveryBuffer { if (kind.is_opening_symbol()) { open_groups.push_back(token); } else if (kind.is_closing_symbol()) { - CARBON_CHECK(!open_groups.empty()) << "Failed to balance brackets"; + CARBON_CHECK(!open_groups.empty(), "Failed to balance brackets"); auto opening_token = open_groups.pop_back_val(); CARBON_CHECK( - kind == buffer_.GetTokenInfo(opening_token).kind().closing_symbol()) - << "Failed to balance brackets"; + kind == buffer_.GetTokenInfo(opening_token).kind().closing_symbol(), + "Failed to balance brackets"); auto& opening_token_info = buffer_.GetTokenInfo(opening_token); auto& closing_token_info = buffer_.GetTokenInfo(token); opening_token_info.set_closing_token_index(token); @@ -1530,7 +1530,7 @@ auto Lexer::DiagnoseAndFixMismatchedBrackets() -> void { fixes.ReplaceWithError(token); } - CARBON_CHECK(!fixes.empty()) << "Didn't find anything to fix"; + CARBON_CHECK(!fixes.empty(), "Didn't find anything to fix"); fixes.Apply(); fixes.FixTokenCrossReferences(); } diff --git a/toolchain/lex/numeric_literal.cpp b/toolchain/lex/numeric_literal.cpp index 88f452d2dc0f..8b78e2b01a68 100644 --- a/toolchain/lex/numeric_literal.cpp +++ b/toolchain/lex/numeric_literal.cpp @@ -82,7 +82,7 @@ auto NumericLiteral::Lex(llvm::StringRef source_text) IsAlnum(source_text[i + 1])) { // This is not possible because we don't update result.exponent after we // see a '+' or '-'. - CARBON_CHECK(!seen_plus_minus) << "should only consume one + or -"; + CARBON_CHECK(!seen_plus_minus, "should only consume one + or -"); seen_plus_minus = true; continue; } diff --git a/toolchain/lex/string_literal.cpp b/toolchain/lex/string_literal.cpp index 718e578980b8..f32ff8b5c31f 100644 --- a/toolchain/lex/string_literal.cpp +++ b/toolchain/lex/string_literal.cpp @@ -282,7 +282,7 @@ static auto AppendFrontOfContents(char*& buffer_cursor, static auto ExpandAndConsumeEscapeSequence(LexerDiagnosticEmitter& emitter, llvm::StringRef& content, char*& buffer_cursor) -> void { - CARBON_CHECK(!content.empty()) << "should have escaped closing delimiter"; + CARBON_CHECK(!content.empty(), "should have escaped closing delimiter"); char first = content.front(); content = content.drop_front(1); @@ -424,8 +424,8 @@ static auto ExpandEscapeSequencesAndRemoveIndent( if (IsHorizontalWhitespace(contents.front())) { // Horizontal whitespace other than ` ` is valid only at the end of a // line. - CARBON_CHECK(contents.front() != ' ') - << "should not have stopped at a plain space"; + CARBON_CHECK(contents.front() != ' ', + "should not have stopped at a plain space"); auto after_space = contents.find_if_not(IsHorizontalWhitespace); if (after_space == llvm::StringRef::npos || contents[after_space] != '\n') { @@ -487,9 +487,9 @@ auto StringLiteral::ComputeValue(llvm::BumpPtrAllocator& allocator, auto result = ExpandEscapeSequencesAndRemoveIndent( emitter, content_, hash_level_, indent, allocator.Allocate(content_.size())); - CARBON_CHECK(result.size() <= content_.size()) - << "Content grew from " << content_.size() << " to " << result.size() - << ": `" << content_ << "`"; + CARBON_CHECK(result.size() <= content_.size(), + "Content grew from {0} to {1}: `{2}`", content_.size(), + result.size(), content_); return result; } diff --git a/toolchain/lex/test_helpers.h b/toolchain/lex/test_helpers.h index b1eae9238d53..88bfa4f9d18c 100644 --- a/toolchain/lex/test_helpers.h +++ b/toolchain/lex/test_helpers.h @@ -26,8 +26,8 @@ class SingleTokenDiagnosticConverter : public DiagnosticConverter { auto ConvertLoc(const char* pos, ContextFnT /*context_fn*/) const -> DiagnosticLoc override { - CARBON_CHECK(StringRefContainsPointer(token_, pos)) - << "invalid diagnostic location"; + CARBON_CHECK(StringRefContainsPointer(token_, pos), + "invalid diagnostic location"); llvm::StringRef prefix = token_.take_front(pos - token_.begin()); auto [before_last_newline, this_line] = prefix.rsplit('\n'); if (before_last_newline.size() == prefix.size()) { diff --git a/toolchain/lex/token_kind.h b/toolchain/lex/token_kind.h index abe69dfd0c4f..bfe1a49fcebf 100644 --- a/toolchain/lex/token_kind.h +++ b/toolchain/lex/token_kind.h @@ -56,7 +56,7 @@ class TokenKind : public CARBON_ENUM_BASE(TokenKind) { // The token kind must be an opening symbol. auto closing_symbol() const -> TokenKind { auto result = ClosingSymbol[AsInt()]; - CARBON_DCHECK(result != Error) << "Only opening symbols are valid!"; + CARBON_DCHECK(result != Error, "Only opening symbols are valid!"); return result; } @@ -68,7 +68,7 @@ class TokenKind : public CARBON_ENUM_BASE(TokenKind) { // The token kind must be a closing symbol. auto opening_symbol() const -> TokenKind { auto result = OpeningSymbol[AsInt()]; - CARBON_DCHECK(result != Error) << "Only closing symbols are valid!"; + CARBON_DCHECK(result != Error, "Only closing symbols are valid!"); return result; } diff --git a/toolchain/lex/tokenized_buffer.cpp b/toolchain/lex/tokenized_buffer.cpp index 66c3d8ad3f33..d6eccc6fdcae 100644 --- a/toolchain/lex/tokenized_buffer.cpp +++ b/toolchain/lex/tokenized_buffer.cpp @@ -75,7 +75,7 @@ auto TokenizedBuffer::GetTokenText(TokenIndex token) const -> llvm::StringRef { token_info.kind() == TokenKind::RealLiteral) { std::optional relexed_token = NumericLiteral::Lex(source_->text().substr(token_info.byte_offset())); - CARBON_CHECK(relexed_token) << "Could not reform numeric literal token."; + CARBON_CHECK(relexed_token, "Could not reform numeric literal token."); return relexed_token->text(); } @@ -84,7 +84,7 @@ auto TokenizedBuffer::GetTokenText(TokenIndex token) const -> llvm::StringRef { if (token_info.kind() == TokenKind::StringLiteral) { std::optional relexed_token = StringLiteral::Lex(source_->text().substr(token_info.byte_offset())); - CARBON_CHECK(relexed_token) << "Could not reform string literal token."; + CARBON_CHECK(relexed_token, "Could not reform string literal token."); return relexed_token->text(); } @@ -102,56 +102,60 @@ auto TokenizedBuffer::GetTokenText(TokenIndex token) const -> llvm::StringRef { return llvm::StringRef(); } - CARBON_CHECK(token_info.kind() == TokenKind::Identifier) << token_info.kind(); + CARBON_CHECK(token_info.kind() == TokenKind::Identifier, "{0}", + token_info.kind()); return value_stores_->identifiers().Get(token_info.ident_id()); } auto TokenizedBuffer::GetIdentifier(TokenIndex token) const -> IdentifierId { const auto& token_info = GetTokenInfo(token); - CARBON_CHECK(token_info.kind() == TokenKind::Identifier) << token_info.kind(); + CARBON_CHECK(token_info.kind() == TokenKind::Identifier, "{0}", + token_info.kind()); return token_info.ident_id(); } auto TokenizedBuffer::GetIntLiteral(TokenIndex token) const -> IntId { const auto& token_info = GetTokenInfo(token); - CARBON_CHECK(token_info.kind() == TokenKind::IntLiteral) << token_info.kind(); + CARBON_CHECK(token_info.kind() == TokenKind::IntLiteral, "{0}", + token_info.kind()); return token_info.int_id(); } auto TokenizedBuffer::GetRealLiteral(TokenIndex token) const -> RealId { const auto& token_info = GetTokenInfo(token); - CARBON_CHECK(token_info.kind() == TokenKind::RealLiteral) - << token_info.kind(); + CARBON_CHECK(token_info.kind() == TokenKind::RealLiteral, "{0}", + token_info.kind()); return token_info.real_id(); } auto TokenizedBuffer::GetStringLiteralValue(TokenIndex token) const -> StringLiteralValueId { const auto& token_info = GetTokenInfo(token); - CARBON_CHECK(token_info.kind() == TokenKind::StringLiteral) - << token_info.kind(); + CARBON_CHECK(token_info.kind() == TokenKind::StringLiteral, "{0}", + token_info.kind()); return token_info.string_literal_id(); } auto TokenizedBuffer::GetTypeLiteralSize(TokenIndex token) const -> IntId { const auto& token_info = GetTokenInfo(token); - CARBON_CHECK(token_info.kind().is_sized_type_literal()) << token_info.kind(); + CARBON_CHECK(token_info.kind().is_sized_type_literal(), "{0}", + token_info.kind()); return token_info.int_id(); } auto TokenizedBuffer::GetMatchedClosingToken(TokenIndex opening_token) const -> TokenIndex { const auto& opening_token_info = GetTokenInfo(opening_token); - CARBON_CHECK(opening_token_info.kind().is_opening_symbol()) - << opening_token_info.kind(); + CARBON_CHECK(opening_token_info.kind().is_opening_symbol(), "{0}", + opening_token_info.kind()); return opening_token_info.closing_token_index(); } auto TokenizedBuffer::GetMatchedOpeningToken(TokenIndex closing_token) const -> TokenIndex { const auto& closing_token_info = GetTokenInfo(closing_token); - CARBON_CHECK(closing_token_info.kind().is_closing_symbol()) - << closing_token_info.kind(); + CARBON_CHECK(closing_token_info.kind().is_closing_symbol(), "{0}", + closing_token_info.kind()); return closing_token_info.opening_token_index(); } @@ -205,7 +209,7 @@ auto TokenizedBuffer::PrintWidths::Widen(const PrintWidths& widths) -> void { // // This routine requires its argument to be *non-negative*. static auto ComputeDecimalPrintedWidth(int number) -> int { - CARBON_CHECK(number >= 0) << "Negative numbers are not supported."; + CARBON_CHECK(number >= 0, "Negative numbers are not supported."); if (number == 0) { return 1; } @@ -382,8 +386,8 @@ auto TokenIterator::Print(llvm::raw_ostream& output) const -> void { auto TokenizedBuffer::SourceBufferDiagnosticConverter::ConvertLoc( const char* loc, ContextFnT /*context_fn*/) const -> DiagnosticLoc { - CARBON_CHECK(StringRefContainsPointer(buffer_->source_->text(), loc)) - << "location not within buffer"; + CARBON_CHECK(StringRefContainsPointer(buffer_->source_->text(), loc), + "location not within buffer"); int32_t offset = loc - buffer_->source_->text().begin(); // Find the first line starting after the given location. @@ -392,8 +396,8 @@ auto TokenizedBuffer::SourceBufferDiagnosticConverter::ConvertLoc( [offset](const LineInfo& line) { return line.start <= offset; }); // Step back one line to find the line containing the given position. - CARBON_CHECK(next_line_it != buffer_->line_infos_.begin()) - << "location precedes the start of the first line"; + CARBON_CHECK(next_line_it != buffer_->line_infos_.begin(), + "location precedes the start of the first line"); const auto* line_it = std::prev(next_line_it); int line_number = line_it - buffer_->line_infos_.begin(); int column_number = offset - line_it->start; diff --git a/toolchain/lex/tokenized_buffer.h b/toolchain/lex/tokenized_buffer.h index ebf12855d772..da2ca1d1f18a 100644 --- a/toolchain/lex/tokenized_buffer.h +++ b/toolchain/lex/tokenized_buffer.h @@ -399,8 +399,8 @@ class TokenizedBuffer : public Printable { has_leading_space_(has_leading_space), token_payload_(payload), byte_offset_(byte_offset) { - CARBON_DCHECK(payload >= 0 && payload < (2 << PayloadBits)) - << "Payload won't fit into unsigned bit pack: " << payload; + CARBON_DCHECK(payload >= 0 && payload < (2 << PayloadBits), + "Payload won't fit into unsigned bit pack: {0}", payload); } // A bitfield that encodes the token's kind, the leading space flag, and the diff --git a/toolchain/lex/tokenized_buffer_benchmark.cpp b/toolchain/lex/tokenized_buffer_benchmark.cpp index 37252ee7a989..7e9d5099c1a6 100644 --- a/toolchain/lex/tokenized_buffer_benchmark.cpp +++ b/toolchain/lex/tokenized_buffer_benchmark.cpp @@ -85,9 +85,10 @@ struct RandomSourceOptions { string_literal_percent)); CARBON_CHECK(tokens_per_line <= NumTokens); - CARBON_CHECK(NumTokens % tokens_per_line == 0) - << "Tokens per line of " << tokens_per_line - << " does not divide the number of tokens " << NumTokens; + CARBON_CHECK( + NumTokens % tokens_per_line == 0, + "Tokens per line of {0} does not divide the number of tokens {1}", + tokens_per_line, NumTokens); CARBON_CHECK(is_percentage(comment_line_percent)); CARBON_CHECK(is_percentage(blank_line_percent)); @@ -142,10 +143,10 @@ auto RandomSource(RandomSourceOptions options) -> std::string { int num_symbols = (NumTokens / 100) * options.symbol_percent; int num_keywords = (NumTokens / 100) * options.keyword_percent; int num_identifiers = NumTokens - num_symbols - num_keywords; - CARBON_CHECK(num_identifiers == 0 || num_identifiers > 500) - << "We require at least 500 identifiers as we need to collect a " - "reasonable number of samples to end up with a reasonable " - "distribution of lengths."; + CARBON_CHECK( + num_identifiers == 0 || num_identifiers > 500, + "We require at least 500 identifiers as we need to collect a reasonable " + "number of samples to end up with a reasonable distribution of lengths."); llvm::SmallVector ids = Testing::SourceGen::Global().GetIdentifiers(num_identifiers); @@ -221,8 +222,8 @@ class LexerBenchHelper { StreamDiagnosticConsumer consumer(out); auto buffer = Lex::Lex(value_stores_, source_, consumer); consumer.Flush(); - CARBON_CHECK(buffer.has_errors()) - << "Asked to diagnose errors but none found!"; + CARBON_CHECK(buffer.has_errors(), + "Asked to diagnose errors but none found!"); return result; } @@ -332,7 +333,7 @@ void BM_ValidIdentifiers(benchmark::State& state) { LexerBenchHelper helper(source); for (auto _ : state) { TokenizedBuffer buffer = helper.Lex(); - CARBON_CHECK(!buffer.has_errors()) << helper.DiagnoseErrors(); + CARBON_CHECK(!buffer.has_errors(), "{0}", helper.DiagnoseErrors()); } state.SetBytesProcessed(state.iterations() * source.size()); @@ -370,7 +371,7 @@ void BM_HorizontalWhitespace(benchmark::State& state) { // Ensure that lexing actually occurs for benchmarking and that it doesn't // hit errors that would skew the benchmark results. - CARBON_CHECK(!buffer.has_errors()) << helper.DiagnoseErrors(); + CARBON_CHECK(!buffer.has_errors(), "{0}", helper.DiagnoseErrors()); } state.SetBytesProcessed(state.iterations() * source.size()); @@ -388,7 +389,7 @@ void BM_RandomSource(benchmark::State& state) { // Ensure that lexing actually occurs for benchmarking and that it doesn't // hit errors that would skew the benchmark results. - CARBON_CHECK(!buffer.has_errors()) << helper.DiagnoseErrors(); + CARBON_CHECK(!buffer.has_errors(), "{0}", helper.DiagnoseErrors()); } state.SetBytesProcessed(state.iterations() * source.size()); @@ -454,7 +455,7 @@ void BM_GroupingSymbols(benchmark::State& state) { // Ensure that lexing actually occurs for benchmarking and that it doesn't // hit errors that would skew the benchmark results. - CARBON_CHECK(!buffer.has_errors()) << helper.DiagnoseErrors(); + CARBON_CHECK(!buffer.has_errors(), "{0}", helper.DiagnoseErrors()); } state.SetBytesProcessed(state.iterations() * source.size()); @@ -504,7 +505,7 @@ void BM_BlankLines(benchmark::State& state) { // Ensure that lexing actually occurs for benchmarking and that it doesn't // hit errors that would skew the benchmark results. - CARBON_CHECK(!buffer.has_errors()) << helper.DiagnoseErrors(); + CARBON_CHECK(!buffer.has_errors(), "{0}", helper.DiagnoseErrors()); } state.SetBytesProcessed(state.iterations() * source.size()); @@ -539,7 +540,7 @@ void BM_CommentLines(benchmark::State& state) { // Ensure that lexing actually occurs for benchmarking and that it doesn't // hit errors that would skew the benchmark results. - CARBON_CHECK(!buffer.has_errors()) << helper.DiagnoseErrors(); + CARBON_CHECK(!buffer.has_errors(), "{0}", helper.DiagnoseErrors()); } state.SetBytesProcessed(state.iterations() * source.size()); diff --git a/toolchain/lex/tokenized_buffer_fuzzer.cpp b/toolchain/lex/tokenized_buffer_fuzzer.cpp index 56fa689a91a1..986b69e7a1bb 100644 --- a/toolchain/lex/tokenized_buffer_fuzzer.cpp +++ b/toolchain/lex/tokenized_buffer_fuzzer.cpp @@ -47,11 +47,11 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, // token stream. for (Lex::TokenIndex token : buffer.tokens()) { int line_number = buffer.GetLineNumber(token); - CARBON_CHECK(line_number > 0) << "Invalid line number!"; - CARBON_CHECK(line_number < INT_MAX) << "Invalid line number!"; + CARBON_CHECK(line_number > 0, "Invalid line number!"); + CARBON_CHECK(line_number < INT_MAX, "Invalid line number!"); int column_number = buffer.GetColumnNumber(token); - CARBON_CHECK(column_number > 0) << "Invalid line number!"; - CARBON_CHECK(column_number < INT_MAX) << "Invalid line number!"; + CARBON_CHECK(column_number > 0, "Invalid line number!"); + CARBON_CHECK(column_number < INT_MAX, "Invalid line number!"); } return 0; diff --git a/toolchain/lower/constant.cpp b/toolchain/lower/constant.cpp index 13376fe8cd5e..26238f2d7598 100644 --- a/toolchain/lower/constant.cpp +++ b/toolchain/lower/constant.cpp @@ -30,14 +30,15 @@ class ConstantContext { // Gets the lowered constant value for a constant that has already been // lowered. auto GetConstant(SemIR::ConstantId const_id) const -> llvm::Constant* { - CARBON_CHECK(const_id.is_template()) - << "Unexpected constant ID " << const_id; + CARBON_CHECK(const_id.is_template(), "Unexpected constant ID {0}", + const_id); auto inst_id = file_context_->sem_ir().constant_values().GetInstId(const_id); - CARBON_CHECK(inst_id.index >= 0 && - inst_id.index <= last_lowered_constant_index_) - << "Queried constant " << const_id << " with instruction " << inst_id - << " that has not been lowered yet"; + CARBON_CHECK( + inst_id.index >= 0 && inst_id.index <= last_lowered_constant_index_, + "Queried constant {0} with instruction {1} that has not been lowered " + "yet", + const_id, inst_id); return constants_[inst_id.index]; } @@ -109,7 +110,7 @@ template InstT::Kind.constant_kind() == SemIR::InstConstantKind::SymbolicOnly) static auto EmitAsConstant(ConstantContext& /*context*/, InstT inst) -> llvm::Constant* { - CARBON_FATAL() << "Unexpected constant instruction kind " << inst; + CARBON_FATAL("Unexpected constant instruction kind {0}", inst); } // For constants that are always of type `type`, produce the trivial runtime @@ -147,7 +148,7 @@ static auto EmitAsConstant(ConstantContext& /*context*/, SemIR::AddrOf /*inst*/) -> llvm::Constant* { // TODO: Constant lvalue support. For now we have no constant lvalues, so we // should never form a constant AddrOf. - CARBON_FATAL() << "AddrOf constants not supported yet"; + CARBON_FATAL("AddrOf constants not supported yet"); } static auto EmitAsConstant(ConstantContext& context, @@ -204,7 +205,7 @@ static auto EmitAsConstant(ConstantContext& context, SemIR::Namespace inst) static auto EmitAsConstant(ConstantContext& /*context*/, SemIR::StringLiteral inst) -> llvm::Constant* { - CARBON_FATAL() << "TODO: Add support: " << inst; + CARBON_FATAL("TODO: Add support: {0}", inst); } static auto EmitAsConstant(ConstantContext& /*context*/, diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index a4adbbb340f9..a78464fc8ca8 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -38,13 +38,13 @@ FileContext::FileContext(llvm::LLVMContext& llvm_context, sem_ir_(&sem_ir), inst_namer_(inst_namer), vlog_stream_(vlog_stream) { - CARBON_CHECK(!sem_ir.has_errors()) - << "Generating LLVM IR from invalid SemIR::File is unsupported."; + CARBON_CHECK(!sem_ir.has_errors(), + "Generating LLVM IR from invalid SemIR::File is unsupported."); } // TODO: Move this to lower.cpp. auto FileContext::Run() -> std::unique_ptr { - CARBON_CHECK(llvm_module_) << "Run can only be called once."; + CARBON_CHECK(llvm_module_, "Run can only be called once."); // Lower all types that were required to be complete. types_.resize(sem_ir_->insts().size()); @@ -157,8 +157,8 @@ auto FileContext::GetGlobal(SemIR::InstId inst_id) -> llvm::Value* { // TODO: For generics, handle references to symbolic constants. - CARBON_FATAL() << "Missing value: " << inst_id << " " - << sem_ir().insts().Get(inst_id); + CARBON_FATAL("Missing value: {0} {1}", inst_id, + sem_ir().insts().Get(inst_id)); } auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id) @@ -187,7 +187,7 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id) const auto return_info = SemIR::ReturnTypeInfo::ForFunction(sem_ir(), function, specific_id); - CARBON_CHECK(return_info.is_valid()) << "Should not lower invalid functions."; + CARBON_CHECK(return_info.is_valid(), "Should not lower invalid functions."); auto implicit_param_refs = sem_ir().inst_blocks().GetOrEmpty(function.implicit_param_refs_id); @@ -219,8 +219,7 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id) switch (auto value_rep = SemIR::ValueRepr::ForType(sem_ir(), param_type_id); value_rep.kind) { case SemIR::ValueRepr::Unknown: - CARBON_FATAL() - << "Incomplete parameter type lowering function declaration"; + CARBON_FATAL("Incomplete parameter type lowering function declaration"); case SemIR::ValueRepr::None: break; case SemIR::ValueRepr::Copy: @@ -364,8 +363,8 @@ auto FileContext::BuildDISubprogram(const SemIR::Function& function, return nullptr; } auto name = sem_ir().names().GetAsStringIfIdentifier(function.name_id); - CARBON_CHECK(name) << "Unexpected special name for function: " - << function.name_id; + CARBON_CHECK(name, "Unexpected special name for function: {0}", + function.name_id); auto loc = GetLocForDI(function.definition_id); // FIXME: Add more details here, including real subroutine type (once type // information is built), etc. @@ -390,7 +389,7 @@ static auto BuildTypeForInst(FileContext& context, SemIR::BuiltinInst inst) -> llvm::Type* { switch (inst.builtin_inst_kind) { case SemIR::BuiltinInstKind::Invalid: - CARBON_FATAL() << "Unexpected builtin type in lowering."; + CARBON_FATAL("Unexpected builtin type in lowering."); case SemIR::BuiltinInstKind::Error: // This is a complete type but uses of it should never be lowered. return nullptr; @@ -423,7 +422,7 @@ template requires(InstT::Kind.is_type() == SemIR::InstIsType::Never) static auto BuildTypeForInst(FileContext& /*context*/, InstT inst) -> llvm::Type* { - CARBON_FATAL() << "Cannot use inst as type: " << inst; + CARBON_FATAL("Cannot use inst as type: {0}", inst); } static auto BuildTypeForInst(FileContext& context, SemIR::ClassType inst) @@ -448,7 +447,7 @@ static auto BuildTypeForInst(FileContext& context, SemIR::IntType inst) -> llvm::Type* { auto width = context.sem_ir().insts().TryGetAs(inst.bit_width_id); - CARBON_CHECK(width) << "Can't lower int type with symbolic width"; + CARBON_CHECK(width, "Can't lower int type with symbolic width"); return llvm::IntegerType::get( context.llvm_context(), context.sem_ir().ints().Get(width->int_id).getZExtValue()); diff --git a/toolchain/lower/file_context.h b/toolchain/lower/file_context.h index 989a7ebfe154..644602ef4086 100644 --- a/toolchain/lower/file_context.h +++ b/toolchain/lower/file_context.h @@ -50,8 +50,8 @@ class FileContext { // Returns a lowered type for the given type_id. auto GetType(SemIR::TypeId type_id) -> llvm::Type* { // InvalidType should not be passed in. - CARBON_CHECK(type_id.index >= 0) << type_id; - CARBON_CHECK(types_[type_id.index]) << "Missing type " << type_id; + CARBON_CHECK(type_id.index >= 0, "{0}", type_id); + CARBON_CHECK(types_[type_id.index], "Missing type {0}", type_id); return types_[type_id.index]; } diff --git a/toolchain/lower/function_context.cpp b/toolchain/lower/function_context.cpp index 8cfa1f606096..3a9df72e6577 100644 --- a/toolchain/lower/function_context.cpp +++ b/toolchain/lower/function_context.cpp @@ -66,15 +66,14 @@ template static auto LowerInstHelper(FunctionContext& context, SemIR::InstId inst_id, InstT inst) { if constexpr (!InstT::Kind.is_lowered()) { - CARBON_FATAL() - << "Encountered an instruction that isn't expected to lower. It's " - "possible that logic needs to be changed in order to stop " - "showing this instruction in lowered contexts. Instruction: " - << inst; + CARBON_FATAL( + "Encountered an instruction that isn't expected to lower. It's " + "possible that logic needs to be changed in order to stop showing this " + "instruction in lowered contexts. Instruction: {0}", + inst); } else if constexpr (InstT::Kind.constant_kind() == SemIR::InstConstantKind::Always) { - CARBON_FATAL() << "Missing constant value for constant instruction " - << inst; + CARBON_FATAL("Missing constant value for constant instruction {0}", inst); } else if constexpr (InstT::Kind.is_type() == SemIR::InstIsType::Always) { // For instructions that are always of type `type`, produce the trivial // runtime representation of type `type`. @@ -99,9 +98,9 @@ auto FunctionContext::LowerInst(SemIR::InstId inst_id) -> void { builder_.getInserter().SetCurrentInstId(inst_id); if (di_subprogram_) { auto loc = file_context_->GetLocForDI(inst_id); - CARBON_CHECK(loc.filename == di_subprogram_->getFile()->getFilename()) - << "Instructions located in a different file from their enclosing " - "function aren't handled yet"; + CARBON_CHECK(loc.filename == di_subprogram_->getFile()->getFilename(), + "Instructions located in a different file from their " + "enclosing function aren't handled yet"); builder_.SetCurrentDebugLocation( llvm::DILocation::get(builder_.getContext(), loc.line_number, loc.column_number, di_subprogram_)); @@ -129,9 +128,9 @@ auto FunctionContext::GetBlockArg(SemIR::InstBlockId block_id, // Find the existing phi, if any. auto phis = block->phis(); if (!phis.empty()) { - CARBON_CHECK(std::next(phis.begin()) == phis.end()) - << "Expected at most one phi, found " - << std::distance(phis.begin(), phis.end()); + CARBON_CHECK(std::next(phis.begin()) == phis.end(), + "Expected at most one phi, found {0}", + std::distance(phis.begin(), phis.end())); return &*phis.begin(); } @@ -163,8 +162,8 @@ auto FunctionContext::FinishInit(SemIR::TypeId type_id, SemIR::InstId dest_id, CopyValue(type_id, source_id, dest_id); break; case SemIR::InitRepr::Incomplete: - CARBON_FATAL() << "Lowering aggregate initialization of incomplete type " - << sem_ir().types().GetAsInst(type_id); + CARBON_FATAL("Lowering aggregate initialization of incomplete type {0}", + sem_ir().types().GetAsInst(type_id)); } } @@ -172,7 +171,7 @@ auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id, SemIR::InstId dest_id) -> void { switch (auto rep = SemIR::ValueRepr::ForType(sem_ir(), type_id); rep.kind) { case SemIR::ValueRepr::Unknown: - CARBON_FATAL() << "Attempt to copy incomplete type"; + CARBON_FATAL("Attempt to copy incomplete type"); case SemIR::ValueRepr::None: break; case SemIR::ValueRepr::Copy: @@ -182,7 +181,7 @@ auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id, CopyObject(type_id, source_id, dest_id); break; case SemIR::ValueRepr::Custom: - CARBON_FATAL() << "TODO: Add support for CopyValue with custom value rep"; + CARBON_FATAL("TODO: Add support for CopyValue with custom value rep"); } } diff --git a/toolchain/lower/function_context.h b/toolchain/lower/function_context.h index 0440ec0ee45c..8bdd6d73bf49 100644 --- a/toolchain/lower/function_context.h +++ b/toolchain/lower/function_context.h @@ -63,8 +63,8 @@ class FunctionContext { // Sets the value for the given instruction. auto SetLocal(SemIR::InstId inst_id, llvm::Value* value) { bool added = locals_.Insert(inst_id, value).is_inserted(); - CARBON_CHECK(added) << "Duplicate local insert: " << inst_id << " " - << sem_ir().insts().Get(inst_id); + CARBON_CHECK(added, "Duplicate local insert: {0} {1}", inst_id, + sem_ir().insts().Get(inst_id)); } // Gets a callable's function. diff --git a/toolchain/lower/handle.cpp b/toolchain/lower/handle.cpp index f24cb6dcfcbb..f06ab81a3a5f 100644 --- a/toolchain/lower/handle.cpp +++ b/toolchain/lower/handle.cpp @@ -26,7 +26,7 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, SemIR::AddrPattern /*inst*/) -> void { - CARBON_FATAL() << "`addr` should be lowered by `BuildFunctionDefinition`"; + CARBON_FATAL("`addr` should be lowered by `BuildFunctionDefinition`"); } auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, @@ -140,8 +140,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/, context.TryToReuseBlock(inst.target_id, block)) { // Reuse this block as the branch target. phi_predecessor = block->getSinglePredecessor(); - CARBON_CHECK(phi_predecessor) - << "Synthetic block did not have a single predecessor"; + CARBON_CHECK(phi_predecessor, + "Synthetic block did not have a single predecessor"); } else { context.builder().CreateBr(context.GetBlock(inst.target_id)); } @@ -184,7 +184,7 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, SemIR::Param /*inst*/) -> void { - CARBON_FATAL() << "Parameters should be lowered by `BuildFunctionDefinition`"; + CARBON_FATAL("Parameters should be lowered by `BuildFunctionDefinition`"); } auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/, @@ -209,8 +209,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/, context.builder().CreateRet(context.GetValue(inst.expr_id)); return; case SemIR::InitRepr::Incomplete: - CARBON_FATAL() << "Lowering return of incomplete type " - << context.sem_ir().types().GetAsInst(result_type_id); + CARBON_FATAL("Lowering return of incomplete type {0}", + context.sem_ir().types().GetAsInst(result_type_id)); } } diff --git a/toolchain/lower/handle_aggregates.cpp b/toolchain/lower/handle_aggregates.cpp index 40fac01fa2e7..e8cb49448f16 100644 --- a/toolchain/lower/handle_aggregates.cpp +++ b/toolchain/lower/handle_aggregates.cpp @@ -34,16 +34,16 @@ static auto GetAggregateElement(FunctionContext& context, case SemIR::ExprCategory::NotExpr: case SemIR::ExprCategory::Initializing: case SemIR::ExprCategory::Mixed: - CARBON_FATAL() << "Unexpected expression category for aggregate access"; + CARBON_FATAL("Unexpected expression category for aggregate access"); case SemIR::ExprCategory::Value: { auto value_rep = SemIR::ValueRepr::ForType(context.sem_ir(), aggr_inst.type_id()); - CARBON_CHECK(value_rep.aggregate_kind != SemIR::ValueRepr::NotAggregate) - << "aggregate type should have aggregate value representation"; + CARBON_CHECK(value_rep.aggregate_kind != SemIR::ValueRepr::NotAggregate, + "aggregate type should have aggregate value representation"); switch (value_rep.kind) { case SemIR::ValueRepr::Unknown: - CARBON_FATAL() << "Lowering access to incomplete aggregate type"; + CARBON_FATAL("Lowering access to incomplete aggregate type"); case SemIR::ValueRepr::None: return aggr_value; case SemIR::ValueRepr::Copy: @@ -73,8 +73,8 @@ static auto GetAggregateElement(FunctionContext& context, context.GetType(result_value_type_id), elem_ptr, name + ".load"); } case SemIR::ValueRepr::Custom: - CARBON_FATAL() - << "Aggregate should never have custom value representation"; + CARBON_FATAL( + "Aggregate should never have custom value representation"); } } @@ -132,8 +132,9 @@ static auto EmitAggregateInitializer(FunctionContext& context, case SemIR::InitRepr::ByCopy: { auto refs = context.sem_ir().inst_blocks().Get(refs_id); - CARBON_CHECK(refs.size() == 1) - << "Unexpected size for aggregate with by-copy value representation"; + CARBON_CHECK( + refs.size() == 1, + "Unexpected size for aggregate with by-copy value representation"); // TODO: Remove the LLVM StructType wrapper in this case, so we don't // need this `insert_value` wrapping. return context.builder().CreateInsertValue( @@ -142,8 +143,8 @@ static auto EmitAggregateInitializer(FunctionContext& context, } case SemIR::InitRepr::Incomplete: - CARBON_FATAL() << "Lowering aggregate initialization of incomplete type " - << context.sem_ir().types().GetAsInst(type_id); + CARBON_FATAL("Lowering aggregate initialization of incomplete type {0}", + context.sem_ir().types().GetAsInst(type_id)); } } @@ -177,7 +178,7 @@ static auto EmitAggregateValueRepr(FunctionContext& context, auto value_rep = SemIR::ValueRepr::ForType(context.sem_ir(), type_id); switch (value_rep.kind) { case SemIR::ValueRepr::Unknown: - CARBON_FATAL() << "Incomplete aggregate type in lowering"; + CARBON_FATAL("Incomplete aggregate type in lowering"); case SemIR::ValueRepr::None: // TODO: Add a helper to get a "no value representation" value. @@ -185,8 +186,9 @@ static auto EmitAggregateValueRepr(FunctionContext& context, case SemIR::ValueRepr::Copy: { auto refs = context.sem_ir().inst_blocks().Get(refs_id); - CARBON_CHECK(refs.size() == 1) - << "Unexpected size for aggregate with by-copy value representation"; + CARBON_CHECK( + refs.size() == 1, + "Unexpected size for aggregate with by-copy value representation"); // TODO: Remove the LLVM StructType wrapper in this case, so we don't // need this `insert_value` wrapping. return context.builder().CreateInsertValue( @@ -211,8 +213,7 @@ static auto EmitAggregateValueRepr(FunctionContext& context, } case SemIR::ValueRepr::Custom: - CARBON_FATAL() - << "Aggregate should never have custom value representation"; + CARBON_FATAL("Aggregate should never have custom value representation"); } } diff --git a/toolchain/lower/handle_call.cpp b/toolchain/lower/handle_call.cpp index d3281f1186d8..ab5ca0c259db 100644 --- a/toolchain/lower/handle_call.cpp +++ b/toolchain/lower/handle_call.cpp @@ -30,7 +30,7 @@ static auto GetBuiltinICmpPredicate(SemIR::BuiltinFunctionKind builtin_kind, case SemIR::BuiltinFunctionKind::IntGreaterEq: return is_signed ? llvm::CmpInst::ICMP_SGE : llvm::CmpInst::ICMP_UGE; default: - CARBON_FATAL() << "Unexpected builtin kind " << builtin_kind; + CARBON_FATAL("Unexpected builtin kind {0}", builtin_kind); } } @@ -52,7 +52,7 @@ static auto GetBuiltinFCmpPredicate(SemIR::BuiltinFunctionKind builtin_kind) case SemIR::BuiltinFunctionKind::FloatGreaterEq: return llvm::CmpInst::FCMP_OGE; default: - CARBON_FATAL() << "Unexpected builtin kind " << builtin_kind; + CARBON_FATAL("Unexpected builtin kind {0}", builtin_kind); } } @@ -74,7 +74,7 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id, // TODO: Move the instruction names here into InstNamer. switch (builtin_kind) { case SemIR::BuiltinFunctionKind::None: - CARBON_FATAL() << "No callee in function call."; + CARBON_FATAL("No callee in function call."); case SemIR::BuiltinFunctionKind::PrintInt: { llvm::Type* char_type[] = {llvm::PointerType::get( @@ -287,7 +287,7 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id, } } - CARBON_FATAL() << "Unsupported builtin call."; + CARBON_FATAL("Unsupported builtin call."); } auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, diff --git a/toolchain/lower/handle_expr_category.cpp b/toolchain/lower/handle_expr_category.cpp index 7a6739229a6b..87f5ac3cb8e0 100644 --- a/toolchain/lower/handle_expr_category.cpp +++ b/toolchain/lower/handle_expr_category.cpp @@ -12,8 +12,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, switch (auto rep = SemIR::ValueRepr::ForType(context.sem_ir(), inst.type_id); rep.kind) { case SemIR::ValueRepr::Unknown: - CARBON_FATAL() - << "Value binding for type with incomplete value representation"; + CARBON_FATAL( + "Value binding for type with incomplete value representation"); case SemIR::ValueRepr::None: // Nothing should use this value, but StubRef needs a value to // propagate. @@ -30,7 +30,7 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, context.SetLocal(inst_id, context.GetValue(inst.value_id)); break; case SemIR::ValueRepr::Custom: - CARBON_FATAL() << "TODO: Add support for BindValue with custom value rep"; + CARBON_FATAL("TODO: Add support for BindValue with custom value rep"); } } diff --git a/toolchain/lower/mangler.cpp b/toolchain/lower/mangler.cpp index 29cdc5737a33..5288f8609327 100644 --- a/toolchain/lower/mangler.cpp +++ b/toolchain/lower/mangler.cpp @@ -62,7 +62,7 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os, break; } default: - CARBON_FATAL() << "Attempting to mangle unsupported SemIR."; + CARBON_FATAL("Attempting to mangle unsupported SemIR."); break; } // Skip the tail of the loop that adds the parent name scope to the @@ -86,7 +86,7 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os, break; } default: - CARBON_FATAL() << "Attempting to mangle unsupported SemIR."; + CARBON_FATAL("Attempting to mangle unsupported SemIR."); break; } names_to_render.push_back( diff --git a/toolchain/parse/context.cpp b/toolchain/parse/context.cpp index 661c6153c7fb..3d9a557353a8 100644 --- a/toolchain/parse/context.cpp +++ b/toolchain/parse/context.cpp @@ -59,11 +59,11 @@ Context::Context(Tree& tree, Lex::TokenizedBuffer& tokens, vlog_stream_(vlog_stream), position_(tokens_->tokens().begin()), end_(tokens_->tokens().end()) { - CARBON_CHECK(position_ != end_) << "Empty TokenizedBuffer"; + CARBON_CHECK(position_ != end_, "Empty TokenizedBuffer"); --end_; - CARBON_CHECK(tokens_->GetKind(*end_) == Lex::TokenKind::FileEnd) - << "TokenizedBuffer should end with FileEnd, ended with " - << tokens_->GetKind(*end_); + CARBON_CHECK(tokens_->GetKind(*end_) == Lex::TokenKind::FileEnd, + "TokenizedBuffer should end with FileEnd, ended with {0}", + tokens_->GetKind(*end_)); } auto Context::AddLeafNode(NodeKind kind, Lex::TokenIndex token, bool has_error) @@ -79,8 +79,8 @@ auto Context::AddNode(NodeKind kind, Lex::TokenIndex token, bool has_error) auto Context::ReplacePlaceholderNode(int32_t position, NodeKind kind, Lex::TokenIndex token, bool has_error) -> void { - CARBON_CHECK(position >= 0 && position < tree_->size()) - << "position: " << position << " size: " << tree_->size(); + CARBON_CHECK(position >= 0 && position < tree_->size(), + "position: {0} size: {1}", position, tree_->size()); auto* node_impl = &tree_->node_impls_[position]; CARBON_CHECK(node_impl->kind == NodeKind::Placeholder); node_impl->kind = kind; @@ -138,8 +138,8 @@ auto Context::ConsumeAndAddLeafNodeIf(Lex::TokenKind token_kind, } auto Context::ConsumeChecked(Lex::TokenKind kind) -> Lex::TokenIndex { - CARBON_CHECK(PositionIs(kind)) - << "Required " << kind << ", found " << PositionKind(); + CARBON_CHECK(PositionIs(kind), "Required {0}, found {1}", kind, + PositionKind()); return Consume(); } @@ -230,10 +230,10 @@ auto Context::SkipPastLikelyEnd(Lex::TokenIndex skip_root) -> Lex::TokenIndex { } auto Context::SkipTo(Lex::TokenIndex t) -> void { - CARBON_CHECK(t >= *position_) << "Tried to skip backwards from " << position_ - << " to " << Lex::TokenIterator(t); + CARBON_CHECK(t >= *position_, "Tried to skip backwards from {0} to {1}", + position_, Lex::TokenIterator(t)); position_ = Lex::TokenIterator(t); - CARBON_CHECK(position_ != end_) << "Skipped past EOF."; + CARBON_CHECK(position_ != end_, "Skipped past EOF."); } // Determines whether the given token is considered to be the start of an @@ -265,7 +265,7 @@ static auto IsPossibleStartOfOperand(Lex::TokenKind kind) -> bool { } auto Context::IsLexicallyValidInfixOperator() -> bool { - CARBON_CHECK(position_ != end_) << "Expected an operator token."; + CARBON_CHECK(position_ != end_, "Expected an operator token."); bool leading_space = tokens().HasLeadingWhitespace(*position_); bool trailing_space = tokens().HasTrailingWhitespace(*position_); @@ -371,9 +371,8 @@ auto Context::ConsumeListToken(NodeKind comma_kind, Lex::TokenKind close_kind, // Recover from the invalid token. auto end_of_element = FindNextOf({Lex::TokenKind::Comma, close_kind}); // The lexer guarantees that parentheses are balanced. - CARBON_CHECK(end_of_element) - << "missing matching `" << close_kind.opening_symbol() << "` for `" - << close_kind << "`"; + CARBON_CHECK(end_of_element, "missing matching `{0}` for `{1}`", + close_kind.opening_symbol(), close_kind); SkipTo(*end_of_element); } diff --git a/toolchain/parse/context.h b/toolchain/parse/context.h index fe71bfc5b907..a8ae5b09b329 100644 --- a/toolchain/parse/context.h +++ b/toolchain/parse/context.h @@ -267,8 +267,8 @@ class Context { auto PushState(StateStackEntry state) -> void { CARBON_VLOG("Push {0}: {1}\n", state_stack_.size(), state); state_stack_.push_back(state); - CARBON_CHECK(state_stack_.size() < (1 << 20)) - << "Excessive stack size: likely infinite loop"; + CARBON_CHECK(state_stack_.size() < (1 << 20), + "Excessive stack size: likely infinite loop"); } // Pushes a constructed state onto the stack, with a different parse state. diff --git a/toolchain/parse/handle_expr.cpp b/toolchain/parse/handle_expr.cpp index 7e7068e90377..91b53c658dd0 100644 --- a/toolchain/parse/handle_expr.cpp +++ b/toolchain/parse/handle_expr.cpp @@ -350,8 +350,8 @@ auto HandleExprLoop(Context& context) -> void { #include "toolchain/parse/node_kind.def" default: - CARBON_FATAL() << "Unexpected token kind for postfix operator: " - << operator_kind; + CARBON_FATAL("Unexpected token kind for postfix operator: {0}", + operator_kind); } context.AddNode(node_kind, state.token, state.has_error); @@ -381,8 +381,7 @@ auto HandleExprLoopForInfixOperator(Context& context) -> void { #include "toolchain/parse/node_kind.def" default: - CARBON_FATAL() << "Unexpected token kind for infix operator: " - << token_kind; + CARBON_FATAL("Unexpected token kind for infix operator: {0}", token_kind); } } @@ -398,8 +397,8 @@ auto HandleExprLoopForPrefixOperator(Context& context) -> void { #include "toolchain/parse/node_kind.def" default: - CARBON_FATAL() << "Unexpected token kind for prefix operator: " - << token_kind; + CARBON_FATAL("Unexpected token kind for prefix operator: {0}", + token_kind); } } diff --git a/toolchain/parse/handle_paren_expr.cpp b/toolchain/parse/handle_paren_expr.cpp index e54510c1a18f..888027c5bcb2 100644 --- a/toolchain/parse/handle_paren_expr.cpp +++ b/toolchain/parse/handle_paren_expr.cpp @@ -71,8 +71,8 @@ auto HandleExprAfterOpenParenFinish(Context& context) -> void { // We found a comma, so switch parent state to tuple handling. auto finish_state = context.PopState(); - CARBON_CHECK(finish_state.state == State::ParenExprFinish) - << "Unexpected parent state, found: " << finish_state.state; + CARBON_CHECK(finish_state.state == State::ParenExprFinish, + "Unexpected parent state, found: {0}", finish_state.state); context.PushState(finish_state, State::TupleLiteralFinish); // If the comma is not immediately followed by a close paren, push handlers diff --git a/toolchain/parse/handle_requirement.cpp b/toolchain/parse/handle_requirement.cpp index 086500697e3a..394bba49a0b9 100644 --- a/toolchain/parse/handle_requirement.cpp +++ b/toolchain/parse/handle_requirement.cpp @@ -88,8 +88,8 @@ auto HandleRequirementOperatorFinish(Context& context) -> void { // RequirementOperatorFinish state is only pushed in // HandleRequirementOperator on one of the three requirement operator // tokens. - CARBON_FATAL() << "Unexpected token kind for requirement operator: " - << token_kind; + CARBON_FATAL("Unexpected token kind for requirement operator: {0}", + token_kind); return; } if (state.has_error) { diff --git a/toolchain/parse/node_kind.h b/toolchain/parse/node_kind.h index 0630def4344e..8dccf7e9c5d3 100644 --- a/toolchain/parse/node_kind.h +++ b/toolchain/parse/node_kind.h @@ -171,7 +171,7 @@ class NodeKind::Definition : public NodeKind { // Returns the bracketing node kind for the current node kind. Requires that // has_bracket is true. constexpr auto bracket() const -> NodeKind { - CARBON_CHECK(has_bracket()) << *this; + CARBON_CHECK(has_bracket(), "{0}", *this); return bracket_; } @@ -181,7 +181,7 @@ class NodeKind::Definition : public NodeKind { // Returns the number of children that the node must have, often 0. Requires // that has_child_count is true. constexpr auto child_count() const -> int32_t { - CARBON_CHECK(has_child_count()) << *this; + CARBON_CHECK(has_child_count(), "{0}", *this); return child_count_; } @@ -194,8 +194,7 @@ class NodeKind::Definition : public NodeKind { // This is factored out and non-constexpr to improve the compile-time error // message if the check below fails. auto MustSpecifyEitherBracketingNodeOrChildCount() { - CARBON_FATAL() - << "Must specify either bracketing node or fixed child count."; + CARBON_FATAL("Must specify either bracketing node or fixed child count."); } constexpr explicit Definition(NodeKind kind, DefinitionArgs args) diff --git a/toolchain/parse/parse.cpp b/toolchain/parse/parse.cpp index df13a0890e64..d6c5642032cc 100644 --- a/toolchain/parse/parse.cpp +++ b/toolchain/parse/parse.cpp @@ -13,8 +13,8 @@ namespace Carbon::Parse { auto HandleInvalid(Context& context) -> void { - CARBON_FATAL() << "The Invalid state shouldn't be on the stack: " - << context.PopState(); + CARBON_FATAL("The Invalid state shouldn't be on the stack: {0}", + context.PopState()); } auto Parse(Lex::TokenizedBuffer& tokens, DiagnosticConsumer& consumer, @@ -55,7 +55,7 @@ auto Parse(Lex::TokenizedBuffer& tokens, DiagnosticConsumer& consumer, // hopefully comfortable copy-pasting stderr when there are bugs in tree // construction. tree.Print(llvm::errs()); - CARBON_FATAL() << "Invalid tree returned by Parse(): " << verify.error(); + CARBON_FATAL("Invalid tree returned by Parse(): {0}", verify.error()); } return tree; } diff --git a/toolchain/parse/precedence.cpp b/toolchain/parse/precedence.cpp index ba280b5d42aa..bc68a3500c8c 100644 --- a/toolchain/parse/precedence.cpp +++ b/toolchain/parse/precedence.cpp @@ -126,8 +126,8 @@ struct OperatorPriorityTable { for (int8_t a = 0; a != NumPrecedenceLevels; ++a) { for (int8_t b = 0; b != NumPrecedenceLevels; ++b) { if (table[a][b] == OperatorPriority::LeftFirst) { - CARBON_CHECK(table[b][a] != OperatorPriority::LeftFirst) - << "inconsistent lookup table entries"; + CARBON_CHECK(table[b][a] != OperatorPriority::LeftFirst, + "inconsistent lookup table entries"); table[b][a] = OperatorPriority::RightFirst; } } @@ -163,13 +163,13 @@ struct OperatorPriorityTable { for (int8_t level = 0; level != NumPrecedenceLevels; ++level) { if (level != Highest) { CARBON_CHECK(table[Highest][level] == OperatorPriority::LeftFirst && - table[level][Highest] == OperatorPriority::RightFirst) - << "Highest is not highest priority"; + table[level][Highest] == OperatorPriority::RightFirst, + "Highest is not highest priority"); } if (level != Lowest) { CARBON_CHECK(table[Lowest][level] == OperatorPriority::RightFirst && - table[level][Lowest] == OperatorPriority::LeftFirst) - << "Lowest is not lowest priority"; + table[level][Lowest] == OperatorPriority::LeftFirst, + "Lowest is not lowest priority"); } } } diff --git a/toolchain/parse/tree_and_subtrees.cpp b/toolchain/parse/tree_and_subtrees.cpp index 4f1d0a47150a..4f75b3d1e540 100644 --- a/toolchain/parse/tree_and_subtrees.cpp +++ b/toolchain/parse/tree_and_subtrees.cpp @@ -19,25 +19,26 @@ TreeAndSubtrees::TreeAndSubtrees(const Lex::TokenizedBuffer& tokens, auto kind = tree.node_kind(n); if (kind.has_child_count()) { // When the child count is set, remove the specific number from the stack. - CARBON_CHECK(static_cast(size_stack.size()) >= - kind.child_count()) - << "Need " << kind.child_count() << " children for " << kind - << ", have " << size_stack.size() << " available"; + CARBON_CHECK( + static_cast(size_stack.size()) >= kind.child_count(), + "Need {0} children for {1}, have {2} available", kind.child_count(), + kind, size_stack.size()); for (auto i : llvm::seq(kind.child_count())) { auto child = size_stack.pop_back_val(); CARBON_CHECK((size_t)child.index < subtree_sizes_.size()); size += subtree_sizes_[child.index]; if (kind.has_bracket() && i == kind.child_count() - 1) { - CARBON_CHECK(kind.bracket() == tree.node_kind(child)) - << "Node " << kind << " with child count " << kind.child_count() - << " needs bracket " << kind.bracket() << ", found wrong bracket " - << tree.node_kind(child); + CARBON_CHECK(kind.bracket() == tree.node_kind(child), + "Node {0} with child count {1} needs bracket {2}, found " + "wrong bracket {3}", + kind, kind.child_count(), kind.bracket(), + tree.node_kind(child)); } } } else { while (true) { - CARBON_CHECK(!size_stack.empty()) - << "Node " << kind << " is missing bracket " << kind.bracket(); + CARBON_CHECK(!size_stack.empty(), "Node {0} is missing bracket {1}", + kind, kind.bracket()); auto child = size_stack.pop_back_val(); size += subtree_sizes_[child.index]; if (kind.bracket() == tree.node_kind(child)) { @@ -52,15 +53,15 @@ TreeAndSubtrees::TreeAndSubtrees(const Lex::TokenizedBuffer& tokens, CARBON_CHECK(static_cast(subtree_sizes_.size()) == tree_->size()); // Remaining nodes should all be roots in the tree; make sure they line up. - CARBON_CHECK(size_stack.back().index == - static_cast(tree_->size()) - 1) - << size_stack.back() << " " << tree_->size() - 1; + CARBON_CHECK( + size_stack.back().index == static_cast(tree_->size()) - 1, + "{0} {1}", size_stack.back(), tree_->size() - 1); int prev_index = -1; for (const auto& n : size_stack) { - CARBON_CHECK(n.index - subtree_sizes_[n.index] == prev_index) - << "NodeId " << n << " is a root " << tree_->node_kind(n) - << " with subtree_size " << subtree_sizes_[n.index] - << ", but previous root was at " << prev_index << "."; + CARBON_CHECK(n.index - subtree_sizes_[n.index] == prev_index, + "NodeId {0} is a root {1} with subtree_size {2}, but previous " + "root was at {3}.", + n, tree_->node_kind(n), subtree_sizes_[n.index], prev_index); prev_index = n.index; } } @@ -219,7 +220,7 @@ auto TreeAndSubtrees::PrintPreorder(llvm::raw_ostream& output) const -> void { } int next_depth = node_stack.empty() ? 0 : node_stack.back().second; - CARBON_CHECK(next_depth <= depth) << "Cannot have the next depth increase!"; + CARBON_CHECK(next_depth <= depth, "Cannot have the next depth increase!"); for (int close_children_count : llvm::seq(0, depth - next_depth)) { (void)close_children_count; output << "]}"; diff --git a/toolchain/parse/tree_and_subtrees.h b/toolchain/parse/tree_and_subtrees.h index 783991e0477c..39954138b56d 100644 --- a/toolchain/parse/tree_and_subtrees.h +++ b/toolchain/parse/tree_and_subtrees.h @@ -230,8 +230,8 @@ auto TreeAndSubtrees::ExtractNodeFromChildren( // On error try again, this time capturing a trace. ErrorBuilder trace; TryExtractNodeFromChildren(node_id, children, &trace); - CARBON_FATAL() << "Malformed parse node:\n" - << static_cast(trace).message(); + CARBON_FATAL("Malformed parse node:\n{0}", + static_cast(trace).message()); } return *result; } diff --git a/toolchain/sem_ir/block_value_store.h b/toolchain/sem_ir/block_value_store.h index 9e17280d9ed5..1e865913b1f2 100644 --- a/toolchain/sem_ir/block_value_store.h +++ b/toolchain/sem_ir/block_value_store.h @@ -103,8 +103,8 @@ class BlockValueStore : public Yaml::Printable> { // Sets the contents of an empty block to the given content. auto SetContent(IdT block_id, llvm::ArrayRef content) -> void { - CARBON_CHECK(Get(block_id).empty()) - << "inst block content set more than once"; + CARBON_CHECK(Get(block_id).empty(), + "inst block content set more than once"); values_.Get(block_id) = AllocateCopy(content); } diff --git a/toolchain/sem_ir/constant.cpp b/toolchain/sem_ir/constant.cpp index 4a68947ec28c..bbd59544546c 100644 --- a/toolchain/sem_ir/constant.cpp +++ b/toolchain/sem_ir/constant.cpp @@ -29,9 +29,9 @@ auto ConstantStore::GetOrAdd(Inst inst, bool is_symbolic) -> ConstantId { return const_id; }); CARBON_CHECK(result.value() != ConstantId::Invalid); - CARBON_CHECK(result.value().is_symbolic() == is_symbolic) - << "Constant " << inst - << " registered as both symbolic and template constant."; + CARBON_CHECK( + result.value().is_symbolic() == is_symbolic, + "Constant {0} registered as both symbolic and template constant.", inst); return result.value(); } diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 4bbd99ebcfee..073876808d7a 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -49,9 +49,9 @@ File::File(CheckIRId check_ir_id, IdentifierId package_id, : TypeId::TypeType, \ .builtin_inst_kind = BuiltinInstKind::Name})); #include "toolchain/sem_ir/builtin_inst_kind.def" - CARBON_CHECK(insts_.size() == BuiltinInstKind::ValidCount) - << "Builtins should produce " << BuiltinInstKind::ValidCount - << " insts, actual: " << insts_.size(); + CARBON_CHECK(insts_.size() == BuiltinInstKind::ValidCount, + "Builtins should produce {0} insts, actual: {1}", + BuiltinInstKind::ValidCount, insts_.size()); for (auto i : llvm::seq(BuiltinInstKind::ValidCount)) { auto builtin_id = SemIR::InstId(i); constant_values_.Set(builtin_id, @@ -176,8 +176,8 @@ auto File::CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const // precedence of that type's syntax. Higher numbers correspond to higher // precedence. static auto GetTypePrecedence(InstKind kind) -> int { - CARBON_CHECK(kind.is_type() != InstIsType::Never) - << "Only called for kinds which can define a type."; + CARBON_CHECK(kind.is_type() != InstIsType::Never, + "Only called for kinds which can define a type."); if (kind == ConstType::Kind) { return -1; } diff --git a/toolchain/sem_ir/generic.cpp b/toolchain/sem_ir/generic.cpp index 96860521be82..c86e8d8ef5c3 100644 --- a/toolchain/sem_ir/generic.cpp +++ b/toolchain/sem_ir/generic.cpp @@ -81,10 +81,11 @@ auto GetConstantInSpecific(const File& sem_ir, SpecificId specific_id, } auto value_block_id = specific.GetValueBlock(symbolic.index.region()); - CARBON_CHECK(value_block_id.is_valid()) - << "Queried " << symbolic.index << " in " << specific_id << " for " - << sem_ir.insts().Get(sem_ir.generics().Get(specific.generic_id).decl_id) - << " before it was resolved."; + CARBON_CHECK( + value_block_id.is_valid(), + "Queried {0} in {1} for {2} before it was resolved.", symbolic.index, + specific_id, + sem_ir.insts().Get(sem_ir.generics().Get(specific.generic_id).decl_id)); return sem_ir.constant_values().Get( sem_ir.inst_blocks().Get(value_block_id)[symbolic.index.index()]); } diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index daf0405e8127..95f345c63b38 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -426,8 +426,8 @@ struct BoolValue : public IdBase, public Printable { // Returns the `bool` corresponding to this `BoolValue`. constexpr auto ToBool() -> bool { - CARBON_CHECK(*this == False || *this == True) - << "Invalid bool value " << index; + CARBON_CHECK(*this == False || *this == True, "Invalid bool value {0}", + index); return *this != False; } @@ -438,7 +438,7 @@ struct BoolValue : public IdBase, public Printable { } else if (*this == True) { out << "true"; } else { - CARBON_FATAL() << "Invalid bool value " << index; + CARBON_FATAL("Invalid bool value {0}", index); } } }; @@ -465,7 +465,7 @@ struct IntKind : public IdBase, public Printable { } else if (*this == Signed) { out << "signed"; } else { - CARBON_FATAL() << "Invalid int kind value " << index; + CARBON_FATAL("Invalid int kind value {0}", index); } } }; @@ -510,7 +510,7 @@ struct NameId : public IdBase, public Printable { } else if (!id.is_valid()) { return NameId::Invalid; } else { - CARBON_FATAL() << "Unexpected identifier ID " << id; + CARBON_FATAL("Unexpected identifier ID {0}", id); } } @@ -535,7 +535,7 @@ struct NameId : public IdBase, public Printable { } else if (*this == Base) { out << "Base"; } else { - CARBON_CHECK(!is_valid() || index >= 0) << "Unknown index " << index; + CARBON_CHECK(!is_valid() || index >= 0, "Unknown index {0}", index); IdBase::Print(out); } } @@ -710,8 +710,8 @@ struct LibraryNameId : public IdBase, public Printable { // Returns the LibraryNameId for a library name as a string literal. static auto ForStringLiteralValueId(StringLiteralValueId id) -> LibraryNameId { - CARBON_CHECK(id.index >= InvalidIndex) - << "Unexpected library name ID " << id; + CARBON_CHECK(id.index >= InvalidIndex, "Unexpected library name ID {0}", + id); if (id == StringLiteralValueId::Invalid) { // Prior to SemIR, we use invalid to indicate `default`. return LibraryNameId::Default; @@ -724,7 +724,7 @@ struct LibraryNameId : public IdBase, public Printable { // Converts a LibraryNameId back to a string literal. auto AsStringLiteralValueId() const -> StringLiteralValueId { - CARBON_CHECK(index >= InvalidIndex) << *this << " must be handled directly"; + CARBON_CHECK(index >= InvalidIndex, "{0} must be handled directly", *this); return StringLiteralValueId(index); } diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index e929b86930d7..748b53234e70 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -164,8 +164,8 @@ class Inst : public Printable { requires Internal::InstLikeType auto As() const -> TypedInst { using Info = Internal::InstLikeTypeInfo; - CARBON_CHECK(Is()) << "Casting inst of kind " << kind() - << " to wrong kind " << Info::DebugName(); + CARBON_CHECK(Is(), "Casting inst of kind {0} to wrong kind {1}", + kind(), Info::DebugName()); auto build_with_type_id_onwards = [&](auto... type_id_onwards) { if constexpr (Internal::HasKindMemberAsField) { return TypedInst{kind(), type_id_onwards...}; @@ -393,9 +393,9 @@ class InstStore { } auto GetLocId(InstId inst_id) const -> LocId { - CARBON_CHECK(inst_id.index >= 0) << inst_id.index; - CARBON_CHECK(inst_id.index < (int)loc_ids_.size()) - << inst_id.index << " " << loc_ids_.size(); + CARBON_CHECK(inst_id.index >= 0, "{0}", inst_id.index); + CARBON_CHECK(inst_id.index < (int)loc_ids_.size(), "{0} {1}", inst_id.index, + loc_ids_.size()); return loc_ids_[inst_id.index]; } diff --git a/toolchain/sem_ir/inst_namer.cpp b/toolchain/sem_ir/inst_namer.cpp index 3cbad8dc635d..022ab102d670 100644 --- a/toolchain/sem_ir/inst_namer.cpp +++ b/toolchain/sem_ir/inst_namer.cpp @@ -206,7 +206,7 @@ auto InstNamer::GetLabelFor(ScopeId scope_id, InstBlockId block_id) const auto InstNamer::Namespace::Name::str() const -> llvm::StringRef { llvm::StringMapEntry* value = value_; - CARBON_CHECK(value) << "cannot print a null name"; + CARBON_CHECK(value, "cannot print a null name"); while (value->second.ambiguous && value->second.fallback) { value = value->second.fallback.value_; } diff --git a/toolchain/sem_ir/name.cpp b/toolchain/sem_ir/name.cpp index 05b0b9af1eaa..088580021367 100644 --- a/toolchain/sem_ir/name.cpp +++ b/toolchain/sem_ir/name.cpp @@ -24,7 +24,7 @@ static auto GetSpecialName(NameId name_id, bool for_ir) -> llvm::StringRef { case NameId::Base.index: return "base"; default: - CARBON_FATAL() << "Unknown special name"; + CARBON_FATAL("Unknown special name"); } } diff --git a/toolchain/sem_ir/name_scope.h b/toolchain/sem_ir/name_scope.h index 4401cd9a0144..a8d4b8c34f4b 100644 --- a/toolchain/sem_ir/name_scope.h +++ b/toolchain/sem_ir/name_scope.h @@ -54,8 +54,8 @@ struct NameScope : Printable { return index; }; auto result = name_map.Insert(name_entry.name_id, add_name); - CARBON_CHECK(result.is_inserted()) - << "Failed to add required name: " << name_entry.name_id; + CARBON_CHECK(result.is_inserted(), "Failed to add required name: {0}", + name_entry.name_id); } // Names in the scope. We store both an insertion-ordered vector for iterating diff --git a/toolchain/sem_ir/type.h b/toolchain/sem_ir/type.h index 183ef6b36097..69f199c801c9 100644 --- a/toolchain/sem_ir/type.h +++ b/toolchain/sem_ir/type.h @@ -86,8 +86,8 @@ class TypeStore : public Yaml::Printable { CARBON_CHECK(value_repr.kind != ValueRepr::Unknown); auto insert_info = complete_type_info_.Insert(type_id, {.value_repr = value_repr}); - CARBON_CHECK(insert_info.is_inserted()) - << "Type " << type_id << " completed more than once"; + CARBON_CHECK(insert_info.is_inserted(), "Type {0} completed more than once", + type_id); complete_types_.push_back(type_id); CARBON_CHECK(IsComplete(type_id)); } diff --git a/toolchain/testing/file_test.cpp b/toolchain/testing/file_test.cpp index 55cd36e4fccc..3fd54476f1e0 100644 --- a/toolchain/testing/file_test.cpp +++ b/toolchain/testing/file_test.cpp @@ -71,8 +71,8 @@ class ToolchainFileTest : public FileTestBase { } else if (component_ == "lower") { args.push_back("--dump-llvm-ir"); } else { - CARBON_FATAL() << "Unexpected test component " << component_ << ": " - << test_name(); + CARBON_FATAL("Unexpected test component {0}: {1}", component_, + test_name()); } // For `lex` and `parse`, we don't need to import the prelude; exclude it to @@ -150,7 +150,7 @@ class ToolchainFileTest : public FileTestBase { // This handles cases where the toolchain directory may be copied into a // repository that doesn't put it at the root. auto pos = test_name.find("toolchain/"); - CARBON_CHECK(pos != llvm::StringRef::npos) << test_name; + CARBON_CHECK(pos != llvm::StringRef::npos, "{0}", test_name); test_name = test_name.drop_front(pos + strlen("toolchain/")); test_name = test_name.take_front(test_name.find("/")); return test_name;