| ... | @@ -26629,21 +26629,41 @@ fn resolveStructLayout( | ... | @@ -26629,21 +26629,41 @@ fn resolveStructLayout( |
| 26629 | switch (struct_obj.status) { | 26629 | switch (struct_obj.status) { |
| 26630 | .none, .have_field_types => {}, | 26630 | .none, .have_field_types => {}, |
| 26631 | .field_types_wip, .layout_wip => { | 26631 | .field_types_wip, .layout_wip => { |
| 26632 | return sema.fail(block, src, "struct '{}' depends on itself", .{ty.fmt(sema.mod)}); | 26632 | const msg = try Module.ErrorMsg.create( |
| | 26633 | sema.gpa, |
| | 26634 | struct_obj.srcLoc(sema.mod), |
| | 26635 | "struct '{}' depends on itself", |
| | 26636 | .{ty.fmt(sema.mod)}, |
| | 26637 | ); |
| | 26638 | return sema.failWithOwnedErrorMsg(msg); |
| 26633 | }, | 26639 | }, |
| 26634 | .have_layout, .fully_resolved_wip, .fully_resolved => return, | 26640 | .have_layout, .fully_resolved_wip, .fully_resolved => return, |
| 26635 | } | 26641 | } |
| 26636 | struct_obj.status = .layout_wip; | 26642 | struct_obj.status = .layout_wip; |
| 26637 | for (struct_obj.fields.values()) |field| { | 26643 | for (struct_obj.fields.values()) |field, i| { |
| 26638 | try sema.resolveTypeLayout(block, src, field.ty); | 26644 | sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) { |
| | 26645 | error.AnalysisFail => { |
| | 26646 | const msg = sema.err orelse return err; |
| | 26647 | try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); |
| | 26648 | return err; |
| | 26649 | }, |
| | 26650 | else => return err, |
| | 26651 | }; |
| 26639 | } | 26652 | } |
| 26640 | struct_obj.status = .have_layout; | 26653 | struct_obj.status = .have_layout; |
| 26641 | | 26654 | |
| 26642 | // In case of querying the ABI alignment of this struct, we will ask | 26655 | // In case of querying the ABI alignment of this struct, we will ask |
| 26643 | // for hasRuntimeBits() of each field, so we need "requires comptime" | 26656 | // for hasRuntimeBits() of each field, so we need "requires comptime" |
| 26644 | // to be known already before this function returns. | 26657 | // to be known already before this function returns. |
| 26645 | for (struct_obj.fields.values()) |field| { | 26658 | for (struct_obj.fields.values()) |field, i| { |
| 26646 | _ = try sema.typeRequiresComptime(block, src, field.ty); | 26659 | _ = sema.typeRequiresComptime(block, src, field.ty) catch |err| switch (err) { |
| | 26660 | error.AnalysisFail => { |
| | 26661 | const msg = sema.err orelse return err; |
| | 26662 | try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); |
| | 26663 | return err; |
| | 26664 | }, |
| | 26665 | else => return err, |
| | 26666 | }; |
| 26647 | } | 26667 | } |
| 26648 | } | 26668 | } |
| 26649 | // otherwise it's a tuple; no need to resolve anything | 26669 | // otherwise it's a tuple; no need to resolve anything |
| ... | @@ -26660,13 +26680,26 @@ fn resolveUnionLayout( | ... | @@ -26660,13 +26680,26 @@ fn resolveUnionLayout( |
| 26660 | switch (union_obj.status) { | 26680 | switch (union_obj.status) { |
| 26661 | .none, .have_field_types => {}, | 26681 | .none, .have_field_types => {}, |
| 26662 | .field_types_wip, .layout_wip => { | 26682 | .field_types_wip, .layout_wip => { |
| 26663 | return sema.fail(block, src, "union '{}' depends on itself", .{ty.fmt(sema.mod)}); | 26683 | const msg = try Module.ErrorMsg.create( |
| | 26684 | sema.gpa, |
| | 26685 | union_obj.srcLoc(sema.mod), |
| | 26686 | "union '{}' depends on itself", |
| | 26687 | .{ty.fmt(sema.mod)}, |
| | 26688 | ); |
| | 26689 | return sema.failWithOwnedErrorMsg(msg); |
| 26664 | }, | 26690 | }, |
| 26665 | .have_layout, .fully_resolved_wip, .fully_resolved => return, | 26691 | .have_layout, .fully_resolved_wip, .fully_resolved => return, |
| 26666 | } | 26692 | } |
| 26667 | union_obj.status = .layout_wip; | 26693 | union_obj.status = .layout_wip; |
| 26668 | for (union_obj.fields.values()) |field| { | 26694 | for (union_obj.fields.values()) |field, i| { |
| 26669 | try sema.resolveTypeLayout(block, src, field.ty); | 26695 | sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) { |
| | 26696 | error.AnalysisFail => { |
| | 26697 | const msg = sema.err orelse return err; |
| | 26698 | try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); |
| | 26699 | return err; |
| | 26700 | }, |
| | 26701 | else => return err, |
| | 26702 | }; |
| 26670 | } | 26703 | } |
| 26671 | union_obj.status = .have_layout; | 26704 | union_obj.status = .have_layout; |
| 26672 | } | 26705 | } |
| ... | @@ -26794,12 +26827,12 @@ pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) | ... | @@ -26794,12 +26827,12 @@ pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 26794 | switch (ty.tag()) { | 26827 | switch (ty.tag()) { |
| 26795 | .@"struct" => { | 26828 | .@"struct" => { |
| 26796 | const struct_obj = ty.castTag(.@"struct").?.data; | 26829 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 26797 | try sema.resolveTypeFieldsStruct(block, src, ty, struct_obj); | 26830 | try sema.resolveTypeFieldsStruct(ty, struct_obj); |
| 26798 | return ty; | 26831 | return ty; |
| 26799 | }, | 26832 | }, |
| 26800 | .@"union", .union_safety_tagged, .union_tagged => { | 26833 | .@"union", .union_safety_tagged, .union_tagged => { |
| 26801 | const union_obj = ty.cast(Type.Payload.Union).?.data; | 26834 | const union_obj = ty.cast(Type.Payload.Union).?.data; |
| 26802 | try sema.resolveTypeFieldsUnion(block, src, ty, union_obj); | 26835 | try sema.resolveTypeFieldsUnion(ty, union_obj); |
| 26803 | return ty; | 26836 | return ty; |
| 26804 | }, | 26837 | }, |
| 26805 | .type_info => return sema.resolveBuiltinTypeFields(block, src, "Type"), | 26838 | .type_info => return sema.resolveBuiltinTypeFields(block, src, "Type"), |
| ... | @@ -26820,15 +26853,19 @@ pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) | ... | @@ -26820,15 +26853,19 @@ pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 26820 | | 26853 | |
| 26821 | fn resolveTypeFieldsStruct( | 26854 | fn resolveTypeFieldsStruct( |
| 26822 | sema: *Sema, | 26855 | sema: *Sema, |
| 26823 | block: *Block, | | |
| 26824 | src: LazySrcLoc, | | |
| 26825 | ty: Type, | 26856 | ty: Type, |
| 26826 | struct_obj: *Module.Struct, | 26857 | struct_obj: *Module.Struct, |
| 26827 | ) CompileError!void { | 26858 | ) CompileError!void { |
| 26828 | switch (struct_obj.status) { | 26859 | switch (struct_obj.status) { |
| 26829 | .none => {}, | 26860 | .none => {}, |
| 26830 | .field_types_wip => { | 26861 | .field_types_wip => { |
| 26831 | return sema.fail(block, src, "struct '{}' depends on itself", .{ty.fmt(sema.mod)}); | 26862 | const msg = try Module.ErrorMsg.create( |
| | 26863 | sema.gpa, |
| | 26864 | struct_obj.srcLoc(sema.mod), |
| | 26865 | "struct '{}' depends on itself", |
| | 26866 | .{ty.fmt(sema.mod)}, |
| | 26867 | ); |
| | 26868 | return sema.failWithOwnedErrorMsg(msg); |
| 26832 | }, | 26869 | }, |
| 26833 | .have_field_types, | 26870 | .have_field_types, |
| 26834 | .have_layout, | 26871 | .have_layout, |
| ... | @@ -26842,17 +26879,17 @@ fn resolveTypeFieldsStruct( | ... | @@ -26842,17 +26879,17 @@ fn resolveTypeFieldsStruct( |
| 26842 | try semaStructFields(sema.mod, struct_obj); | 26879 | try semaStructFields(sema.mod, struct_obj); |
| 26843 | } | 26880 | } |
| 26844 | | 26881 | |
| 26845 | fn resolveTypeFieldsUnion( | 26882 | fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_obj: *Module.Union) CompileError!void { |
| 26846 | sema: *Sema, | | |
| 26847 | block: *Block, | | |
| 26848 | src: LazySrcLoc, | | |
| 26849 | ty: Type, | | |
| 26850 | union_obj: *Module.Union, | | |
| 26851 | ) CompileError!void { | | |
| 26852 | switch (union_obj.status) { | 26883 | switch (union_obj.status) { |
| 26853 | .none => {}, | 26884 | .none => {}, |
| 26854 | .field_types_wip => { | 26885 | .field_types_wip => { |
| 26855 | return sema.fail(block, src, "union '{}' depends on itself", .{ty.fmt(sema.mod)}); | 26886 | const msg = try Module.ErrorMsg.create( |
| | 26887 | sema.gpa, |
| | 26888 | union_obj.srcLoc(sema.mod), |
| | 26889 | "union '{}' depends on itself", |
| | 26890 | .{ty.fmt(sema.mod)}, |
| | 26891 | ); |
| | 26892 | return sema.failWithOwnedErrorMsg(msg); |
| 26856 | }, | 26893 | }, |
| 26857 | .have_field_types, | 26894 | .have_field_types, |
| 26858 | .have_layout, | 26895 | .have_layout, |
| ... | @@ -27786,9 +27823,19 @@ pub fn typeHasOnePossibleValue( | ... | @@ -27786,9 +27823,19 @@ pub fn typeHasOnePossibleValue( |
| 27786 | .@"struct" => { | 27823 | .@"struct" => { |
| 27787 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); | 27824 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); |
| 27788 | const s = resolved_ty.castTag(.@"struct").?.data; | 27825 | const s = resolved_ty.castTag(.@"struct").?.data; |
| 27789 | for (s.fields.values()) |value| { | 27826 | for (s.fields.values()) |field, i| { |
| 27790 | if (value.is_comptime) continue; | 27827 | if (field.is_comptime) continue; |
| 27791 | if ((try sema.typeHasOnePossibleValue(block, src, value.ty)) == null) { | 27828 | if (field.ty.eql(resolved_ty, sema.mod)) { |
| | 27829 | const msg = try Module.ErrorMsg.create( |
| | 27830 | sema.gpa, |
| | 27831 | s.srcLoc(sema.mod), |
| | 27832 | "struct '{}' depends on itself", |
| | 27833 | .{ty.fmt(sema.mod)}, |
| | 27834 | ); |
| | 27835 | try sema.addFieldErrNote(block, resolved_ty, i, msg, "while checking this field", .{}); |
| | 27836 | return sema.failWithOwnedErrorMsg(msg); |
| | 27837 | } |
| | 27838 | if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) { |
| 27792 | return null; | 27839 | return null; |
| 27793 | } | 27840 | } |
| 27794 | } | 27841 | } |
| ... | @@ -27854,6 +27901,16 @@ pub fn typeHasOnePossibleValue( | ... | @@ -27854,6 +27901,16 @@ pub fn typeHasOnePossibleValue( |
| 27854 | const tag_val = (try sema.typeHasOnePossibleValue(block, src, union_obj.tag_ty)) orelse | 27901 | const tag_val = (try sema.typeHasOnePossibleValue(block, src, union_obj.tag_ty)) orelse |
| 27855 | return null; | 27902 | return null; |
| 27856 | const only_field = union_obj.fields.values()[0]; | 27903 | const only_field = union_obj.fields.values()[0]; |
| | 27904 | if (only_field.ty.eql(resolved_ty, sema.mod)) { |
| | 27905 | const msg = try Module.ErrorMsg.create( |
| | 27906 | sema.gpa, |
| | 27907 | union_obj.srcLoc(sema.mod), |
| | 27908 | "union '{}' depends on itself", |
| | 27909 | .{ty.fmt(sema.mod)}, |
| | 27910 | ); |
| | 27911 | try sema.addFieldErrNote(block, resolved_ty, 0, msg, "while checking this field", .{}); |
| | 27912 | return sema.failWithOwnedErrorMsg(msg); |
| | 27913 | } |
| 27857 | const val_val = (try sema.typeHasOnePossibleValue(block, src, only_field.ty)) orelse | 27914 | const val_val = (try sema.typeHasOnePossibleValue(block, src, only_field.ty)) orelse |
| 27858 | return null; | 27915 | return null; |
| 27859 | // TODO make this not allocate. The function in `Type.onePossibleValue` | 27916 | // TODO make this not allocate. The function in `Type.onePossibleValue` |
| ... | @@ -28493,7 +28550,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ | ... | @@ -28493,7 +28550,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 28493 | if (struct_obj.status == .field_types_wip) | 28550 | if (struct_obj.status == .field_types_wip) |
| 28494 | return false; | 28551 | return false; |
| 28495 | | 28552 | |
| 28496 | try sema.resolveTypeFieldsStruct(block, src, ty, struct_obj); | 28553 | try sema.resolveTypeFieldsStruct(ty, struct_obj); |
| 28497 | | 28554 | |
| 28498 | struct_obj.requires_comptime = .wip; | 28555 | struct_obj.requires_comptime = .wip; |
| 28499 | for (struct_obj.fields.values()) |field| { | 28556 | for (struct_obj.fields.values()) |field| { |
| ... | @@ -28518,7 +28575,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ | ... | @@ -28518,7 +28575,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 28518 | if (union_obj.status == .field_types_wip) | 28575 | if (union_obj.status == .field_types_wip) |
| 28519 | return false; | 28576 | return false; |
| 28520 | | 28577 | |
| 28521 | try sema.resolveTypeFieldsUnion(block, src, ty, union_obj); | 28578 | try sema.resolveTypeFieldsUnion(ty, union_obj); |
| 28522 | | 28579 | |
| 28523 | union_obj.requires_comptime = .wip; | 28580 | union_obj.requires_comptime = .wip; |
| 28524 | for (union_obj.fields.values()) |field| { | 28581 | for (union_obj.fields.values()) |field| { |