authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-28 13:47:03+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-28 13:05:40-07:00
logc517e65d8f5d7c06aea56dfce5527843d7711a99
tree147a2ee5b919910c55a646cac511e8dab23554fe
parent5515b81f8c4f1b7eae98ee7bb41e4b4579de45dc

Sema: implement coerceInMemoryAllowed for optionals


2 files changed, 30 insertions(+), 3 deletions(-)

src/Sema.zig+21-3
......@@ -18222,8 +18222,10 @@ fn coerceInMemoryAllowed(
1822218222 // Pointers / Pointer-like Optionals
1822318223 var dest_buf: Type.Payload.ElemType = undefined;
1822418224 var src_buf: Type.Payload.ElemType = undefined;
18225 if (try sema.typePtrOrOptionalPtrTy(block, dest_ty, &dest_buf, dest_src)) |dest_ptr_ty| {
18226 if (try sema.typePtrOrOptionalPtrTy(block, src_ty, &src_buf, src_src)) |src_ptr_ty| {
18225 const maybe_dest_ptr_ty = try sema.typePtrOrOptionalPtrTy(block, dest_ty, &dest_buf, dest_src);
18226 const maybe_src_ptr_ty = try sema.typePtrOrOptionalPtrTy(block, src_ty, &src_buf, src_src);
18227 if (maybe_dest_ptr_ty) |dest_ptr_ty| {
18228 if (maybe_src_ptr_ty) |src_ptr_ty| {
1822718229 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ptr_ty, src_ptr_ty, dest_is_mut, target, dest_src, src_src);
1822818230 }
1822918231 }
......@@ -18288,7 +18290,23 @@ fn coerceInMemoryAllowed(
1828818290 return .ok;
1828918291 }
1829018292
18291 // TODO: non-pointer-like optionals
18293 // Optionals
18294 if (dest_tag == .Optional and src_tag == .Optional) optionals: {
18295 if ((maybe_dest_ptr_ty != null) != (maybe_src_ptr_ty != null)) {
18296 // TODO "optional type child '{}' cannot cast into optional type '{}'"
18297 return .no_match;
18298 }
18299 const dest_child_type = dest_ty.optionalChild(&dest_buf);
18300 const src_child_type = src_ty.optionalChild(&src_buf);
18301
18302 const child = try sema.coerceInMemoryAllowed(block, dest_child_type, src_child_type, dest_is_mut, target, dest_src, src_src);
18303 if (child == .no_match) {
18304 // TODO "optional type child '{}' cannot cast into optional type child '{}'"
18305 break :optionals;
18306 }
18307
18308 return .ok;
18309 }
1829218310
1829318311 return .no_match;
1829418312}
test/behavior/cast.zig+9
......@@ -1363,3 +1363,12 @@ test "cast i8 fn call peers to i32 result" {
13631363 try S.doTheTest();
13641364 comptime try S.doTheTest();
13651365}
1366
1367test "cast compatible optional types" {
1368 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1369 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1370
1371 var a: ?[:0]const u8 = null;
1372 var b: ?[]const u8 = a;
1373 try expect(b == null);
1374}