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(...@@ -18383,6 +18383,24 @@ fn resolvePeerTypes(
18383 continue;18383 continue;
18384 }18384 }
18385 },18385 },
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 },
18386 .ErrorUnion => {18404 .ErrorUnion => {
18387 const chosen_ptr_ty = chosen_ty.errorUnionPayload();18405 const chosen_ptr_ty = chosen_ty.errorUnionPayload();
18388 if (chosen_ptr_ty.zigTypeTag() == .Pointer) {18406 if (chosen_ptr_ty.zigTypeTag() == .Pointer) {
...@@ -18406,15 +18424,17 @@ fn resolvePeerTypes(...@@ -18406,15 +18424,17 @@ fn resolvePeerTypes(
18406 .Optional => {18424 .Optional => {
18407 var opt_child_buf: Type.Payload.ElemType = undefined;18425 var opt_child_buf: Type.Payload.ElemType = undefined;
18408 const opt_child_ty = candidate_ty.optionalChild(&opt_child_buf);18426 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 }
18414 if ((try sema.coerceInMemoryAllowed(block, chosen_ty, opt_child_ty, false, target, src, src)) == .ok) {18427 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();
18415 any_are_null = true;18429 any_are_null = true;
18416 continue;18430 continue;
18417 }18431 }
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;
18418 },18438 },
18419 else => {},18439 else => {},
18420 }18440 }
test/behavior/slice.zig+7-5
...@@ -333,17 +333,15 @@ test "obtaining a null terminated slice" {...@@ -333,17 +333,15 @@ test "obtaining a null terminated slice" {
333}333}
334334
335test "empty array to slice" {335test "empty array to slice" {
336 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
337
338 const S = struct {336 const S = struct {
339 fn doTheTest() !void {337 fn doTheTest() !void {
340 const empty: []align(16) u8 = &[_]u8{};338 const empty: []align(16) u8 = &[_]u8{};
341 const align_1: []align(1) u8 = empty;339 const align_1: []align(1) u8 = empty;
342 const align_4: []align(4) u8 = empty;340 const align_4: []align(4) u8 = empty;
343 const align_16: []align(16) u8 = empty;341 const align_16: []align(16) u8 = empty;
344 try expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment);342 try expect(1 == @typeInfo(@TypeOf(align_1)).Pointer.alignment);
345 try expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment);343 try expect(4 == @typeInfo(@TypeOf(align_4)).Pointer.alignment);
346 try expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment);344 try expect(16 == @typeInfo(@TypeOf(align_16)).Pointer.alignment);
347 }345 }
348 };346 };
349347
...@@ -478,6 +476,10 @@ test "slice syntax resulting in pointer-to-array" {...@@ -478,6 +476,10 @@ test "slice syntax resulting in pointer-to-array" {
478 var array: [2]u8 = [2]u8{ 1, 2 };476 var array: [2]u8 = [2]u8{ 1, 2 };
479 var slice: ?[]u8 = &array;477 var slice: ?[]u8 = &array;
480 comptime try expect(@TypeOf(&array, slice) == ?[]u8);478 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 }
481 comptime try expect(@TypeOf(slice.?[0..2]) == *[2]u8);483 comptime try expect(@TypeOf(slice.?[0..2]) == *[2]u8);
482 }484 }
483485