Commit 2618366055

Timon Kruiper <timonkruiper@gmail.com>
2020-02-10 23:42:07
Add cast between [*c]T and ?[*:0]T on fn parameter
Fixes #4176
1 parent 3237528
Changed files (2)
src
test
stage1
behavior
src/ir.cpp
@@ -11592,7 +11592,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
             wanted_ptr_type->data.pointer.sentinel == nullptr ||
             (actual_ptr_type->data.pointer.sentinel != nullptr &&
              const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel,
-                 actual_ptr_type->data.pointer.sentinel));
+                 actual_ptr_type->data.pointer.sentinel)) ||
+            actual_ptr_type->data.pointer.ptr_len == PtrLenC;
         if (!ok_null_term_ptrs) {
             result.id = ConstCastResultIdPtrSentinel;
             result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1);
test/stage1/behavior/cast.zig
@@ -768,3 +768,17 @@ test "variable initialization uses result locations properly with regards to the
     const x: i32 = if (b) 1 else 2;
     expect(x == 1);
 }
+
+test "cast between [*c]T and ?[*:0]T on fn parameter" {
+    const S = struct {
+        const Handler = ?extern fn ([*c]const u8) void;
+        fn addCallback(handler: Handler) void {}
+
+        fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {}
+
+        fn doTheTest() void {
+            addCallback(myCallback);
+        }
+    };
+    S.doTheTest();
+}