authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-02 21:36:41+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-03 00:48:04+02:00
logb500e0eb179218f5eb03408c09b5e5a928f0c46e
tree5bfba354de8733d79ee13a465b6530bc1bd7e5f7
parent74285a4ed70848452f34623454d665daae7f9522

Sema: add "parameter type declared here" note to type coercion


11 files changed, 62 insertions(+), 11 deletions(-)

src/Sema.zig+52-11
...@@ -291,8 +291,8 @@ pub const Block = struct {...@@ -291,8 +291,8 @@ pub const Block = struct {
291 try sema.errNote(ci.block, ci.src, parent, prefix ++ "it is inside a @cImport", .{});291 try sema.errNote(ci.block, ci.src, parent, prefix ++ "it is inside a @cImport", .{});
292 },292 },
293 .comptime_ret_ty => |rt| {293 .comptime_ret_ty => |rt| {
294 const src_loc = if (try sema.funcDeclSrc(rt.func)) |capture| blk: {294 const src_loc = if (try sema.funcDeclSrc(rt.func)) |fn_decl| blk: {
295 var src_loc = capture;295 var src_loc = fn_decl.srcLoc();
296 src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 };296 src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 };
297 break :blk src_loc;297 break :blk src_loc;
298 } else blk: {298 } else blk: {
...@@ -5843,7 +5843,7 @@ fn lookupInNamespace(...@@ -5843,7 +5843,7 @@ fn lookupInNamespace(
5843 return null;5843 return null;
5844}5844}
58455845
5846fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?Module.SrcLoc {5846fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
5847 const func_val = (try sema.resolveMaybeUndefVal(func_inst)) orelse return null;5847 const func_val = (try sema.resolveMaybeUndefVal(func_inst)) orelse return null;
5848 if (func_val.isUndef()) return null;5848 if (func_val.isUndef()) return null;
5849 const owner_decl_index = switch (func_val.tag()) {5849 const owner_decl_index = switch (func_val.tag()) {
...@@ -5852,8 +5852,7 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?Module.SrcLoc {...@@ -5852,8 +5852,7 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?Module.SrcLoc {
5852 .decl_ref => sema.mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data.owner_decl,5852 .decl_ref => sema.mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data.owner_decl,
5853 else => return null,5853 else => return null,
5854 };5854 };
5855 const owner_decl = sema.mod.declPtr(owner_decl_index);5855 return sema.mod.declPtr(owner_decl_index);
5856 return owner_decl.srcLoc();
5857}5856}
58585857
5859pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {5858pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
...@@ -6031,7 +6030,7 @@ fn zirCall(...@@ -6031,7 +6030,7 @@ fn zirCall(
6031 break :check_args;6030 break :check_args;
6032 }6031 }
60336032
6034 const decl_src = try sema.funcDeclSrc(func);6033 const maybe_decl = try sema.funcDeclSrc(func);
6035 const member_str = if (bound_arg_src != null) "member function " else "";6034 const member_str = if (bound_arg_src != null) "member function " else "";
6036 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";6035 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
6037 const msg = msg: {6036 const msg = msg: {
...@@ -6048,7 +6047,7 @@ fn zirCall(...@@ -6048,7 +6047,7 @@ fn zirCall(
6048 );6047 );
6049 errdefer msg.destroy(sema.gpa);6048 errdefer msg.destroy(sema.gpa);
60506049
6051 if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});6050 if (maybe_decl) |fn_decl| try sema.mod.errNoteNonLazy(fn_decl.srcLoc(), msg, "function declared here", .{});
6052 break :msg msg;6051 break :msg msg;
6053 };6052 };
6054 return sema.failWithOwnedErrorMsg(msg);6053 return sema.failWithOwnedErrorMsg(msg);
...@@ -6242,7 +6241,7 @@ fn analyzeCall(...@@ -6242,7 +6241,7 @@ fn analyzeCall(
6242 const func_ty_info = func_ty.fnInfo();6241 const func_ty_info = func_ty.fnInfo();
6243 const cc = func_ty_info.cc;6242 const cc = func_ty_info.cc;
6244 if (cc == .Naked) {6243 if (cc == .Naked) {
6245 const decl_src = try sema.funcDeclSrc(func);6244 const maybe_decl = try sema.funcDeclSrc(func);
6246 const msg = msg: {6245 const msg = msg: {
6247 const msg = try sema.errMsg(6246 const msg = try sema.errMsg(
6248 block,6247 block,
...@@ -6252,7 +6251,7 @@ fn analyzeCall(...@@ -6252,7 +6251,7 @@ fn analyzeCall(
6252 );6251 );
6253 errdefer msg.destroy(sema.gpa);6252 errdefer msg.destroy(sema.gpa);
62546253
6255 if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});6254 if (maybe_decl) |fn_decl| try sema.mod.errNoteNonLazy(fn_decl.srcLoc(), msg, "function declared here", .{});
6256 break :msg msg;6255 break :msg msg;
6257 };6256 };
6258 return sema.failWithOwnedErrorMsg(msg);6257 return sema.failWithOwnedErrorMsg(msg);
...@@ -6488,6 +6487,7 @@ fn analyzeCall(...@@ -6488,6 +6487,7 @@ fn analyzeCall(
6488 &should_memoize,6487 &should_memoize,
6489 memoized_call_key,6488 memoized_call_key,
6490 func_ty_info.param_types,6489 func_ty_info.param_types,
6490 func,
6491 ) catch |err| switch (err) {6491 ) catch |err| switch (err) {
6492 error.NeededSourceLocation => {6492 error.NeededSourceLocation => {
6493 _ = sema.inst_map.remove(inst);6493 _ = sema.inst_map.remove(inst);
...@@ -6504,6 +6504,7 @@ fn analyzeCall(...@@ -6504,6 +6504,7 @@ fn analyzeCall(
6504 &should_memoize,6504 &should_memoize,
6505 memoized_call_key,6505 memoized_call_key,
6506 func_ty_info.param_types,6506 func_ty_info.param_types,
6507 func,
6507 );6508 );
6508 return error.AnalysisFail;6509 return error.AnalysisFail;
6509 },6510 },
...@@ -6646,12 +6647,17 @@ fn analyzeCall(...@@ -6646,12 +6647,17 @@ fn analyzeCall(
6646 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);6647 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);
6647 for (uncasted_args) |uncasted_arg, i| {6648 for (uncasted_args) |uncasted_arg, i| {
6648 if (i < fn_params_len) {6649 if (i < fn_params_len) {
6650 const opts: CoerceOpts = .{ .param_src = .{
6651 .func_inst = func,
6652 .param_i = @intCast(u32, i),
6653 } };
6649 const param_ty = func_ty.fnParamType(i);6654 const param_ty = func_ty.fnParamType(i);
6650 args[i] = sema.analyzeCallArg(6655 args[i] = sema.analyzeCallArg(
6651 block,6656 block,
6652 .unneeded,6657 .unneeded,
6653 param_ty,6658 param_ty,
6654 uncasted_arg,6659 uncasted_arg,
6660 opts,
6655 ) catch |err| switch (err) {6661 ) catch |err| switch (err) {
6656 error.NeededSourceLocation => {6662 error.NeededSourceLocation => {
6657 const decl = sema.mod.declPtr(block.src_decl);6663 const decl = sema.mod.declPtr(block.src_decl);
...@@ -6660,6 +6666,7 @@ fn analyzeCall(...@@ -6660,6 +6666,7 @@ fn analyzeCall(
6660 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src),6666 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src),
6661 param_ty,6667 param_ty,
6662 uncasted_arg,6668 uncasted_arg,
6669 opts,
6663 );6670 );
6664 return error.AnalysisFail;6671 return error.AnalysisFail;
6665 },6672 },
...@@ -6741,6 +6748,7 @@ fn analyzeInlineCallArg(...@@ -6741,6 +6748,7 @@ fn analyzeInlineCallArg(
6741 should_memoize: *bool,6748 should_memoize: *bool,
6742 memoized_call_key: Module.MemoizedCall.Key,6749 memoized_call_key: Module.MemoizedCall.Key,
6743 raw_param_types: []const Type,6750 raw_param_types: []const Type,
6751 func_inst: Air.Inst.Ref,
6744) !void {6752) !void {
6745 const zir_tags = sema.code.instructions.items(.tag);6753 const zir_tags = sema.code.instructions.items(.tag);
6746 switch (zir_tags[inst]) {6754 switch (zir_tags[inst]) {
...@@ -6765,7 +6773,13 @@ fn analyzeInlineCallArg(...@@ -6765,7 +6773,13 @@ fn analyzeInlineCallArg(
6765 return err;6773 return err;
6766 };6774 };
6767 }6775 }
6768 const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src);6776 const casted_arg = sema.coerceExtra(arg_block, param_ty, uncasted_arg, arg_src, .{ .param_src = .{
6777 .func_inst = func_inst,
6778 .param_i = @intCast(u32, arg_i.*),
6779 } }) catch |err| switch (err) {
6780 error.NotCoercible => unreachable,
6781 else => |e| return e,
6782 };
67696783
6770 if (is_comptime_call) {6784 if (is_comptime_call) {
6771 sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg);6785 sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg);
...@@ -6855,9 +6869,13 @@ fn analyzeCallArg(...@@ -6855,9 +6869,13 @@ fn analyzeCallArg(
6855 arg_src: LazySrcLoc,6869 arg_src: LazySrcLoc,
6856 param_ty: Type,6870 param_ty: Type,
6857 uncasted_arg: Air.Inst.Ref,6871 uncasted_arg: Air.Inst.Ref,
6872 opts: CoerceOpts,
6858) !Air.Inst.Ref {6873) !Air.Inst.Ref {
6859 try sema.resolveTypeFully(param_ty);6874 try sema.resolveTypeFully(param_ty);
6860 return sema.coerce(block, param_ty, uncasted_arg, arg_src);6875 return sema.coerceExtra(block, param_ty, uncasted_arg, arg_src, opts) catch |err| switch (err) {
6876 error.NotCoercible => unreachable,
6877 else => |e| return e,
6878 };
6861}6879}
68626880
6863fn analyzeGenericCallArg(6881fn analyzeGenericCallArg(
...@@ -24056,6 +24074,25 @@ const CoerceOpts = struct {...@@ -24056,6 +24074,25 @@ const CoerceOpts = struct {
24056 is_ret: bool = false,24074 is_ret: bool = false,
24057 /// Should coercion to comptime_int ermit an error message.24075 /// Should coercion to comptime_int ermit an error message.
24058 no_cast_to_comptime_int: bool = false,24076 no_cast_to_comptime_int: bool = false,
24077
24078 param_src: struct {
24079 func_inst: Air.Inst.Ref = .none,
24080 param_i: u32 = undefined,
24081
24082 fn get(info: @This(), sema: *Sema) !?Module.SrcLoc {
24083 if (info.func_inst == .none) return null;
24084 const fn_decl = (try sema.funcDeclSrc(info.func_inst)) orelse return null;
24085 const param_src = Module.paramSrc(0, sema.gpa, fn_decl, info.param_i);
24086 if (param_src == .node_offset_param) {
24087 return Module.SrcLoc{
24088 .file_scope = fn_decl.getFileScope(),
24089 .parent_decl_node = fn_decl.src_node,
24090 .lazy = LazySrcLoc.nodeOffset(param_src.node_offset_param),
24091 };
24092 }
24093 return param_src.toSrcLoc(fn_decl);
24094 }
24095 } = .{},
24059};24096};
2406024097
24061fn coerceExtra(24098fn coerceExtra(
...@@ -24715,6 +24752,10 @@ fn coerceExtra(...@@ -24715,6 +24752,10 @@ fn coerceExtra(
24715 }24752 }
24716 }24753 }
2471724754
24755 if (try opts.param_src.get(sema)) |param_src| {
24756 try sema.mod.errNoteNonLazy(param_src, msg, "parameter type declared here", .{});
24757 }
24758
24718 // TODO maybe add "cannot store an error in type '{}'" note24759 // TODO maybe add "cannot store an error in type '{}'" note
2471924760
24720 break :msg msg;24761 break :msg msg;
test/cases/compile_errors/calling_var_args_extern_function_passing_array_instead_of_pointer.zig+1
...@@ -8,3 +8,4 @@ pub extern fn foo(format: *const u8, ...) void;...@@ -8,3 +8,4 @@ pub extern fn foo(format: *const u8, ...) void;
8// target=native8// target=native
9//9//
10// :2:16: error: expected type '*const u8', found '[5:0]u8'10// :2:16: error: expected type '*const u8', found '[5:0]u8'
11// :4:27: note: parameter type declared here
test/cases/compile_errors/casting_bit_offset_pointer_to_regular_pointer.zig+1
...@@ -21,3 +21,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }...@@ -21,3 +21,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
21// :8:16: error: expected type '*const u3', found '*align(0:3:1) const u3'21// :8:16: error: expected type '*const u3', found '*align(0:3:1) const u3'
22// :8:16: note: pointer host size '1' cannot cast into pointer host size '0'22// :8:16: note: pointer host size '1' cannot cast into pointer host size '0'
23// :8:16: note: pointer bit offset '3' cannot cast into pointer bit offset '0'23// :8:16: note: pointer bit offset '3' cannot cast into pointer bit offset '0'
24// :11:11: note: parameter type declared here
test/cases/compile_errors/closure_get_in_param_ty_instantiate_incorrectly.zig+1
...@@ -22,3 +22,4 @@ pub export fn entry() void {...@@ -22,3 +22,4 @@ pub export fn entry() void {
22// target=native22// target=native
23//23//
24// :17:25: error: expected type 'u32', found 'type'24// :17:25: error: expected type 'u32', found 'type'
25// :3:21: note: parameter type declared here
test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig+1
...@@ -11,3 +11,4 @@ pub export fn entry() void {...@@ -11,3 +11,4 @@ pub export fn entry() void {
11//11//
12// :5:14: error: expected type '[*:0]const u8', found '[*]const u8'12// :5:14: error: expected type '[*:0]const u8', found '[*]const u8'
13// :5:14: note: destination pointer requires '0' sentinel13// :5:14: note: destination pointer requires '0' sentinel
14// :1:20: note: parameter type declared here
test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig+1
...@@ -24,5 +24,6 @@ pub export fn entry3() void {...@@ -24,5 +24,6 @@ pub export fn entry3() void {
24// :4:35: note: cannot implicitly cast double pointer '*const *const usize' to anyopaque pointer '*const anyopaque'24// :4:35: note: cannot implicitly cast double pointer '*const *const usize' to anyopaque pointer '*const anyopaque'
25// :9:10: error: expected type '?*anyopaque', found '*[*:0]u8'25// :9:10: error: expected type '?*anyopaque', found '*[*:0]u8'
26// :9:10: note: cannot implicitly cast double pointer '*[*:0]u8' to anyopaque pointer '?*anyopaque'26// :9:10: note: cannot implicitly cast double pointer '*[*:0]u8' to anyopaque pointer '?*anyopaque'
27// :11:12: note: parameter type declared here
27// :15:35: error: expected type '*const anyopaque', found '*?*usize'28// :15:35: error: expected type '*const anyopaque', found '*?*usize'
28// :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque'29// :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque'
test/cases/compile_errors/implicitly_increasing_pointer_alignment.zig+1
...@@ -18,3 +18,4 @@ fn bar(x: *u32) void {...@@ -18,3 +18,4 @@ fn bar(x: *u32) void {
18//18//
19// :8:9: error: expected type '*u32', found '*align(1) u32'19// :8:9: error: expected type '*u32', found '*align(1) u32'
20// :8:9: note: pointer alignment '1' cannot cast into pointer alignment '4'20// :8:9: note: pointer alignment '1' cannot cast into pointer alignment '4'
21// :11:11: note: parameter type declared here
test/cases/compile_errors/pass_const_ptr_to_mutable_ptr_fn.zig+1
...@@ -16,3 +16,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }...@@ -16,3 +16,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
16//16//
17// :4:19: error: expected type '*[]const u8', found '*const []const u8'17// :4:19: error: expected type '*[]const u8', found '*const []const u8'
18// :4:19: note: cast discards const qualifier18// :4:19: note: cast discards const qualifier
19// :6:14: note: parameter type declared here
test/cases/compile_errors/struct_init_passed_to_type_param.zig+1
...@@ -12,3 +12,4 @@ export const value = hi(MyStruct{ .x = 12 });...@@ -12,3 +12,4 @@ export const value = hi(MyStruct{ .x = 12 });
12//12//
13// :7:33: error: expected type 'type', found 'tmp.MyStruct'13// :7:33: error: expected type 'type', found 'tmp.MyStruct'
14// :1:18: note: struct declared here14// :1:18: note: struct declared here
15// :3:19: note: parameter type declared here
test/cases/compile_errors/struct_type_mismatch_in_arg.zig+1
...@@ -15,3 +15,4 @@ comptime {...@@ -15,3 +15,4 @@ comptime {
15// :7:16: error: expected type 'tmp.Foo', found 'tmp.Bar'15// :7:16: error: expected type 'tmp.Foo', found 'tmp.Bar'
16// :1:13: note: struct declared here16// :1:13: note: struct declared here
17// :2:13: note: struct declared here17// :2:13: note: struct declared here
18// :4:18: note: parameter type declared here
test/cases/compile_errors/wrong_pointer_coerced_to_pointer_to_opaque_{}.zig+1
...@@ -12,3 +12,4 @@ export fn foo() void {...@@ -12,3 +12,4 @@ export fn foo() void {
12// :5:9: error: expected type '*tmp.Derp', found '*anyopaque'12// :5:9: error: expected type '*tmp.Derp', found '*anyopaque'
13// :5:9: note: pointer type child 'anyopaque' cannot cast into pointer type child 'tmp.Derp'13// :5:9: note: pointer type child 'anyopaque' cannot cast into pointer type child 'tmp.Derp'
14// :1:14: note: opaque declared here14// :1:14: note: opaque declared here
15// :2:18: note: parameter type declared here