authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-30 12:21:24-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-30 12:21:24-04:00
log43e7ac8418172e16def3ed8abf12e303738d7569
tree6b86526c71d127b09b44d010681e07ba1d64e367
parent29defd705dcaf25d4a080f7db8f76e8787fca146

add peer type resolution `[]T` and `[0]T`

closes #349 also fix slicing const array to be []const T instead of []T

4 files changed, 53 insertions(+), 18 deletions(-)

src/ir.cpp+11-7
...@@ -6218,16 +6218,18 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6218,16 +6218,18 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6218 convert_to_const_slice = true;6218 convert_to_const_slice = true;
6219 continue;6219 continue;
6220 } else if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&6220 } else if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
6221 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const &&6221 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6222 types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,6222 cur_type->data.array.len == 0) &&
6223 cur_type->data.array.child_type))6223 types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6224 cur_type->data.array.child_type))
6224 {6225 {
6225 convert_to_const_slice = false;6226 convert_to_const_slice = false;
6226 continue;6227 continue;
6227 } else if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&6228 } else if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
6228 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const &&6229 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6229 types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,6230 prev_type->data.array.len == 0) &&
6230 prev_type->data.array.child_type))6231 types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6232 prev_type->data.array.child_type))
6231 {6233 {
6232 prev_inst = cur_inst;6234 prev_inst = cur_inst;
6233 convert_to_const_slice = false;6235 convert_to_const_slice = false;
...@@ -6796,8 +6798,9 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi...@@ -6796,8 +6798,9 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
6796 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);6798 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
6797 if (!val)6799 if (!val)
6798 return ira->codegen->invalid_instruction;6800 return ira->codegen->invalid_instruction;
6801 bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true;
6799 return ir_get_const_ptr(ira, source_instruction, val, value->value.type,6802 return ir_get_const_ptr(ira, source_instruction, val, value->value.type,
6800 ConstPtrMutComptimeConst, is_const, is_volatile);6803 ConstPtrMutComptimeConst, final_is_const, is_volatile);
6801 }6804 }
68026805
6803 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, is_const, is_volatile, 0, 0);6806 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, is_const, is_volatile, 0, 0);
...@@ -6806,6 +6809,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi...@@ -6806,6 +6809,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
6806 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,6809 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
6807 source_instruction->source_node, value, is_const, is_volatile);6810 source_instruction->source_node, value, is_const, is_volatile);
6808 new_instruction->value.type = ptr_type;6811 new_instruction->value.type = ptr_type;
6812 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack;
6809 fn_entry->alloca_list.append(new_instruction);6813 fn_entry->alloca_list.append(new_instruction);
6810 return new_instruction;6814 return new_instruction;
6811}6815}
test/cases/cast.zig+22
...@@ -173,3 +173,25 @@ fn testCastZeroArrayToErrSliceMut() {...@@ -173,3 +173,25 @@ fn testCastZeroArrayToErrSliceMut() {
173fn gimmeErrOrSlice() -> %[]u8 {173fn gimmeErrOrSlice() -> %[]u8 {
174 return []u8{};174 return []u8{};
175}175}
176
177test "peer type resolution: [0]u8, []const u8, and %[]u8" {
178 {
179 var data = "hi";
180 const slice = data[0...];
181 assert((%%peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
182 assert((%%peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
183 }
184 comptime {
185 var data = "hi";
186 const slice = data[0...];
187 assert((%%peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
188 assert((%%peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
189 }
190}
191fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) -> %[]u8 {
192 if (a) {
193 return []u8{};
194 }
195
196 return slice[0...1];
197}
test/cases/misc.zig+8
...@@ -486,3 +486,11 @@ test "volatileLoadAndStore" {...@@ -486,3 +486,11 @@ test "volatileLoadAndStore" {
486 *ptr += 1;486 *ptr += 1;
487 assert(*ptr == 1235);487 assert(*ptr == 1235);
488}488}
489
490test "slice string literal has type []const u8" {
491 comptime {
492 assert(@typeOf("aoeu"[0...]) == []const u8);
493 const array = []i32{1, 2, 3, 4};
494 assert(@typeOf(array[0...]) == []const i32);
495 }
496}
test/cases/struct_contains_slice_of_itself.zig+12-11
...@@ -5,7 +5,17 @@ const Node = struct {...@@ -5,7 +5,17 @@ const Node = struct {
5 children: []Node,5 children: []Node,
6};6};
77
8test "structContainsSliceOfItself" {8test "struct contains slice of itself" {
9 var other_nodes = []Node{
10 Node {
11 .payload = 31,
12 .children = []Node{},
13 },
14 Node {
15 .payload = 32,
16 .children = []Node{},
17 },
18 };
9 var nodes = []Node {19 var nodes = []Node {
10 Node {20 Node {
11 .payload = 1,21 .payload = 1,
...@@ -17,16 +27,7 @@ test "structContainsSliceOfItself" {...@@ -17,16 +27,7 @@ test "structContainsSliceOfItself" {
17 },27 },
18 Node {28 Node {
19 .payload = 3,29 .payload = 3,
20 .children = ([]Node{30 .children = other_nodes[0...],
21 Node {
22 .payload = 31,
23 .children = []Node{},
24 },
25 Node {
26 .payload = 32,
27 .children = []Node{},
28 },
29 })[0...],
30 },31 },
31 };32 };
32 const root = Node {33 const root = Node {