Commit 541e763010

LemonBoy <thatlemon@gmail.com>
2020-03-20 12:59:55
ir: Peer type resolution between ?[]T and *[N]T
Closes #4767
1 parent 28a6c13
Changed files (3)
lib
src
test
stage1
behavior
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| {
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) &&
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{};