aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-02-27 19:00:16 -0800
committerAndrew Kelley <andrew@ziglang.org>2022-02-28 20:42:13 -0700
commitb4ce8557884bd8f2b3fa621c3564f9d0ff789699 (patch)
treecca72056f4eb39aabb787a0e3744ec7c6db7f167 /src/Sema.zig
parent38aae2cb7cc1dfa906336392a422153b9a345401 (diff)
downloadzig-b4ce8557884bd8f2b3fa621c3564f9d0ff789699.tar.gz
zig-b4ce8557884bd8f2b3fa621c3564f9d0ff789699.zip
stage2: error union and non-error set/union peer cast resolution
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig73
1 files changed, 53 insertions, 20 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 269f726f57..e5cad45e90 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -17814,8 +17814,8 @@ fn resolvePeerTypes(
err_set_ty = try err_set_ty.?.errorSetMerge(sema.arena, candidate_ty);
continue;
},
- .ErrorUnion => {
- if (chosen_ty_tag == .ErrorSet) {
+ .ErrorUnion => switch (chosen_ty_tag) {
+ .ErrorSet => {
if (err_set_ty.?.isAnyError()) {
chosen = candidate;
chosen_i = candidate_i + 1;
@@ -17854,9 +17854,9 @@ fn resolvePeerTypes(
chosen = candidate;
chosen_i = candidate_i + 1;
continue;
- }
+ },
- if (chosen_ty_tag == .ErrorUnion) {
+ .ErrorUnion => {
const chosen_payload_ty = chosen_ty.errorUnionPayload();
const candidate_payload_ty = candidate_ty.errorUnionPayload();
@@ -17926,30 +17926,57 @@ fn resolvePeerTypes(
err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty);
continue;
}
- }
+ },
- const payload_ty = candidate_ty.errorUnionPayload();
- if (chosen_ty_tag == .Pointer and
- chosen_ty.ptrSize() == .One and
- chosen_ty.childType().zigTypeTag() == .Array and
- payload_ty.isSlice())
- {
- const chosen_child_ty = chosen_ty.childType();
- const chosen_elem_ty = chosen_child_ty.elemType2();
- const candidate_elem_ty = payload_ty.elemType2();
- if ((try sema.coerceInMemoryAllowed(block, candidate_elem_ty, chosen_elem_ty, false, target, src, src)) == .ok) {
+ .Pointer => {
+ const payload_ty = candidate_ty.errorUnionPayload();
+ if (chosen_ty.ptrSize() == .One and
+ chosen_ty.childType().zigTypeTag() == .Array and
+ payload_ty.isSlice())
+ {
+ const chosen_child_ty = chosen_ty.childType();
+ const chosen_elem_ty = chosen_child_ty.elemType2();
+ const candidate_elem_ty = payload_ty.elemType2();
+ if ((try sema.coerceInMemoryAllowed(block, candidate_elem_ty, chosen_elem_ty, false, target, src, src)) == .ok) {
+ chosen = candidate;
+ chosen_i = candidate_i + 1;
+
+ convert_to_slice = false; // it already is a slice
+
+ // If the prev pointer is const then we need to const
+ if (chosen_child_ty.isConstPtr())
+ make_the_slice_const = true;
+
+ continue;
+ }
+ }
+ },
+
+ else => {
+ // Chosen coercing into payload type
+ // Then merge error sets (if any)
+ const payload_ty = candidate_ty.errorUnionPayload();
+ if ((try sema.coerceInMemoryAllowed(block, payload_ty, chosen_ty, false, target, src, src)) == .ok) {
chosen = candidate;
chosen_i = candidate_i + 1;
- convert_to_slice = false; // it already is a slice
+ if (err_set_ty) |ty| {
+ const cand_set_ty = candidate_ty.errorUnionSet();
+ if (cand_set_ty.castTag(.error_set_inferred)) |inferred| {
+ try sema.resolveInferredErrorSet(inferred.data);
+ }
+ if (cand_set_ty.isAnyError()) {
+ err_set_ty = cand_set_ty;
+ continue;
+ }
+ if (ty.isAnyError()) continue;
- // If the prev pointer is const then we need to const
- if (chosen_child_ty.isConstPtr())
- make_the_slice_const = true;
+ err_set_ty = try err_set_ty.?.errorSetMerge(sema.arena, cand_set_ty);
+ }
continue;
}
- }
+ },
},
.Pointer => {
if (candidate_ty.ptrSize() == .C) {
@@ -18115,6 +18142,12 @@ fn resolvePeerTypes(
continue;
}
},
+ .ErrorUnion => {
+ const payload_ty = chosen_ty.errorUnionPayload();
+ if ((try sema.coerceInMemoryAllowed(block, payload_ty, candidate_ty, false, target, src, src)) == .ok) {
+ continue;
+ }
+ },
else => {},
}