authorgravatar for william@sengir.comWilliam Sengir <william@sengir.com> 2022-05-11 03:36:58-07:00
committergravatar for william@sengir.comWilliam Sengir <william@sengir.com> 2022-05-11 03:47:03-07:00
log363cdb7d5fc376dfb6fc0f67d983922fc4208aa1
treecb404d97b91469fabb0b975ee8b423cadacc0572
parentbd32a0f3db2d03749e7aef22cbc2aa6f85b689d1
signaturelock-open Commit is signed but in an unrecognized format.

Sema: add error for disjoint error sets in `zirErrSetCast`


1 files changed, 39 insertions(+), 2 deletions(-)

src/Sema.zig+39-2
...@@ -14209,9 +14209,46 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -14209,9 +14209,46 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
14209 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);14209 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
14210 try sema.checkErrorSetType(block, operand_src, operand_ty);14210 try sema.checkErrorSetType(block, operand_src, operand_ty);
1421114211
14212 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {14212 // operand must be defined since it can be an invalid error value
14213 try sema.resolveInferredErrorSetTy(block, src, dest_ty);14213 const maybe_operand_val = try sema.resolveDefinedValue(block, operand_src, operand);
14214
14215 if (disjoint: {
14216 // Try avoiding resolving inferred error sets if we can
14217 if (!dest_ty.isAnyError() and dest_ty.errorSetNames().len == 0) break :disjoint true;
14218 if (!operand_ty.isAnyError() and operand_ty.errorSetNames().len == 0) break :disjoint true;
14219 if (dest_ty.isAnyError()) break :disjoint false;
14220 if (operand_ty.isAnyError()) break :disjoint false;
14221 for (dest_ty.errorSetNames()) |dest_err_name|
14222 if (operand_ty.errorSetHasField(dest_err_name))
14223 break :disjoint false;
14224
14225 if (dest_ty.tag() != .error_set_inferred and operand_ty.tag() != .error_set_inferred)
14226 break :disjoint true;
14227
14228 try sema.resolveInferredErrorSetTy(block, dest_ty_src, dest_ty);
14229 try sema.resolveInferredErrorSetTy(block, operand_src, operand_ty);
14230 for (dest_ty.errorSetNames()) |dest_err_name|
14231 if (operand_ty.errorSetHasField(dest_err_name))
14232 break :disjoint false;
14233
14234 break :disjoint true;
14235 }) {
14236 const msg = msg: {
14237 const msg = try sema.errMsg(
14238 block,
14239 src,
14240 "error sets '{}' and '{}' have no common errors",
14241 .{ operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod) },
14242 );
14243 errdefer msg.destroy(sema.gpa);
14244 try sema.addDeclaredHereNote(msg, operand_ty);
14245 try sema.addDeclaredHereNote(msg, dest_ty);
14246 break :msg msg;
14247 };
14248 return sema.failWithOwnedErrorMsg(block, msg);
14249 }
1421414250
14251 if (maybe_operand_val) |val| {
14215 if (!dest_ty.isAnyError()) {14252 if (!dest_ty.isAnyError()) {
14216 const error_name = val.castTag(.@"error").?.data.name;14253 const error_name = val.castTag(.@"error").?.data.name;
14217 if (!dest_ty.errorSetHasField(error_name)) {14254 if (!dest_ty.errorSetHasField(error_name)) {