Support deduction of the types of struct fields (#4500)

Follow-on to #4492 .

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
This commit is contained in:
josh11b
2024-11-07 21:25:49 +00:00
committed by GitHub
co-authored by Josh L
parent 138ecf108f
commit caba03d27e
2 changed files with 456 additions and 13 deletions
+27 -1
View File
@@ -80,6 +80,28 @@ class DeductionWorklist {
AddAll(context_.inst_blocks().Get(params), args, needs_substitution);
}
auto AddAll(SemIR::StructTypeFieldsId params, SemIR::StructTypeFieldsId args,
bool needs_substitution) -> void {
const auto& param_fields = context_.struct_type_fields().Get(params);
const auto& arg_fields = context_.struct_type_fields().Get(args);
if (param_fields.size() != arg_fields.size()) {
// TODO: Decide whether to error on this or just treat the parameter list
// as non-deduced. For now we treat it as non-deduced.
return;
}
// Don't do deduction unless the names match in order.
// TODO: Support reordering of names.
for (auto [param, arg] : llvm::zip_equal(param_fields, arg_fields)) {
if (param.name_id != arg.name_id) {
return;
}
}
for (auto [param, arg] :
llvm::reverse(llvm::zip_equal(param_fields, arg_fields))) {
Add(param.type_id, arg.type_id, needs_substitution);
}
}
auto AddAll(SemIR::InstBlockId params, SemIR::InstBlockId args,
bool needs_substitution) -> void {
AddAll(context_.inst_blocks().Get(params), context_.inst_blocks().Get(args),
@@ -107,6 +129,10 @@ class DeductionWorklist {
case SemIR::IdKind::For<SemIR::TypeId>:
Add(SemIR::TypeId(param), SemIR::TypeId(arg), needs_substitution);
break;
case SemIR::IdKind::For<SemIR::StructTypeFieldsId>:
AddAll(SemIR::StructTypeFieldsId(param), SemIR::StructTypeFieldsId(arg),
needs_substitution);
break;
case SemIR::IdKind::For<SemIR::InstBlockId>:
AddAll(SemIR::InstBlockId(param), SemIR::InstBlockId(arg),
needs_substitution);
@@ -378,6 +404,7 @@ auto DeductionContext::Deduce() -> bool {
case SemIR::InterfaceType::Kind:
case SemIR::IntType::Kind:
case SemIR::PointerType::Kind:
case SemIR::StructType::Kind:
case SemIR::TupleType::Kind:
case SemIR::TupleValue::Kind: {
auto arg_inst = context().insts().Get(arg_id);
@@ -392,7 +419,6 @@ auto DeductionContext::Deduce() -> bool {
continue;
}
case SemIR::StructType::Kind:
case SemIR::StructValue::Kind:
// TODO: Match field name order between param and arg.
break;