authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-09-16 00:10:42+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-15 21:46:38-07:00
log6df78c3bc17e5922792fcef0025043c358daa52f
tree08cef0a28f498b9bd946714d4bc91ddf284fa166
parent61b70778bdf975957d45432987dde16029aca69a

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

3 files changed, 13 insertions(+), 5 deletions(-)

src/Sema.zig+1-1
...@@ -36506,7 +36506,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -36506,7 +36506,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
36506 .ptr_type => |ptr_type| {36506 .ptr_type => |ptr_type| {
36507 const child_ty = ptr_type.child.toType();36507 const child_ty = ptr_type.child.toType();
36508 switch (child_ty.zigTypeTag(mod)) {36508 switch (child_ty.zigTypeTag(mod)) {
36509 .Fn => return mod.typeToFunc(child_ty).?.is_generic,36509 .Fn => return !try sema.fnHasRuntimeBits(child_ty),
36510 .Opaque => return false,36510 .Opaque => return false,
36511 else => return sema.typeRequiresComptime(child_ty),36511 else => return sema.typeRequiresComptime(child_ty),
36512 }36512 }
src/type.zig+2-4
...@@ -467,12 +467,10 @@ pub const Type = struct {...@@ -467,12 +467,10 @@ pub const Type = struct {
467 .empty_struct_type => false,467 .empty_struct_type => false,
468 else => switch (ip.indexToKey(ty.toIntern())) {468 else => switch (ip.indexToKey(ty.toIntern())) {
469 .int_type => |int_type| int_type.bits != 0,469 .int_type => |int_type| int_type.bits != 0,
470 .ptr_type => |ptr_type| {470 .ptr_type => {
471 // Pointers to zero-bit types still have a runtime address; however, pointers471 // Pointers to zero-bit types still have a runtime address; however, pointers
472 // to comptime-only types do not, with the exception of function pointers.472 // to comptime-only types do not, with the exception of function pointers.
473 if (ignore_comptime_only) return true;473 if (ignore_comptime_only) return true;
474 const child_ty = ptr_type.child.toType();
475 if (child_ty.zigTypeTag(mod) == .Fn) return !mod.typeToFunc(child_ty).?.is_generic;
476 if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty));474 if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty));
477 return !comptimeOnly(ty, mod);475 return !comptimeOnly(ty, mod);
478 },476 },
...@@ -2649,7 +2647,7 @@ pub const Type = struct {...@@ -2649,7 +2647,7 @@ pub const Type = struct {
2649 .ptr_type => |ptr_type| {2647 .ptr_type => |ptr_type| {
2650 const child_ty = ptr_type.child.toType();2648 const child_ty = ptr_type.child.toType();
2651 switch (child_ty.zigTypeTag(mod)) {2649 switch (child_ty.zigTypeTag(mod)) {
2652 .Fn => return mod.typeToFunc(child_ty).?.is_generic,2650 .Fn => return !child_ty.isFnOrHasRuntimeBits(mod),
2653 .Opaque => return false,2651 .Opaque => return false,
2654 else => return child_ty.comptimeOnly(mod),2652 else => return child_ty.comptimeOnly(mod),
2655 }2653 }
test/behavior/call.zig+10
...@@ -491,3 +491,13 @@ test "argument to generic function has correct result type" {...@@ -491,3 +491,13 @@ test "argument to generic function has correct result type" {
491 try S.doTheTest();491 try S.doTheTest();
492 try comptime S.doTheTest();492 try comptime S.doTheTest();
493}493}
494
495test "call inline fn through pointer" {
496 const S = struct {
497 inline fn foo(x: u8) !void {
498 try expect(x == 123);
499 }
500 };
501 const f = &S.foo;
502 try f(123);
503}