| ... | ... | @@ -5525,6 +5525,14 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 5525 | 5525 | } |
| 5526 | 5526 | } |
| 5527 | 5527 | |
| 5528 | fn typeIsDestructurable(ty: Type, zcu: *const Zcu) bool { |
| 5529 | return switch (ty.zigTypeTag(zcu)) { |
| 5530 | .array, .vector => true, |
| 5531 | .@"struct" => ty.isTuple(zcu), |
| 5532 | else => false, |
| 5533 | }; |
| 5534 | } |
| 5535 | |
| 5528 | 5536 | fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5529 | 5537 | const pt = sema.pt; |
| 5530 | 5538 | const zcu = pt.zcu; |
| ... | ... | @@ -5535,19 +5543,15 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 5535 | 5543 | const operand = try sema.resolveInst(extra.operand); |
| 5536 | 5544 | const operand_ty = sema.typeOf(operand); |
| 5537 | 5545 | |
| 5538 | | const can_destructure = switch (operand_ty.zigTypeTag(zcu)) { |
| 5539 | | .array, .vector => true, |
| 5540 | | .@"struct" => operand_ty.isTuple(zcu), |
| 5541 | | else => false, |
| 5542 | | }; |
| 5543 | | |
| 5544 | | if (!can_destructure) { |
| 5546 | if (!typeIsDestructurable(operand_ty, zcu)) { |
| 5545 | 5547 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 5546 | 5548 | const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(pt)}); |
| 5547 | 5549 | errdefer msg.destroy(sema.gpa); |
| 5548 | 5550 | try sema.errNote(destructure_src, msg, "result destructured here", .{}); |
| 5549 | 5551 | if (operand_ty.zigTypeTag(pt.zcu) == .error_union) { |
| 5550 | | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 5552 | const base_op_ty = operand_ty.errorUnionPayload(zcu); |
| 5553 | if (typeIsDestructurable(base_op_ty, zcu)) |
| 5554 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 5551 | 5555 | } |
| 5552 | 5556 | break :msg msg; |
| 5553 | 5557 | }); |