diff --git a/src/ir.cpp b/src/ir.cpp index 6c072a7b90..0ad643a4af 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6218,16 +6218,18 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod convert_to_const_slice = true; continue; } else if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) && - prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const && - types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, - cur_type->data.array.child_type)) + (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || + cur_type->data.array.len == 0) && + types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, + cur_type->data.array.child_type)) { convert_to_const_slice = false; continue; } else if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) && - cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const && - types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, - prev_type->data.array.child_type)) + (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || + prev_type->data.array.len == 0) && + types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, + prev_type->data.array.child_type)) { prev_inst = cur_inst; convert_to_const_slice = false; @@ -6796,8 +6798,9 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); if (!val) return ira->codegen->invalid_instruction; + bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true; return ir_get_const_ptr(ira, source_instruction, val, value->value.type, - ConstPtrMutComptimeConst, is_const, is_volatile); + ConstPtrMutComptimeConst, final_is_const, is_volatile); } 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 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, source_instruction->source_node, value, is_const, is_volatile); new_instruction->value.type = ptr_type; + new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; fn_entry->alloca_list.append(new_instruction); return new_instruction; } diff --git a/test/cases/cast.zig b/test/cases/cast.zig index 849ffe3518..f51502257c 100644 --- a/test/cases/cast.zig +++ b/test/cases/cast.zig @@ -173,3 +173,25 @@ fn testCastZeroArrayToErrSliceMut() { fn gimmeErrOrSlice() -> %[]u8 { return []u8{}; } + +test "peer type resolution: [0]u8, []const u8, and %[]u8" { + { + var data = "hi"; + const slice = data[0...]; + assert((%%peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); + assert((%%peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); + } + comptime { + var data = "hi"; + const slice = data[0...]; + assert((%%peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); + assert((%%peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); + } +} +fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) -> %[]u8 { + if (a) { + return []u8{}; + } + + return slice[0...1]; +} diff --git a/test/cases/misc.zig b/test/cases/misc.zig index de69e7afc9..fbd1bd9462 100644 --- a/test/cases/misc.zig +++ b/test/cases/misc.zig @@ -486,3 +486,11 @@ test "volatileLoadAndStore" { *ptr += 1; assert(*ptr == 1235); } + +test "slice string literal has type []const u8" { + comptime { + assert(@typeOf("aoeu"[0...]) == []const u8); + const array = []i32{1, 2, 3, 4}; + assert(@typeOf(array[0...]) == []const i32); + } +} diff --git a/test/cases/struct_contains_slice_of_itself.zig b/test/cases/struct_contains_slice_of_itself.zig index 6443b52725..4903e565df 100644 --- a/test/cases/struct_contains_slice_of_itself.zig +++ b/test/cases/struct_contains_slice_of_itself.zig @@ -5,7 +5,17 @@ const Node = struct { children: []Node, }; -test "structContainsSliceOfItself" { +test "struct contains slice of itself" { + var other_nodes = []Node{ + Node { + .payload = 31, + .children = []Node{}, + }, + Node { + .payload = 32, + .children = []Node{}, + }, + }; var nodes = []Node { Node { .payload = 1, @@ -17,16 +27,7 @@ test "structContainsSliceOfItself" { }, Node { .payload = 3, - .children = ([]Node{ - Node { - .payload = 31, - .children = []Node{}, - }, - Node { - .payload = 32, - .children = []Node{}, - }, - })[0...], + .children = other_nodes[0...], }, }; const root = Node {