| author | |
| committer | |
| log | 6df78c3bc17e5922792fcef0025043c358daa52f |
| tree | 08cef0a28f498b9bd946714d4bc91ddf284fa166 |
| parent | 61b70778bdf975957d45432987dde16029aca69a |
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: #383 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, pointers | 471 | // 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 | |||
| 495 | test "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 | } |