From 736df276632ad66294a7491a5e35a039dd2c836f Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 9 Aug 2023 09:26:16 -0400 Subject: [PATCH] Sema: use the correct decl for generic argument source locations Closes #16746 --- src/Sema.zig | 37 ++++++++++++++++++------------------- test/compile_errors.zig | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 973cc35be2..ac9886fa62 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9219,6 +9219,21 @@ fn finishFunc( return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty); } +fn genericArgSrcLoc(sema: *Sema, block: *Block, param_index: u32, param_src: LazySrcLoc) Module.SrcLoc { + const mod = sema.mod; + if (sema.generic_owner == .none) return param_src.toSrcLoc(mod.declPtr(block.src_decl), mod); + const arg_decl = sema.generic_call_decl.unwrap().?; + const arg_src: LazySrcLoc = if (param_index == 0 and sema.generic_bound_arg_src != null) + sema.generic_bound_arg_src.? + else + .{ .call_arg = .{ + .decl = arg_decl, + .call_node_offset = sema.generic_call_src.node_offset.x, + .arg_index = param_index - @intFromBool(sema.generic_bound_arg_src != null), + } }; + return arg_src.toSrcLoc(mod.declPtr(arg_decl), mod); +} + fn zirParam( sema: *Sema, block: *Block, @@ -9226,7 +9241,6 @@ fn zirParam( param_index: u32, comptime_syntax: bool, ) CompileError!void { - const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[inst].pl_tok; const src = inst_data.src(); @@ -9330,15 +9344,8 @@ fn zirParam( sema.comptime_args[param_index] = val.toIntern(); return; } - const arg_src: LazySrcLoc = if (param_index == 0 and sema.generic_bound_arg_src != null) - sema.generic_bound_arg_src.? - else if (sema.generic_call_src == .node_offset) .{ .call_arg = .{ - .decl = sema.generic_call_decl.unwrap().?, - .call_node_offset = sema.generic_call_src.node_offset.x, - .arg_index = param_index - @intFromBool(sema.generic_bound_arg_src != null), - } } else src; const msg = msg: { - const src_loc = arg_src.toSrcLoc(mod.declPtr(block.src_decl), mod); + const src_loc = sema.genericArgSrcLoc(block, param_index, src); const msg = try Module.ErrorMsg.create(gpa, src_loc, "{s}", .{ @as([]const u8, "runtime-known argument passed to comptime parameter"), }); @@ -9384,7 +9391,6 @@ fn zirParamAnytype( param_index: u32, comptime_syntax: bool, ) CompileError!void { - const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[inst].str_tok; const param_name: Zir.NullTerminatedString = @enumFromInt(inst_data.start); @@ -9398,13 +9404,6 @@ fn zirParamAnytype( sema.comptime_args[param_index] = opv.toIntern(); return; } - const arg_src: LazySrcLoc = if (param_index == 0 and sema.generic_bound_arg_src != null) - sema.generic_bound_arg_src.? - else if (sema.generic_call_src == .node_offset) .{ .call_arg = .{ - .decl = sema.generic_call_decl.unwrap().?, - .call_node_offset = sema.generic_call_src.node_offset.x, - .arg_index = param_index - @intFromBool(sema.generic_bound_arg_src != null), - } } else src; if (comptime_syntax) { if (try sema.resolveMaybeUndefVal(air_ref)) |val| { @@ -9412,7 +9411,7 @@ fn zirParamAnytype( return; } const msg = msg: { - const src_loc = arg_src.toSrcLoc(mod.declPtr(block.src_decl), mod); + const src_loc = sema.genericArgSrcLoc(block, param_index, src); const msg = try Module.ErrorMsg.create(gpa, src_loc, "{s}", .{ @as([]const u8, "runtime-known argument passed to comptime parameter"), }); @@ -9432,7 +9431,7 @@ fn zirParamAnytype( return; } const msg = msg: { - const src_loc = arg_src.toSrcLoc(mod.declPtr(block.src_decl), mod); + const src_loc = sema.genericArgSrcLoc(block, param_index, src); const msg = try Module.ErrorMsg.create(gpa, src_loc, "{s}", .{ @as([]const u8, "runtime-known argument passed to comptime-only type parameter"), }); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 5a60ef2e55..8675eb9ed7 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -183,4 +183,40 @@ pub fn addCases(ctx: *Cases) !void { ":1:1: note: invalid byte: '\\xff'", }); } + + { + const case = ctx.obj("imported generic method call with invalid param", .{}); + + case.addError( + \\pub const import = @import("import.zig"); + \\ + \\export fn callComptimeBoolFunctionWithRuntimeBool(x: bool) void { + \\ import.comptimeBoolFunction(x); + \\} + \\ + \\export fn callComptimeAnytypeFunctionWithRuntimeBool(x: bool) void { + \\ import.comptimeAnytypeFunction(x); + \\} + \\ + \\export fn callAnytypeFunctionWithRuntimeComptimeOnlyType(x: u32) void { + \\ const S = struct { x: u32, y: type }; + \\ import.anytypeFunction(S{ .x = x, .y = u32 }); + \\} + , &[_][]const u8{ + ":4:33: error: runtime-known argument passed to comptime parameter", + ":1:38: note: declared comptime here", + ":8:36: error: runtime-known argument passed to comptime parameter", + ":2:41: note: declared comptime here", + ":13:29: error: runtime-known argument passed to comptime-only type parameter", + ":3:24: note: declared here", + ":12:35: note: struct requires comptime because of this field", + ":12:35: note: types are not available at runtime", + }); + + case.addSourceFile("import.zig", + \\pub fn comptimeBoolFunction(comptime _: bool) void {} + \\pub fn comptimeAnytypeFunction(comptime _: anytype) void {} + \\pub fn anytypeFunction(_: anytype) void {} + ); + } }