Commit 6df78c3bc1

mlugg <mlugg@mlugg.co.uk>
2023-09-16 01:10:42
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
1 parent 61b7077
Changed files (3)
src
test
behavior
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),
                 }
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),
                     }
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);
+}