aboutsummaryrefslogtreecommitdiff
path: root/boot/type_check.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-11-01 22:10:48 +0100
committerEugen Wissner <belka@caraus.de>2026-11-01 22:10:48 +0100
commit48a51628b841a9b69db846326dcaa67239a8559f (patch)
tree76707565b96d42ee652179e4037e42a2c5559888 /boot/type_check.cc
parent5dd5d460f154c146d26f115706a21b7808658edf (diff)
downloadelna-48a51628b841a9b69db846326dcaa67239a8559f.tar.gz
Fix generic inference for a procedure call as a slice baseHEADcpp
Diffstat (limited to 'boot/type_check.cc')
-rw-r--r--boot/type_check.cc116
1 files changed, 0 insertions, 116 deletions
diff --git a/boot/type_check.cc b/boot/type_check.cc
index 7adaaed..a135bcb 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -1079,112 +1079,6 @@ namespace elna::boot
}
/*
- * Walks a declared parameter type and an actual argument type in parallel,
- * binding a parameter the first time it is met and leaving every later
- * occurrence to the ordinary assignability check. Both sides are resolved
- * at every step, so a transparent instantiation is seen through and only a
- * record-referent one is compared as an instantiation.
- *
- * Returns false when the walk fails on shape rather than on type.
- */
- static bool bind_arguments(const std::vector<type>& parameters, std::vector<type>& bindings,
- const type& declared, const type& actual)
- {
- const type left = resolve_aliases(declared);
- const type right = resolve_aliases(actual);
-
- if (const auto parameter = left.get<parameter_type>())
- {
- for (std::size_t i = 0; i < parameters.size(); ++i)
- {
- if (parameters[i].get<parameter_type>() == parameter && bindings[i].empty())
- {
- // The actual type is recorded as it stands, which inside a
- // generic body may itself be an abstract parameter.
- bindings[i] = actual;
- }
- }
- return true;
- }
- else if (const auto left_pointer = left.get<pointer_type>())
- {
- const std::shared_ptr<pointer_type> right_pointer = right.get<pointer_type>();
-
- return right_pointer != nullptr
- && bind_arguments(parameters, bindings, left_pointer->base, right_pointer->base);
- }
- else if (const auto left_slice = left.get<slice_type>())
- {
- const std::shared_ptr<slice_type> right_slice = right.get<slice_type>();
-
- return right_slice != nullptr
- && bind_arguments(parameters, bindings, left_slice->base, right_slice->base);
- }
- else if (const auto left_array = left.get<array_type>())
- {
- const std::shared_ptr<array_type> right_array = right.get<array_type>();
-
- return right_array != nullptr
- && bind_arguments(parameters, bindings, left_array->base, right_array->base);
- }
- else if (const auto left_constant = left.get<constant_type>())
- {
- const std::shared_ptr<constant_type> right_constant = right.get<constant_type>();
- const type right_unqualified = right_constant != nullptr
- ? right_constant->unqualified
- : right;
-
- return bind_arguments(parameters, bindings, left_constant->unqualified, right_unqualified);
- }
- else if (const auto left_instance = left.get<instantiated_type>())
- {
- for (type candidate = right; !candidate.empty(); candidate = base_of(candidate))
- {
- const std::shared_ptr<instantiated_type> right_instance =
- resolve_aliases(candidate).get<instantiated_type>();
-
- if (right_instance == nullptr
- || !(left_instance->generic == right_instance->generic)
- || left_instance->arguments.size() != right_instance->arguments.size())
- {
- continue;
- }
- for (std::size_t i = 0; i < left_instance->arguments.size(); ++i)
- {
- if (!bind_arguments(parameters, bindings,
- left_instance->arguments.at(i), right_instance->arguments.at(i)))
- {
- return false;
- }
- }
- return true;
- }
- return false;
- }
- else if (const auto left_procedure = left.get<procedure_type>())
- {
- const std::shared_ptr<procedure_type> right_procedure = right.get<procedure_type>();
-
- if (right_procedure == nullptr
- || left_procedure->parameters.size() != right_procedure->parameters.size())
- {
- return false;
- }
- for (std::size_t i = 0; i < left_procedure->parameters.size(); ++i)
- {
- if (!bind_arguments(parameters, bindings,
- left_procedure->parameters.at(i), right_procedure->parameters.at(i)))
- {
- return false;
- }
- }
- return left_procedure->return_type.empty()
- || bind_arguments(parameters, bindings, left_procedure->return_type, right_procedure->return_type);
- }
- return true;
- }
-
- /*
* The volatile builtins take the pointee as their type argument, so the
* rule applies to what is loaded or stored rather than to a pointer.
*/
@@ -1382,19 +1276,9 @@ namespace elna::boot
if (procedure != nullptr && !procedure->parameters.empty())
{
- // Inference reads the argument types, so they are decorated
- // before the parameter types they will be checked against exist.
visit_all(this, call->arguments);
inferred = procedure;
callable_type = infer_call(*call, *reference, *procedure);
-
- // Name analysis decorated the call with the declared return
- // type, which still mentions the parameters inference has
- // just bound.
- if (const auto substituted = callable_type.get<procedure_type>())
- {
- call->type_decoration = substituted->return_type;
- }
}
}
if (const auto procedure = callable_type.get<procedure_type>())