aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-03-28 13:47:03 +0300
committerAndrew Kelley <andrew@ziglang.org>2022-03-28 13:05:40 -0700
commitc517e65d8f5d7c06aea56dfce5527843d7711a99 (patch)
tree147a2ee5b919910c55a646cac511e8dab23554fe /src
parent5515b81f8c4f1b7eae98ee7bb41e4b4579de45dc (diff)
downloadzig-c517e65d8f5d7c06aea56dfce5527843d7711a99.tar.gz
zig-c517e65d8f5d7c06aea56dfce5527843d7711a99.zip
Sema: implement coerceInMemoryAllowed for optionals
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 5523d44aee..375b588c40 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -18222,8 +18222,10 @@ fn coerceInMemoryAllowed(
// Pointers / Pointer-like Optionals
var dest_buf: Type.Payload.ElemType = undefined;
var src_buf: Type.Payload.ElemType = undefined;
- if (try sema.typePtrOrOptionalPtrTy(block, dest_ty, &dest_buf, dest_src)) |dest_ptr_ty| {
- if (try sema.typePtrOrOptionalPtrTy(block, src_ty, &src_buf, src_src)) |src_ptr_ty| {
+ const maybe_dest_ptr_ty = try sema.typePtrOrOptionalPtrTy(block, dest_ty, &dest_buf, dest_src);
+ const maybe_src_ptr_ty = try sema.typePtrOrOptionalPtrTy(block, src_ty, &src_buf, src_src);
+ if (maybe_dest_ptr_ty) |dest_ptr_ty| {
+ if (maybe_src_ptr_ty) |src_ptr_ty| {
return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ptr_ty, src_ptr_ty, dest_is_mut, target, dest_src, src_src);
}
}
@@ -18288,7 +18290,23 @@ fn coerceInMemoryAllowed(
return .ok;
}
- // TODO: non-pointer-like optionals
+ // Optionals
+ if (dest_tag == .Optional and src_tag == .Optional) optionals: {
+ if ((maybe_dest_ptr_ty != null) != (maybe_src_ptr_ty != null)) {
+ // TODO "optional type child '{}' cannot cast into optional type '{}'"
+ return .no_match;
+ }
+ const dest_child_type = dest_ty.optionalChild(&dest_buf);
+ const src_child_type = src_ty.optionalChild(&src_buf);
+
+ const child = try sema.coerceInMemoryAllowed(block, dest_child_type, src_child_type, dest_is_mut, target, dest_src, src_src);
+ if (child == .no_match) {
+ // TODO "optional type child '{}' cannot cast into optional type child '{}'"
+ break :optionals;
+ }
+
+ return .ok;
+ }
return .no_match;
}