Commit 1b0f4d5976

Andrew Kelley <andrew@ziglang.org>
2018-12-05 21:32:25
implement compile error note for function parameter type mismatch
1 parent 518ff33
Changed files (2)
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<ConstCastOnly>(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
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",
     );
 }