Perform overload resolution immediately in C++ operator lookup. (#6416)

Don't attempt to defer overload resolution by creating a
`CppOverloadSet`; this was incorrect as we weren't saving the complete
clang::OverloadCandidateSet, resulting in template candidates not being
found. Moreover, saving the overload candidate set would be expensive,
as the representation is surprisingly large, and is unnecessary since
we're about to build a call.

In passing, improve the diagnostics for overload resolution failure to
use Clang's operator overload resolution messages rather than its call
overload resolution messages.

This fixes calls to templated operator overloads, which is the final
piece needed for us to successfully compile an iostream-based "Hello
world" program.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2025-11-24 23:01:28 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 167b45ca35
commit 054dfca685
8 changed files with 339 additions and 133 deletions
-13
View File
@@ -14,16 +14,6 @@
namespace Carbon::Check {
// Returns whether the function is an imported C++ operator member function.
static auto IsCppOperatorMethod(Context& context, SemIR::FunctionId function_id)
-> bool {
SemIR::ClangDeclId clang_decl_id =
context.functions().Get(function_id).clang_decl_id;
return clang_decl_id.has_value() &&
IsCppOperatorMethodDecl(
context.clang_decls().Get(clang_decl_id).key.decl);
}
auto PerformCallToCppFunction(Context& context, SemIR::LocId loc_id,
SemIR::CppOverloadSetId overload_set_id,
SemIR::InstId self_id,
@@ -41,9 +31,6 @@ auto PerformCallToCppFunction(Context& context, SemIR::LocId loc_id,
if (self_id.has_value()) {
// Preserve the `self` argument from the original callee.
fn.self_id = self_id;
} else if (IsCppOperatorMethod(context, fn.function_id)) {
// Adjust `self` and args for C++ overloaded operator methods.
fn.self_id = arg_ids.consume_front();
}
return PerformCallToFunction(context, loc_id, callee_id, fn, arg_ids);
}