authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-15 15:52:57+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-16 01:12:27+02:00
log2cfa7165e715321dffea21380d4fde0dd5079925
treee1a40071bc030821e7bca65950aba3705ab2c827
parentb6b3462796fe38a071e6ed2cbcdbb5b024359f35

Sema: do not re-evaluate type of non-generic inline call parameters

Closes #13491

2 files changed, 26 insertions(+), 2 deletions(-)

src/Sema.zig+9-2
......@@ -6361,6 +6361,7 @@ fn analyzeCall(
63616361 is_comptime_call,
63626362 &should_memoize,
63636363 memoized_call_key,
6364 func_ty_info.param_types,
63646365 ) catch |err| switch (err) {
63656366 error.NeededSourceLocation => {
63666367 _ = sema.inst_map.remove(inst);
......@@ -6376,6 +6377,7 @@ fn analyzeCall(
63766377 is_comptime_call,
63776378 &should_memoize,
63786379 memoized_call_key,
6380 func_ty_info.param_types,
63796381 );
63806382 return error.AnalysisFail;
63816383 },
......@@ -6612,6 +6614,7 @@ fn analyzeInlineCallArg(
66126614 is_comptime_call: bool,
66136615 should_memoize: *bool,
66146616 memoized_call_key: Module.MemoizedCall.Key,
6617 raw_param_types: []const Type,
66156618) !void {
66166619 const zir_tags = sema.code.instructions.items(.tag);
66176620 switch (zir_tags[inst]) {
......@@ -6622,8 +6625,12 @@ fn analyzeInlineCallArg(
66226625 const param_src = pl_tok.src();
66236626 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);
66246627 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
6625 const param_ty_inst = try sema.resolveBody(param_block, param_body, inst);
6626 const param_ty = try sema.analyzeAsType(param_block, param_src, param_ty_inst);
6628 const param_ty = param_ty: {
6629 const raw_param_ty = raw_param_types[arg_i.*];
6630 if (raw_param_ty.tag() != .generic_poison) break :param_ty raw_param_ty;
6631 const param_ty_inst = try sema.resolveBody(param_block, param_body, inst);
6632 break :param_ty try sema.analyzeAsType(param_block, param_src, param_ty_inst);
6633 };
66276634 new_fn_info.param_types[arg_i.*] = param_ty;
66286635 const uncasted_arg = uncasted_args[arg_i.*];
66296636 if (try sema.typeRequiresComptime(param_ty)) {
test/behavior/call.zig+17
......@@ -327,3 +327,20 @@ test "inline call preserves tail call" {
327327 S.foo();
328328 try expect(S.a == std.math.maxInt(u16));
329329}
330
331test "inline call doesn't re-evaluate non generic struct" {
332 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
333 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
334 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
335 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
336
337 const S = struct {
338 fn foo(f: struct { a: u8, b: u8 }) !void {
339 try expect(f.a == 123);
340 try expect(f.b == 45);
341 }
342 };
343 const ArgTuple = std.meta.ArgsTuple(@TypeOf(S.foo));
344 try @call(.{ .modifier = .always_inline }, S.foo, ArgTuple{.{ .a = 123, .b = 45 }});
345 comptime try @call(.{ .modifier = .always_inline }, S.foo, ArgTuple{.{ .a = 123, .b = 45 }});
346}