From 17a0458e530242254f21fc0b6825e1303ec06028 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 27 May 2024 13:24:43 +0300 Subject: [PATCH] Sema: add missing error for runtime `@ptrFromInt` to comptime-only type Closes #20083 --- src/Sema.zig | 9 +++++++++ ...runtime_@ptrFromInt_to_comptime_only_type.zig | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 test/cases/compile_errors/runtime_@ptrFromInt_to_comptime_only_type.zig diff --git a/src/Sema.zig b/src/Sema.zig index ca6d562eef..ba18869cdf 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -22722,7 +22722,16 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! .storage = .{ .elems = new_elems }, } })); } + if (try sema.typeRequiresComptime(ptr_ty)) { + return sema.failWithOwnedErrorMsg(block, msg: { + const msg = try sema.errMsg(block, src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(mod)}); + errdefer msg.destroy(sema.gpa); + const src_decl = mod.declPtr(block.src_decl); + try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(src, mod), ptr_ty); + break :msg msg; + }); + } try sema.requireRuntimeBlock(block, src, operand_src); if (!is_vector) { if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) { diff --git a/test/cases/compile_errors/runtime_@ptrFromInt_to_comptime_only_type.zig b/test/cases/compile_errors/runtime_@ptrFromInt_to_comptime_only_type.zig new file mode 100644 index 0000000000..0c4e844e76 --- /dev/null +++ b/test/cases/compile_errors/runtime_@ptrFromInt_to_comptime_only_type.zig @@ -0,0 +1,16 @@ +const GuSettings = struct { + fin: ?fn (c_int) callconv(.C) void, +}; +pub export fn callbackFin(id: c_int, arg: ?*anyopaque) void { + const settings: ?*GuSettings = @as(?*GuSettings, @ptrFromInt(@intFromPtr(arg))); + if (settings.?.fin != null) { + settings.?.fin.?(id & 0xffff); + } +} + +// error +// target=native +// +// :5:54: error: pointer to comptime-only type '?*tmp.GuSettings' must be comptime-known, but operand is runtime-known +// :2:10: note: struct requires comptime because of this field +// :2:10: note: use '*const fn (c_int) callconv(.C) void' for a function pointer type