From 541e763010403d8233a6420756a1e8393f1dd4c2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 20 Mar 2020 12:59:55 +0100 Subject: [PATCH] ir: Peer type resolution between ?[]T and *[N]T Closes #4767 --- lib/std/net.zig | 4 ++-- src/ir.cpp | 17 ++++++++++++++--- test/stage1/behavior/slice.zig | 8 ++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/std/net.zig b/lib/std/net.zig index b9c1281191..0a789b0dde 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -820,7 +820,7 @@ fn linuxLookupNameFromHosts( // Skip to the delimiter in the stream, to fix parsing try stream.skipUntilDelimiterOrEof('\n'); // Use the truncated line. A truncated comment or hostname will be handled correctly. - break :blk @as([]u8, &line_buf); // TODO the cast should not be necessary + break :blk &line_buf; }, else => |e| return e, }) |line| { @@ -1017,7 +1017,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void { // Skip to the delimiter in the stream, to fix parsing try stream.skipUntilDelimiterOrEof('\n'); // Give an empty line to the while loop, which will be skipped. - break :blk @as([]u8, line_buf[0..0]); // TODO the cast should not be necessary + break :blk line_buf[0..0]; }, else => |e| return e, }) |line| { diff --git a/src/ir.cpp b/src/ir.cpp index b3b3198ce1..b3e24fed1f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -12350,11 +12350,22 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT prev_type->data.pointer.child_type->id == ZigTypeIdArray && prev_type->data.pointer.ptr_len == PtrLenSingle && ((cur_type->id == ZigTypeIdErrorUnion && is_slice(cur_type->data.error_union.payload_type)) || - is_slice(cur_type))) + (cur_type->id == ZigTypeIdOptional && is_slice(cur_type->data.maybe.child_type)) || + is_slice(cur_type))) { ZigType *array_type = prev_type->data.pointer.child_type; - ZigType *slice_type = (cur_type->id == ZigTypeIdErrorUnion) ? - cur_type->data.error_union.payload_type : cur_type; + ZigType *slice_type; + switch (cur_type->id) { + case ZigTypeIdErrorUnion: + slice_type = cur_type->data.error_union.payload_type; + break; + case ZigTypeIdOptional: + slice_type = cur_type->data.maybe.child_type; + break; + default: + slice_type = cur_type; + break; + } ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || !prev_type->data.pointer.is_const) && diff --git a/test/stage1/behavior/slice.zig b/test/stage1/behavior/slice.zig index d58132cb08..f7d6037a1f 100644 --- a/test/stage1/behavior/slice.zig +++ b/test/stage1/behavior/slice.zig @@ -159,6 +159,7 @@ test "slice syntax resulting in pointer-to-array" { testSlice(); testSliceZ(); testSlice0(); + testSliceOpt(); testSliceAlign(); } @@ -249,6 +250,13 @@ test "slice syntax resulting in pointer-to-array" { comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8); } + fn testSliceOpt() void { + var array: [2]u8 = [2]u8{ 1, 2 }; + var slice: ?[]u8 = &array; + comptime expect(@TypeOf(&array, slice) == ?[]u8); + comptime expect(@TypeOf(slice.?[0..2]) == *[2]u8); + } + fn testSlice0() void { { var array = [0]u8{};