Sema: handle peer type resolution of optional slices

This commit is contained in:
Andrew Kelley 2022-03-06 21:25:45 -07:00
parent 76d810c568
commit 6547da8f97
2 changed files with 32 additions and 10 deletions

View File

@ -18383,6 +18383,24 @@ fn resolvePeerTypes(
continue;
}
},
.Optional => {
var opt_child_buf: Type.Payload.ElemType = undefined;
const chosen_ptr_ty = chosen_ty.optionalChild(&opt_child_buf);
if (chosen_ptr_ty.zigTypeTag() == .Pointer) {
const chosen_info = chosen_ptr_ty.ptrInfo().data;
seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;
// *[N]T to ?![*]T
// *[N]T to ?![]T
if (cand_info.size == .One and
cand_info.pointee_type.zigTypeTag() == .Array and
(chosen_info.size == .Many or chosen_info.size == .Slice))
{
continue;
}
}
},
.ErrorUnion => {
const chosen_ptr_ty = chosen_ty.errorUnionPayload();
if (chosen_ptr_ty.zigTypeTag() == .Pointer) {
@ -18406,15 +18424,17 @@ fn resolvePeerTypes(
.Optional => {
var opt_child_buf: Type.Payload.ElemType = undefined;
const opt_child_ty = candidate_ty.optionalChild(&opt_child_buf);
if ((try sema.coerceInMemoryAllowed(block, opt_child_ty, chosen_ty, false, target, src, src)) == .ok) {
chosen = candidate;
chosen_i = candidate_i + 1;
continue;
}
if ((try sema.coerceInMemoryAllowed(block, chosen_ty, opt_child_ty, false, target, src, src)) == .ok) {
seen_const = seen_const or opt_child_ty.isConstPtr();
any_are_null = true;
continue;
}
seen_const = seen_const or chosen_ty.isConstPtr();
any_are_null = false;
chosen = candidate;
chosen_i = candidate_i + 1;
continue;
},
else => {},
}

View File

@ -333,17 +333,15 @@ test "obtaining a null terminated slice" {
}
test "empty array to slice" {
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
const S = struct {
fn doTheTest() !void {
const empty: []align(16) u8 = &[_]u8{};
const align_1: []align(1) u8 = empty;
const align_4: []align(4) u8 = empty;
const align_16: []align(16) u8 = empty;
try expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment);
try expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment);
try expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment);
try expect(1 == @typeInfo(@TypeOf(align_1)).Pointer.alignment);
try expect(4 == @typeInfo(@TypeOf(align_4)).Pointer.alignment);
try expect(16 == @typeInfo(@TypeOf(align_16)).Pointer.alignment);
}
};
@ -478,6 +476,10 @@ test "slice syntax resulting in pointer-to-array" {
var array: [2]u8 = [2]u8{ 1, 2 };
var slice: ?[]u8 = &array;
comptime try expect(@TypeOf(&array, slice) == ?[]u8);
if (builtin.zig_backend != .stage1) {
// stage1 is not passing this case
comptime try expect(@TypeOf(slice, &array) == ?[]u8);
}
comptime try expect(@TypeOf(slice.?[0..2]) == *[2]u8);
}