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
This commit is contained in:
mlugg 2023-09-16 00:10:42 +01:00 committed by Andrew Kelley
parent 61b70778bd
commit 6df78c3bc1
3 changed files with 13 additions and 5 deletions

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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);
}