zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 9181ecd95133b42da75c6c5e8456830d93a9f7a9 (tree)
parent 129de47a71b954b1118ce188f7032ad726491f53
Author: Carl Ã…stholm <carl@astholm.se>
Date:   Sun, 18 Feb 2024 13:17:48 +0100

Sema: fix runtime call of inline fn with comptime-known comptime-only ret type

Diffstat:
Mlib/std/math/nextafter.zig | 2+-
Msrc/Sema.zig | 6+++---
Mtest/behavior/fn.zig | 14++++++++++++++
3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/lib/std/math/nextafter.zig b/lib/std/math/nextafter.zig @@ -144,7 +144,7 @@ test "int" { } test "float" { - @setEvalBranchQuota(2000); + @setEvalBranchQuota(3000); // normal -> normal try expect(nextAfter(f16, 0x1.234p0, 2.0) == 0x1.238p0); diff --git a/src/Sema.zig b/src/Sema.zig @@ -7525,10 +7525,12 @@ fn analyzeCall( var is_generic_call = func_ty_info.is_generic; var is_comptime_call = block.is_comptime or modifier == .compile_time; + var is_inline_call = is_comptime_call or modifier == .always_inline or func_ty_info.cc == .Inline; var comptime_reason: ?*const Block.ComptimeReason = null; - if (!is_comptime_call) { + if (!is_inline_call and !is_comptime_call) { if (sema.typeRequiresComptime(Type.fromInterned(func_ty_info.return_type))) |ct| { is_comptime_call = ct; + is_inline_call = ct; if (ct) { comptime_reason = &.{ .comptime_ret_ty = .{ .block = block, @@ -7542,8 +7544,6 @@ fn analyzeCall( else => |e| return e, } } - var is_inline_call = is_comptime_call or modifier == .always_inline or - func_ty_info.cc == .Inline; if (sema.func_is_naked and !is_inline_call and !is_comptime_call) { const msg = msg: { diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig @@ -604,3 +604,17 @@ test "comptime parameters don't have to be marked comptime if only called at com }; comptime std.debug.assert(S.foo(5, 6) == 11); } + +test "inline function with comptime-known comptime-only return type called at runtime" { + const S = struct { + inline fn foo(x: *i32, y: *const i32) type { + x.* = y.*; + return f32; + } + }; + var a: i32 = 0; + const b: i32 = 111; + const T = S.foo(&a, &b); + try expectEqual(111, a); + try expectEqual(f32, T); +}