PolySolveElem elem = elem_queue[0];
bh_arr_deleten(elem_queue, 0, 1);
- if (elem.type_expr == (AstType *) target) {
+ // This check does not strictly need the `type_auto_return` check,
+ // but it does prevent bugs if the auto return type placeholder is
+ // accidentally inserted into the real type.
+ if (elem.type_expr == (AstType *) target && elem.actual != &type_auto_return) {
result.kind = elem.kind;
assert(elem.kind != PSK_Undefined);
}
AstTyped *result = (AstTyped *) polymorphic_proc_lookup(pp, PPLM_By_Function_Type, ft->partial_function_type, pp->token);
- if (result && result->type == NULL) {
+
+ // If the result is not ready (NULL, yield flag, no type, or `type_auto_return` as return type), wait.
+ if (result
+ && result->type == NULL
+ || (result->type->kind == Type_Kind_Function && result->type->Function.return_type == &type_auto_return)) {
doing_nested_polymorph_lookup = 1;
result = NULL;
}
package core.iter
-use core {memory, alloc, array}
+use core {memory, alloc, array, Pair}
as_iterator :: #match {}
};
}
-#local Zipped :: struct (T: type_expr, R: type_expr) {
- first: T;
- second: R;
-}
-
-zip :: (left_iterator: Iterator($T), right_iterator: Iterator($R), allocator := context.temp_allocator) -> Iterator(Zipped(T, R)) {
+zip :: (left_iterator: Iterator($T), right_iterator: Iterator($R), allocator := context.temp_allocator) -> Iterator(Pair(T, R)) {
ZippedIterator :: struct (T: type_expr, R: type_expr) {
iterator1: Iterator(T);
iterator2: Iterator(R);
zipped_iterator.iterator2 = right_iterator;
zipped_iterator.allocator = allocator;
- next :: (zi: ^ZippedIterator($T, $R)) -> (Zipped(T, R), bool) {
+ next :: (zi: ^ZippedIterator($T, $R)) -> (Pair(T, R), bool) {
v1, cont1 := zi.iterator1.next(zi.iterator1.data);
v2, cont2 := zi.iterator2.next(zi.iterator2.data);
ctx => {
x_val, cont := take_one(ctx.x_iter);
if cont {
- return .{ x=x_val, y=ctx.y_val }, true;
+ return Pair.make(x_val, ctx.y_val), true;
}
ctx.y_val, cont = take_one(ctx.y_iter);
x_val, cont = take_one(ctx.x_iter);
if !cont do return .{}, false;
- return .{ x=x_val, y=ctx.y_val }, true;
+ return Pair.make(x_val, ctx.y_val), true;
}
);
}
}
#inject Pair {
- make :: (x: $X, y: $Y) => Pair(X, Y).{x, y};
+ make :: macro (x: $X, y: $Y) => Pair(X, Y).{x, y};
_format :: (output: ^conv.Format_Output, format: ^conv.Format, p: ^Pair($First_Type, $Second_Type)) {
conv.format(output, "({}, {})", p.first, p.second);