diff --git a/src/ir.cpp b/src/ir.cpp index 1edb12267..68a0b7f6f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -67,6 +67,8 @@ enum ConstCastResultId { struct ConstCastOnly; struct ConstCastArg { size_t arg_index; + ZigType *actual_param_type; + ZigType *expected_param_type; ConstCastOnly *child; }; @@ -8638,6 +8640,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted if (arg_child.id != ConstCastResultIdOk) { result.id = ConstCastResultIdFnArg; result.data.fn_arg.arg_index = i; + result.data.fn_arg.actual_param_type = actual_param_info->type; + result.data.fn_arg.expected_param_type = expected_param_info->type; result.data.fn_arg.child = allocate_nonzero(1); *result.data.fn_arg.child = arg_child; return result; @@ -10483,6 +10487,15 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa } break; } + case ConstCastResultIdFnArg: { + ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, + buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'", + cast_result->data.fn_arg.arg_index, + buf_ptr(&cast_result->data.fn_arg.actual_param_type->name), + buf_ptr(&cast_result->data.fn_arg.expected_param_type->name))); + report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg); + break; + } case ConstCastResultIdFnAlign: // TODO case ConstCastResultIdFnCC: // TODO case ConstCastResultIdFnVarArgs: // TODO @@ -10490,7 +10503,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa case ConstCastResultIdFnReturnType: // TODO case ConstCastResultIdFnArgCount: // TODO case ConstCastResultIdFnGenericArgCount: // TODO - case ConstCastResultIdFnArg: // TODO case ConstCastResultIdFnArgNoAlias: // TODO case ConstCastResultIdUnresolvedInferredErrSet: // TODO case ConstCastResultIdAsyncAllocatorType: // TODO diff --git a/test/compile_errors.zig b/test/compile_errors.zig index c5575a0c0..be839f055 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1,6 +1,18 @@ const tests = @import("tests.zig"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "error note for function parameter incompatibility", + \\fn do_the_thing(func: fn (arg: i32) void) void {} + \\fn bar(arg: bool) void {} + \\export fn entry() void { + \\ do_the_thing(bar); + \\} + , + ".tmp_source.zig:4:18: error: expected type 'fn(i32) void', found 'fn(bool) void", + ".tmp_source.zig:4:18: note: parameter 0: 'bool' cannot cast into 'i32'", + ); + cases.add( "cast negative value to unsigned integer", \\comptime { @@ -5248,8 +5260,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn foo() void { \\ asm volatile ("" : : [bar]"r"(3) : ""); \\} - , - ".tmp_source.zig:2:35: error: expected sized integer or sized float, found comptime_int", + , + ".tmp_source.zig:2:35: error: expected sized integer or sized float, found comptime_int", ); cases.add( @@ -5257,7 +5269,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn foo() void { \\ asm volatile ("" : : [bar]"r"(3.17) : ""); \\} - , - ".tmp_source.zig:2:35: error: expected sized integer or sized float, found comptime_float", + , + ".tmp_source.zig:2:35: error: expected sized integer or sized float, found comptime_float", ); }