| ... | @@ -5525,6 +5525,14 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -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 | fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 5536 | fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5529 | const pt = sema.pt; | 5537 | const pt = sema.pt; |
| 5530 | const zcu = pt.zcu; | 5538 | const zcu = pt.zcu; |
| ... | @@ -5535,19 +5543,15 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -5535,19 +5543,15 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 5535 | const operand = try sema.resolveInst(extra.operand); | 5543 | const operand = try sema.resolveInst(extra.operand); |
| 5536 | const operand_ty = sema.typeOf(operand); | 5544 | const operand_ty = sema.typeOf(operand); |
| 5537 | | 5545 | |
| 5538 | const can_destructure = switch (operand_ty.zigTypeTag(zcu)) { | 5546 | if (!typeIsDestructurable(operand_ty, zcu)) { |
| 5539 | .array, .vector => true, | | |
| 5540 | .@"struct" => operand_ty.isTuple(zcu), | | |
| 5541 | else => false, | | |
| 5542 | }; | | |
| 5543 | | | |
| 5544 | if (!can_destructure) { | | |
| 5545 | return sema.failWithOwnedErrorMsg(block, msg: { | 5547 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 5546 | const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(pt)}); | 5548 | const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(pt)}); |
| 5547 | errdefer msg.destroy(sema.gpa); | 5549 | errdefer msg.destroy(sema.gpa); |
| 5548 | try sema.errNote(destructure_src, msg, "result destructured here", .{}); | 5550 | try sema.errNote(destructure_src, msg, "result destructured here", .{}); |
| 5549 | if (operand_ty.zigTypeTag(pt.zcu) == .error_union) { | 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 | break :msg msg; | 5556 | break :msg msg; |
| 5553 | }); | 5557 | }); |