authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-25 13:39:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-25 13:39:46-04:00
log683da0e4ecd336f9a74098d49d5748bdc1ed2f70
treefa16c8486981f6d8497c0eca319c3fcdb5bf75fa
parente06885d64e3569719e9479c7069da7ad426a70d3

ability to have struct to have a field which is slice of itself

closes #197

3 files changed, 52 insertions(+), 3 deletions(-)

src/analyze.cpp+8-3
...@@ -1589,6 +1589,9 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1589,6 +1589,9 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
15891589
1590 TypeTableEntry *field_type = type_struct_field->type_entry;1590 TypeTableEntry *field_type = type_struct_field->type_entry;
15911591
1592 assert(field_type->type_ref);
1593 assert(struct_type->type_ref);
1594 assert(struct_type->data.structure.complete);
1592 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);1595 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1593 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);1596 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);
1594 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref,1597 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref,
...@@ -4065,7 +4068,8 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,...@@ -4065,7 +4068,8 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
4065{4068{
4066 AstNode *size_node = node->data.array_type.size;4069 AstNode *size_node = node->data.array_type.size;
40674070
4068 TypeTableEntry *child_type = analyze_type_expr(g, import, context, node->data.array_type.child_type);4071 TypeTableEntry *child_type = analyze_type_expr_pointer_only(g, import, context,
4072 node->data.array_type.child_type, true);
40694073
4070 if (child_type->id == TypeTableEntryIdUnreachable) {4074 if (child_type->id == TypeTableEntryIdUnreachable) {
4071 add_node_error(g, node, buf_create_from_str("array of unreachable not allowed"));4075 add_node_error(g, node, buf_create_from_str("array of unreachable not allowed"));
...@@ -4075,6 +4079,7 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,...@@ -4075,6 +4079,7 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
4075 }4079 }
40764080
4077 if (size_node) {4081 if (size_node) {
4082 child_type = analyze_type_expr(g, import, context, node->data.array_type.child_type);
4078 TypeTableEntry *size_type = analyze_expression(g, import, context,4083 TypeTableEntry *size_type = analyze_expression(g, import, context,
4079 g->builtin_types.entry_usize, size_node);4084 g->builtin_types.entry_usize, size_node);
4080 if (size_type->id == TypeTableEntryIdInvalid) {4085 if (size_type->id == TypeTableEntryIdInvalid) {
...@@ -4101,8 +4106,8 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,...@@ -4101,8 +4106,8 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
4101 return g->builtin_types.entry_invalid;4106 return g->builtin_types.entry_invalid;
4102 }4107 }
4103 } else {4108 } else {
4104 return resolve_expr_const_val_as_type(g, node,4109 TypeTableEntry *slice_type = get_slice_type(g, child_type, node->data.array_type.is_const);
4105 get_slice_type(g, child_type, node->data.array_type.is_const), false);4110 return resolve_expr_const_val_as_type(g, node, slice_type, false);
4106 }4111 }
4107}4112}
41084113
test/cases/struct_contains_slice_of_itself.zig created+43
...@@ -0,0 +1,43 @@
1const assert = @import("std").debug.assert;
2
3struct Node {
4 payload: i32,
5 children: []Node,
6}
7
8#attribute("test")
9fn structContainsSliceOfItself() {
10 var nodes = []Node {
11 Node {
12 .payload = 1,
13 .children = []Node{},
14 },
15 Node {
16 .payload = 2,
17 .children = []Node{},
18 },
19 Node {
20 .payload = 3,
21 .children = []Node{
22 Node {
23 .payload = 31,
24 .children = []Node{},
25 },
26 Node {
27 .payload = 32,
28 .children = []Node{},
29 },
30 },
31 },
32 };
33 const root = Node {
34 .payload = 1234,
35 .children = nodes[0...],
36 };
37 assert(root.payload == 1234);
38 assert(root.children[0].payload == 1);
39 assert(root.children[1].payload == 2);
40 assert(root.children[2].payload == 3);
41 assert(root.children[2].children[0].payload == 31);
42 assert(root.children[2].children[1].payload == 32);
43}
test/self_hosted.zig+1
...@@ -14,6 +14,7 @@ const test_const_slice_child = @import("cases/const_slice_child.zig");...@@ -14,6 +14,7 @@ const test_const_slice_child = @import("cases/const_slice_child.zig");
14const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");14const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");
15const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");15const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
16const test_enum_with_members = @import("cases/enum_with_members.zig");16const test_enum_with_members = @import("cases/enum_with_members.zig");
17const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");
1718
18// normal comment19// normal comment
19/// this is a documentation comment20/// this is a documentation comment