From 6df78c3bc17e5922792fcef0025043c358daa52f Mon Sep 17 00:00:00 2001 From: mlugg Date: Sat, 16 Sep 2023 00:10:42 +0100 Subject: [PATCH] Sema: mark pointers to inline functions as comptime-only This is supposed to be the case, similar to how pointers to generic functions are comptime-only (several pieces of logic already assumed this). These types being considered runtime was causing `dbg_var_val` AIR instructions to be wrongly emitted for such values, causing codegen backends to create a runtime reference to the inline function, which (at least on the LLVM backend) triggers an error. Resolves: #38 --- src/Sema.zig | 2 +- src/type.zig | 6 ++---- test/behavior/call.zig | 10 ++++++++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 16bf872419..4475cfc008 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -36506,7 +36506,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .ptr_type => |ptr_type| { const child_ty = ptr_type.child.toType(); switch (child_ty.zigTypeTag(mod)) { - .Fn => return mod.typeToFunc(child_ty).?.is_generic, + .Fn => return !try sema.fnHasRuntimeBits(child_ty), .Opaque => return false, else => return sema.typeRequiresComptime(child_ty), } diff --git a/src/type.zig b/src/type.zig index 67f855806f..32d207bfbf 100644 --- a/src/type.zig +++ b/src/type.zig @@ -467,12 +467,10 @@ pub const Type = struct { .empty_struct_type => false, else => switch (ip.indexToKey(ty.toIntern())) { .int_type => |int_type| int_type.bits != 0, - .ptr_type => |ptr_type| { + .ptr_type => { // Pointers to zero-bit types still have a runtime address; however, pointers // to comptime-only types do not, with the exception of function pointers. if (ignore_comptime_only) return true; - const child_ty = ptr_type.child.toType(); - if (child_ty.zigTypeTag(mod) == .Fn) return !mod.typeToFunc(child_ty).?.is_generic; if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty)); return !comptimeOnly(ty, mod); }, @@ -2649,7 +2647,7 @@ pub const Type = struct { .ptr_type => |ptr_type| { const child_ty = ptr_type.child.toType(); switch (child_ty.zigTypeTag(mod)) { - .Fn => return mod.typeToFunc(child_ty).?.is_generic, + .Fn => return !child_ty.isFnOrHasRuntimeBits(mod), .Opaque => return false, else => return child_ty.comptimeOnly(mod), } diff --git a/test/behavior/call.zig b/test/behavior/call.zig index d641d5d5ba..6be66da174 100644 --- a/test/behavior/call.zig +++ b/test/behavior/call.zig @@ -491,3 +491,13 @@ test "argument to generic function has correct result type" { try S.doTheTest(); try comptime S.doTheTest(); } + +test "call inline fn through pointer" { + const S = struct { + inline fn foo(x: u8) !void { + try expect(x == 123); + } + }; + const f = &S.foo; + try f(123); +}