From 48dc3b6fe9e16e9a5dc4b586d260e19bdbd682a1 Mon Sep 17 00:00:00 2001 From: elucent <9532786+elucent@users.noreply.github.com> Date: Tue, 21 Apr 2020 02:10:50 -0400 Subject: [PATCH] Added peer type resolution for [*]T and *[N]T. --- src/ir.cpp | 31 +++++++++++++++++++++++++++++++ test/stage1/behavior/cast.zig | 19 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/ir.cpp b/src/ir.cpp index d21ce46cf..0352ab710 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11962,6 +11962,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT bool any_are_null = (prev_inst->value->type->id == ZigTypeIdNull); bool convert_to_const_slice = false; bool make_the_slice_const = false; + bool make_the_pointer_const = false; for (; i < instruction_count; i += 1) { IrInstGen *cur_inst = instructions[i]; ZigType *cur_type = cur_inst->value->type; @@ -12463,6 +12464,34 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } + // *[N]T to [*]T + if (prev_type->id == ZigTypeIdPointer && + prev_type->data.pointer.ptr_len == PtrLenSingle && + prev_type->data.pointer.child_type->id == ZigTypeIdArray && + ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown))) + { + prev_inst = cur_inst; + + if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) { + // const array pointer and non-const unknown pointer + make_the_pointer_const = true; + } + continue; + } + + // *[N]T to [*]T + if (cur_type->id == ZigTypeIdPointer && + cur_type->data.pointer.ptr_len == PtrLenSingle && + cur_type->data.pointer.child_type->id == ZigTypeIdArray && + ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown))) + { + if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) { + // const array pointer and non-const unknown pointer + make_the_pointer_const = true; + } + continue; + } + // *[N]T to []T // *[N]T to E![]T if (cur_type->id == ZigTypeIdPointer && @@ -12677,6 +12706,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } else { zig_unreachable(); } + } else if (make_the_pointer_const) { + return adjust_ptr_const(ira->codegen, prev_inst->value->type, make_the_pointer_const); } else { return prev_inst->value->type; } diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index 7b5f0e8fa..83b21c537 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -805,3 +805,22 @@ test "peer type resolve array pointers, one of them const" { comptime expect(@TypeOf(&array1, &array2) == []const u8); comptime expect(@TypeOf(&array2, &array1) == []const u8); } + +test "peer type resolve array pointer and unknown pointer" { + const const_array: [4]u8 = undefined; + var array: [4]u8 = undefined; + var const_ptr: [*]const u8 = undefined; + var ptr: [*]u8 = undefined; + + comptime expect(@TypeOf(&array, ptr) == [*]u8); + comptime expect(@TypeOf(ptr, &array) == [*]u8); + + comptime expect(@TypeOf(&const_array, ptr) == [*]const u8); + comptime expect(@TypeOf(ptr, &const_array) == [*]const u8); + + comptime expect(@TypeOf(&array, const_ptr) == [*]const u8); + comptime expect(@TypeOf(const_ptr, &array) == [*]const u8); + + comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8); + comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8); +}