stage2: support comptime fn call returning type

...when the field type expressions reference locals as well as
comptime function parameters.
This commit is contained in:
Andrew Kelley 2021-08-20 17:44:03 -07:00
parent 6c55d854cf
commit f0176eec4a
2 changed files with 30 additions and 1 deletions

View File

@ -2623,7 +2623,18 @@ fn analyzeCall(
defer sema.fn_ret_ty = parent_fn_ret_ty;
_ = try sema.analyzeBody(&child_block, fn_info.body);
break :res try sema.analyzeBlockBody(block, call_src, &child_block, merges);
const result = try sema.analyzeBlockBody(block, call_src, &child_block, merges);
// Much like in `Module.semaDecl`, if the result is a struct or union type,
// we need to resolve the field type expressions right here, right now, while
// the child `Sema` is still available, with the AIR instruction map intact,
// because the field type expressions may reference into it.
if (sema.typeOf(result).zigTypeTag() == .Type) {
const ty = try sema.analyzeAsType(&child_block, call_src, result);
try sema.resolveDeclFields(&child_block, call_src, ty);
}
break :res result;
} else if (func_ty_info.is_generic) res: {
const func_val = try sema.resolveConstValue(block, func_src, func);
const module_fn = func_val.castTag(.function).?.data;

View File

@ -78,3 +78,21 @@ fn max_i32(a: i32, b: i32) i32 {
fn max_f64(a: f64, b: f64) f64 {
return max_anytype(a, b);
}
test "type constructed by comptime function call" {
var l: List(10) = undefined;
l.array[0] = 10;
l.array[1] = 11;
l.array[2] = 12;
const ptr = @ptrCast([*]u8, &l.array);
try expect(ptr[0] == 10);
try expect(ptr[1] == 11);
try expect(ptr[2] == 12);
}
fn List(comptime L: usize) type {
var T = u8;
return struct {
array: [L]T,
};
}