Function call type checking and narrowing

This commit is contained in:
2026-08-04 08:14:07 +10:00
parent fa0b3ce34d
commit 7e713430a8

View File

@@ -395,7 +395,7 @@ namespace Solstice {
}
void TypeChecker::checkFunctionCallNodeType(Node& node) {
void TypeChecker::narrowFunctionCallNode(Node& node) {
// get function
auto name = node.children[0].getIdentifier();
if (!name.has_value()) {
@@ -408,23 +408,34 @@ namespace Solstice {
auto& function = functions[*name];
// get types we are calling with
std::vector<Type> args;
std::vector<PossibleType> args;
// narrow types based on function
for (auto& child : node.children[1].children) {
checkNodeType(child);
auto childType = child.ptype.getOnlyType();
if (!childType.has_value()) {
throw std::runtime_error("cannot call function with ambiguous type");
args.push_back(child.ptype);
}
// get all possible combinations
auto sets = doCartesianProductOnTypeSets(args);
bool found = false;
for (const auto& set : sets) {
if (function.returnTypes.find(set) != function.returnTypes.end()) {
if (found) {
throw std::runtime_error("conflicting function definitions");
}
found = true;
node.ptype = {{function.returnTypes[set]}};
}
args.push_back(*childType);
}
// find argument type
if (function.returnTypes.find(args) == function.returnTypes.end()) {
throw std::runtime_error("no matching function call to " + *name);
if (!found) {
throw std::runtime_error("no matching overload found for function " + *name);
}
}
node.ptype = {{function.returnTypes[args]}};
void TypeChecker::checkFunctionCallNodeType(Node& node) {
narrowFunctionCallNode(node);
}
void TypeChecker::checkSetNodeType(Node& node) {