Commit 9aa65c0e8e

Ben Noordhuis <info@bnoordhuis.nl>
2018-02-26 18:40:33
allow implicit cast from &const to ?&const &const
Allow implicit casts from n-th degree const pointers to nullable const pointers of degree n+1. That is: fn f() void { const s = S {}; const p = &s; g(p); // Works. g(&p); // So does this. } fn g(_: ?&const &const S) void { // Nullable 2nd degree const ptr. } Fixes #731 some more.
1 parent 1eecfda
Changed files (2)
src
test
cases
src/ir.cpp
@@ -8830,7 +8830,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
             }
         } else if (wanted_child_type->id == TypeTableEntryIdPointer &&
                    wanted_child_type->data.pointer.is_const &&
-                   is_container(actual_type)) {
+                   (actual_type->id == TypeTableEntryIdPointer || is_container(actual_type)))
+        {
             IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_child_type, value);
             if (type_is_invalid(cast1->value.type))
                 return ira->codegen->invalid_instruction;
test/cases/cast.zig
@@ -103,6 +103,37 @@ const Enum = enum {
     }
 };
 
+test "implicitly cast indirect pointer to maybe-indirect pointer" {
+    const S = struct {
+        const Self = this;
+        x: u8,
+        fn constConst(p: &const &const Self) u8 {
+            return (*p).x;
+        }
+        fn maybeConstConst(p: ?&const &const Self) u8 {
+            return (*??p).x;
+        }
+        fn constConstConst(p: &const &const &const Self) u8 {
+            return (**p).x;
+        }
+        fn maybeConstConstConst(p: ?&const &const &const Self) u8 {
+            return (**??p).x;
+        }
+    };
+    const s = S { .x = 42 };
+    const p = &s;
+    const q = &p;
+    const r = &q;
+    assert(42 == S.constConst(p));
+    assert(42 == S.constConst(q));
+    assert(42 == S.maybeConstConst(p));
+    assert(42 == S.maybeConstConst(q));
+    assert(42 == S.constConstConst(q));
+    assert(42 == S.constConstConst(r));
+    assert(42 == S.maybeConstConstConst(q));
+    assert(42 == S.maybeConstConstConst(r));
+}
+
 test "explicit cast from integer to error type" {
     testCastIntToErr(error.ItBroke);
     comptime testCastIntToErr(error.ItBroke);