aboutsummaryrefslogtreecommitdiff
path: root/boot/name_analysis.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/name_analysis.cc
parent5dd5d460f154c146d26f115706a21b7808658edf (diff)
downloadelna-48a51628b841a9b69db846326dcaa67239a8559f.tar.gz
Fix generic inference for a procedure call as a slice baseHEADcpp
Diffstat (limited to 'boot/name_analysis.cc')
-rw-r--r--boot/name_analysis.cc31
1 files changed, 30 insertions, 1 deletions
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 9305cd2..959aefc 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -968,13 +968,42 @@ namespace elna::boot
void resolving_visitor::visit(procedure_call *call)
{
call->callable().accept(this);
+ visit_all(this, call->arguments);
+
+ if (const auto *reference = call->callable().is_named();
+ reference != nullptr && reference->arguments.empty())
+ {
+ const std::shared_ptr<info> symbol = this->bag.lookup(reference->name);
+ const std::shared_ptr<procedure_info> procedure =
+ symbol == nullptr ? nullptr : symbol->is_procedure();
+
+ if (procedure != nullptr && !procedure->parameters.empty())
+ {
+ std::vector<type> bindings(procedure->parameters.size());
+ auto argument_iterator = call->arguments.begin();
+ auto declared_iterator = procedure->symbol.parameters.begin();
+
+ while (argument_iterator != call->arguments.end()
+ && declared_iterator != procedure->symbol.parameters.end())
+ {
+ const type actual = unqualify((*argument_iterator)->type_decoration);
+ bind_arguments(procedure->parameters, bindings, *declared_iterator, actual);
+ ++argument_iterator;
+ ++declared_iterator;
+ }
+ if (std::ranges::none_of(bindings, &type::empty))
+ {
+ call->callable().type_decoration = substitute(
+ call->callable().type_decoration, procedure->parameters, bindings);
+ }
+ }
+ }
const type callable_type = resolve_underlying_type(call->callable().type_decoration);
if (const auto procedure = callable_type.get<procedure_type>())
{
call->type_decoration = procedure->return_type;
}
- visit_all(this, call->arguments);
this->current_type = type();
}