| author | |
| committer | |
| log | 101918198260482d98f6690f0ce3b1fb77a30595 |
| tree | 6399c1745a033a5805d0386df4946416aa75ddf8 |
| parent | 117ef22d3cb86858632d84699e19a90c24745d89 |
| signature |
2 files changed, 32 insertions(+), 12 deletions(-)
src/Sema.zig+30-2| ... | ... | @@ -17073,6 +17073,30 @@ fn resolvePeerTypes( |
| 17073 | 17073 | }, |
| 17074 | 17074 | else => {}, |
| 17075 | 17075 | }, |
| 17076 | .ErrorUnion => { | |
| 17077 | const payload_ty = candidate_ty.errorUnionPayload(); | |
| 17078 | if (chosen_ty_tag == .Pointer and | |
| 17079 | chosen_ty.ptrSize() == .One and | |
| 17080 | chosen_ty.childType().zigTypeTag() == .Array and | |
| 17081 | payload_ty.isSlice()) | |
| 17082 | { | |
| 17083 | const chosen_child_ty = chosen_ty.childType(); | |
| 17084 | const chosen_elem_ty = chosen_child_ty.elemType2(); | |
| 17085 | const candidate_elem_ty = payload_ty.elemType2(); | |
| 17086 | if ((try sema.coerceInMemoryAllowed(block, candidate_elem_ty, chosen_elem_ty, false, target, src, src)) == .ok) { | |
| 17087 | chosen = candidate; | |
| 17088 | chosen_i = candidate_i + 1; | |
| 17089 | ||
| 17090 | convert_to_slice = false; // it already is a slice | |
| 17091 | ||
| 17092 | // If the prev pointer is const then we need to const | |
| 17093 | if (chosen_child_ty.isConstPtr()) | |
| 17094 | make_the_slice_const = true; | |
| 17095 | ||
| 17096 | continue; | |
| 17097 | } | |
| 17098 | } | |
| 17099 | }, | |
| 17076 | 17100 | .Pointer => { |
| 17077 | 17101 | if (candidate_ty.ptrSize() == .C) { |
| 17078 | 17102 | if (chosen_ty_tag == .Int or chosen_ty_tag == .ComptimeInt) { |
| ... | ... | @@ -17086,11 +17110,15 @@ fn resolvePeerTypes( |
| 17086 | 17110 | } |
| 17087 | 17111 | |
| 17088 | 17112 | // *[N]T to []T (prev is slice) |
| 17089 | if (chosen_ty.isSlice() and | |
| 17113 | // *[N]T to E![]T | |
| 17114 | if ((chosen_ty.isSlice() or (chosen_ty_tag == .ErrorUnion and chosen_ty.errorUnionPayload().isSlice())) and | |
| 17090 | 17115 | candidate_ty.ptrSize() == .One and |
| 17091 | 17116 | candidate_ty.childType().zigTypeTag() == .Array) |
| 17092 | 17117 | { |
| 17093 | const chosen_elem_ty = chosen_ty.elemType2(); | |
| 17118 | const chosen_elem_ty = switch (chosen_ty_tag) { | |
| 17119 | .ErrorUnion => chosen_ty.errorUnionPayload().elemType2(), | |
| 17120 | else => chosen_ty.elemType2(), | |
| 17121 | }; | |
| 17094 | 17122 | const candidate_elem_ty = candidate_ty.childType().elemType2(); |
| 17095 | 17123 | if ((try sema.coerceInMemoryAllowed(block, candidate_elem_ty, chosen_elem_ty, false, target, src, src)) == .ok) { |
| 17096 | 17124 | convert_to_slice = false; // it already is a slice |
test/behavior/cast.zig+2-10| ... | ... | @@ -358,8 +358,6 @@ fn testCastIntToErr(err: anyerror) !void { |
| 358 | 358 | } |
| 359 | 359 | |
| 360 | 360 | test "peer resolve array and const slice" { |
| 361 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 362 | ||
| 363 | 361 | try testPeerResolveArrayConstSlice(true); |
| 364 | 362 | comptime try testPeerResolveArrayConstSlice(true); |
| 365 | 363 | } |
| ... | ... | @@ -492,8 +490,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 { |
| 492 | 490 | } |
| 493 | 491 | |
| 494 | 492 | test "single-item pointer of array to slice to unknown length pointer" { |
| 495 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 496 | ||
| 497 | 493 | try testCastPtrOfArrayToSliceAndPtr(); |
| 498 | 494 | comptime try testCastPtrOfArrayToSliceAndPtr(); |
| 499 | 495 | } |
| ... | ... | @@ -607,18 +603,16 @@ test "peer type resolution: unreachable, error set, unreachable" { |
| 607 | 603 | } |
| 608 | 604 | |
| 609 | 605 | test "peer cast *[0]T to E![]const T" { |
| 610 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 611 | ||
| 612 | 606 | var buffer: [5]u8 = "abcde".*; |
| 613 | 607 | var buf: anyerror![]const u8 = buffer[0..]; |
| 614 | 608 | var b = false; |
| 615 | 609 | var y = if (b) &[0]u8{} else buf; |
| 610 | var z = if (!b) buf else &[0]u8{}; | |
| 616 | 611 | try expect(mem.eql(u8, "abcde", y catch unreachable)); |
| 612 | try expect(mem.eql(u8, "abcde", z catch unreachable)); | |
| 617 | 613 | } |
| 618 | 614 | |
| 619 | 615 | test "peer cast *[0]T to []const T" { |
| 620 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 621 | ||
| 622 | 616 | var buffer: [5]u8 = "abcde".*; |
| 623 | 617 | var buf: []const u8 = buffer[0..]; |
| 624 | 618 | var b = false; |
| ... | ... | @@ -744,8 +738,6 @@ test "peer type resolution implicit cast to variable type" { |
| 744 | 738 | } |
| 745 | 739 | |
| 746 | 740 | test "variable initialization uses result locations properly with regards to the type" { |
| 747 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 748 | ||
| 749 | 741 | var b = true; |
| 750 | 742 | const x: i32 = if (b) 1 else 2; |
| 751 | 743 | try expect(x == 1); |