authorgravatar for info@bnoordhuis.nlBen Noordhuis <info@bnoordhuis.nl> 2018-02-26 18:40:33+01:00
committergravatar for info@bnoordhuis.nlBen Noordhuis <info@bnoordhuis.nl> 2018-02-26 19:56:26+01:00
log9aa65c0e8e6e4135dcc04bcb388d1fa38c6d10f6
treed7bedb06367d28f4851fc2020f3fa6ca84b96294
parent1eecfdaa9b9c04e50058695b8df9978ef47f121a

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.

2 files changed, 33 insertions(+), 1 deletions(-)

src/ir.cpp+2-1
...@@ -8830,7 +8830,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8830,7 +8830,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8830 }8830 }
8831 } else if (wanted_child_type->id == TypeTableEntryIdPointer &&8831 } else if (wanted_child_type->id == TypeTableEntryIdPointer &&
8832 wanted_child_type->data.pointer.is_const &&8832 wanted_child_type->data.pointer.is_const &&
8833 is_container(actual_type)) {8833 (actual_type->id == TypeTableEntryIdPointer || is_container(actual_type)))
8834 {
8834 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_child_type, value);8835 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_child_type, value);
8835 if (type_is_invalid(cast1->value.type))8836 if (type_is_invalid(cast1->value.type))
8836 return ira->codegen->invalid_instruction;8837 return ira->codegen->invalid_instruction;
test/cases/cast.zig+31
...@@ -103,6 +103,37 @@ const Enum = enum {...@@ -103,6 +103,37 @@ const Enum = enum {
103 }103 }
104};104};
105105
106test "implicitly cast indirect pointer to maybe-indirect pointer" {
107 const S = struct {
108 const Self = this;
109 x: u8,
110 fn constConst(p: &const &const Self) u8 {
111 return (*p).x;
112 }
113 fn maybeConstConst(p: ?&const &const Self) u8 {
114 return (*??p).x;
115 }
116 fn constConstConst(p: &const &const &const Self) u8 {
117 return (**p).x;
118 }
119 fn maybeConstConstConst(p: ?&const &const &const Self) u8 {
120 return (**??p).x;
121 }
122 };
123 const s = S { .x = 42 };
124 const p = &s;
125 const q = &p;
126 const r = &q;
127 assert(42 == S.constConst(p));
128 assert(42 == S.constConst(q));
129 assert(42 == S.maybeConstConst(p));
130 assert(42 == S.maybeConstConst(q));
131 assert(42 == S.constConstConst(q));
132 assert(42 == S.constConstConst(r));
133 assert(42 == S.maybeConstConstConst(q));
134 assert(42 == S.maybeConstConstConst(r));
135}
136
106test "explicit cast from integer to error type" {137test "explicit cast from integer to error type" {
107 testCastIntToErr(error.ItBroke);138 testCastIntToErr(error.ItBroke);
108 comptime testCastIntToErr(error.ItBroke);139 comptime testCastIntToErr(error.ItBroke);