authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-06 21:25:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-06 21:29:07-07:00
log6547da8f97b94453fb08f582c2c7ce4eb1782a80
tree6e15b39d0736dae623112250a4ac2ef9aea18b85
parent76d810c568648e32af0d74af2037b73b7ea38270

Sema: handle peer type resolution of optional slices


2 files changed, 32 insertions(+), 10 deletions(-)

src/Sema.zig+25-5
......@@ -18383,6 +18383,24 @@ fn resolvePeerTypes(
1838318383 continue;
1838418384 }
1838518385 },
18386 .Optional => {
18387 var opt_child_buf: Type.Payload.ElemType = undefined;
18388 const chosen_ptr_ty = chosen_ty.optionalChild(&opt_child_buf);
18389 if (chosen_ptr_ty.zigTypeTag() == .Pointer) {
18390 const chosen_info = chosen_ptr_ty.ptrInfo().data;
18391
18392 seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;
18393
18394 // *[N]T to ?![*]T
18395 // *[N]T to ?![]T
18396 if (cand_info.size == .One and
18397 cand_info.pointee_type.zigTypeTag() == .Array and
18398 (chosen_info.size == .Many or chosen_info.size == .Slice))
18399 {
18400 continue;
18401 }
18402 }
18403 },
1838618404 .ErrorUnion => {
1838718405 const chosen_ptr_ty = chosen_ty.errorUnionPayload();
1838818406 if (chosen_ptr_ty.zigTypeTag() == .Pointer) {
......@@ -18406,15 +18424,17 @@ fn resolvePeerTypes(
1840618424 .Optional => {
1840718425 var opt_child_buf: Type.Payload.ElemType = undefined;
1840818426 const opt_child_ty = candidate_ty.optionalChild(&opt_child_buf);
18409 if ((try sema.coerceInMemoryAllowed(block, opt_child_ty, chosen_ty, false, target, src, src)) == .ok) {
18410 chosen = candidate;
18411 chosen_i = candidate_i + 1;
18412 continue;
18413 }
1841418427 if ((try sema.coerceInMemoryAllowed(block, chosen_ty, opt_child_ty, false, target, src, src)) == .ok) {
18428 seen_const = seen_const or opt_child_ty.isConstPtr();
1841518429 any_are_null = true;
1841618430 continue;
1841718431 }
18432
18433 seen_const = seen_const or chosen_ty.isConstPtr();
18434 any_are_null = false;
18435 chosen = candidate;
18436 chosen_i = candidate_i + 1;
18437 continue;
1841818438 },
1841918439 else => {},
1842018440 }
test/behavior/slice.zig+7-5
......@@ -333,17 +333,15 @@ test "obtaining a null terminated slice" {
333333}
334334
335335test "empty array to slice" {
336 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
337
338336 const S = struct {
339337 fn doTheTest() !void {
340338 const empty: []align(16) u8 = &[_]u8{};
341339 const align_1: []align(1) u8 = empty;
342340 const align_4: []align(4) u8 = empty;
343341 const align_16: []align(16) u8 = empty;
344 try expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment);
345 try expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment);
346 try expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment);
342 try expect(1 == @typeInfo(@TypeOf(align_1)).Pointer.alignment);
343 try expect(4 == @typeInfo(@TypeOf(align_4)).Pointer.alignment);
344 try expect(16 == @typeInfo(@TypeOf(align_16)).Pointer.alignment);
347345 }
348346 };
349347
......@@ -478,6 +476,10 @@ test "slice syntax resulting in pointer-to-array" {
478476 var array: [2]u8 = [2]u8{ 1, 2 };
479477 var slice: ?[]u8 = &array;
480478 comptime try expect(@TypeOf(&array, slice) == ?[]u8);
479 if (builtin.zig_backend != .stage1) {
480 // stage1 is not passing this case
481 comptime try expect(@TypeOf(slice, &array) == ?[]u8);
482 }
481483 comptime try expect(@TypeOf(slice.?[0..2]) == *[2]u8);
482484 }
483485