Support list initialization of C++ classes that is performed via a constructor call. (#6660)

The general strategy here is to import the constructor with a signature
that directly matches the argument. The intent is that the imported
function will eventually be usable directly as the `ImplicitAs.Convert`
function in a generated `impl`.

For initialization from a tuple, for example `(1, 2)`, we import the
selected constructor with a signature that takes a tuple pattern:

  `fn Class.Class((a: i32, b: i32)) -> Class;`

In order to support that, this PR also adds support in general for tuple
patterns in function signatures. It turns out the implementation was
already very close to allowing this.

Assisted-by: Gemini 3 Pro via Antigravity
This commit is contained in:
Richard Smith
2026-01-27 22:04:21 +00:00
committed by GitHub
parent 9f6e84cc02
commit e69c3fd978
18 changed files with 2151 additions and 1118 deletions
+9 -4
View File
@@ -245,8 +245,9 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::AnyBindingPattern binding_pattern,
MatchContext::WorkItem entry) -> void {
if (kind_ == MatchKind::Caller) {
CARBON_CHECK(binding_pattern.kind == SemIR::SymbolicBindingPattern::Kind,
"Found runtime binding pattern during caller pattern match");
CARBON_CHECK(
binding_pattern.kind == SemIR::SymbolicBindingPattern::Kind,
"Found named runtime binding pattern during caller pattern match");
return;
}
// We're logically consuming this map entry, so we invalidate it in order
@@ -534,8 +535,12 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
};
if (!entry.scrutinee_id.has_value()) {
CARBON_CHECK(kind_ == MatchKind::Callee);
context.TODO(entry.pattern_id,
"Support patterns besides bindings in parameter list");
// If we don't have a scrutinee yet, we're still on the caller side of the
// pattern, so the subpatterns don't have a scrutinee either.
for (auto subpattern_id : llvm::reverse(subpattern_ids)) {
AddWork(
{.pattern_id = subpattern_id, .scrutinee_id = SemIR::InstId::None});
}
return;
}
auto scrutinee = context.insts().GetWithLocId(entry.scrutinee_id);