Skip to content

Commit 43e7ac8

Browse files
committed
add peer type resolution []T and [0]T
closes #349 also fix slicing const array to be []const T instead of []T
1 parent 29defd7 commit 43e7ac8

File tree

4 files changed

+53
-18
lines changed

4 files changed

+53
-18
lines changed

src/ir.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6218,16 +6218,18 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
62186218
convert_to_const_slice = true;
62196219
continue;
62206220
} 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 &&
6222-
types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6223-
cur_type->data.array.child_type))
6221+
(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6222+
cur_type->data.array.len == 0) &&
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))
62246225
{
62256226
convert_to_const_slice = false;
62266227
continue;
62276228
} 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-
types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6230-
prev_type->data.array.child_type))
6229+
(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6230+
prev_type->data.array.len == 0) &&
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))
62316233
{
62326234
prev_inst = cur_inst;
62336235
convert_to_const_slice = false;
@@ -6796,8 +6798,9 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
67966798
ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
67976799
if (!val)
67986800
return ira->codegen->invalid_instruction;
6801+
bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true;
67996802
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);
68016804
}
68026805

68036806
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
68066809
IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
68076810
source_instruction->source_node, value, is_const, is_volatile);
68086811
new_instruction->value.type = ptr_type;
6812+
new_instruction->value.data.rh_ptr = RuntimeHintPtrStack;
68096813
fn_entry->alloca_list.append(new_instruction);
68106814
return new_instruction;
68116815
}

test/cases/cast.zig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,25 @@ fn testCastZeroArrayToErrSliceMut() {
173173
fn gimmeErrOrSlice() -> %[]u8 {
174174
return []u8{};
175175
}
176+
177+
test "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+
}
191+
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) -> %[]u8 {
192+
if (a) {
193+
return []u8{};
194+
}
195+
196+
return slice[0...1];
197+
}

test/cases/misc.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,11 @@ test "volatileLoadAndStore" {
486486
*ptr += 1;
487487
assert(*ptr == 1235);
488488
}
489+
490+
test "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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@ const Node = struct {
55
children: []Node,
66
};
77

8-
test "structContainsSliceOfItself" {
8+
test "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+
};
919
var nodes = []Node {
1020
Node {
1121
.payload = 1,
@@ -17,16 +27,7 @@ test "structContainsSliceOfItself" {
1727
},
1828
Node {
1929
.payload = 3,
20-
.children = ([]Node{
21-
Node {
22-
.payload = 31,
23-
.children = []Node{},
24-
},
25-
Node {
26-
.payload = 32,
27-
.children = []Node{},
28-
},
29-
})[0...],
30+
.children = other_nodes[0...],
3031
},
3132
};
3233
const root = Node {

0 commit comments

Comments
 (0)