| ... | @@ -19764,6 +19764,8 @@ fn validateRunTimeType( | ... | @@ -19764,6 +19764,8 @@ fn validateRunTimeType( |
| 19764 | }; | 19764 | }; |
| 19765 | } | 19765 | } |
| 19766 | | 19766 | |
| | 19767 | const TypeSet = std.HashMapUnmanaged(Type, void, Type.HashContext64, std.hash_map.default_max_load_percentage); |
| | 19768 | |
| 19767 | fn explainWhyTypeIsComptime( | 19769 | fn explainWhyTypeIsComptime( |
| 19768 | sema: *Sema, | 19770 | sema: *Sema, |
| 19769 | block: *Block, | 19771 | block: *Block, |
| ... | @@ -19771,6 +19773,22 @@ fn explainWhyTypeIsComptime( | ... | @@ -19771,6 +19773,22 @@ fn explainWhyTypeIsComptime( |
| 19771 | msg: *Module.ErrorMsg, | 19773 | msg: *Module.ErrorMsg, |
| 19772 | src_loc: Module.SrcLoc, | 19774 | src_loc: Module.SrcLoc, |
| 19773 | ty: Type, | 19775 | ty: Type, |
| | 19776 | ) CompileError!void { |
| | 19777 | var type_set = TypeSet{}; |
| | 19778 | defer type_set.deinit(sema.gpa); |
| | 19779 | |
| | 19780 | try sema.resolveTypeFully(block, src, ty); |
| | 19781 | return sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty, &type_set); |
| | 19782 | } |
| | 19783 | |
| | 19784 | fn explainWhyTypeIsComptimeInner( |
| | 19785 | sema: *Sema, |
| | 19786 | block: *Block, |
| | 19787 | src: LazySrcLoc, |
| | 19788 | msg: *Module.ErrorMsg, |
| | 19789 | src_loc: Module.SrcLoc, |
| | 19790 | ty: Type, |
| | 19791 | type_set: *TypeSet, |
| 19774 | ) CompileError!void { | 19792 | ) CompileError!void { |
| 19775 | const mod = sema.mod; | 19793 | const mod = sema.mod; |
| 19776 | switch (ty.zigTypeTag()) { | 19794 | switch (ty.zigTypeTag()) { |
| ... | @@ -19808,7 +19826,7 @@ fn explainWhyTypeIsComptime( | ... | @@ -19808,7 +19826,7 @@ fn explainWhyTypeIsComptime( |
| 19808 | }, | 19826 | }, |
| 19809 | | 19827 | |
| 19810 | .Array, .Vector => { | 19828 | .Array, .Vector => { |
| 19811 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType()); | 19829 | try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.elemType(), type_set); |
| 19812 | }, | 19830 | }, |
| 19813 | .Pointer => { | 19831 | .Pointer => { |
| 19814 | const elem_ty = ty.elemType2(); | 19832 | const elem_ty = ty.elemType2(); |
| ... | @@ -19826,18 +19844,20 @@ fn explainWhyTypeIsComptime( | ... | @@ -19826,18 +19844,20 @@ fn explainWhyTypeIsComptime( |
| 19826 | } | 19844 | } |
| 19827 | return; | 19845 | return; |
| 19828 | } | 19846 | } |
| 19829 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType()); | 19847 | try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.elemType(), type_set); |
| 19830 | }, | 19848 | }, |
| 19831 | | 19849 | |
| 19832 | .Optional => { | 19850 | .Optional => { |
| 19833 | var buf: Type.Payload.ElemType = undefined; | 19851 | var buf: Type.Payload.ElemType = undefined; |
| 19834 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.optionalChild(&buf)); | 19852 | try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.optionalChild(&buf), type_set); |
| 19835 | }, | 19853 | }, |
| 19836 | .ErrorUnion => { | 19854 | .ErrorUnion => { |
| 19837 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.errorUnionPayload()); | 19855 | try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.errorUnionPayload(), type_set); |
| 19838 | }, | 19856 | }, |
| 19839 | | 19857 | |
| 19840 | .Struct => { | 19858 | .Struct => { |
| | 19859 | if ((try type_set.getOrPutContext(sema.gpa, ty, .{ .mod = mod })).found_existing) return; |
| | 19860 | |
| 19841 | if (ty.castTag(.@"struct")) |payload| { | 19861 | if (ty.castTag(.@"struct")) |payload| { |
| 19842 | const struct_obj = payload.data; | 19862 | const struct_obj = payload.data; |
| 19843 | for (struct_obj.fields.values()) |field, i| { | 19863 | for (struct_obj.fields.values()) |field, i| { |
| ... | @@ -19845,9 +19865,10 @@ fn explainWhyTypeIsComptime( | ... | @@ -19845,9 +19865,10 @@ fn explainWhyTypeIsComptime( |
| 19845 | .index = i, | 19865 | .index = i, |
| 19846 | .range = .type, | 19866 | .range = .type, |
| 19847 | }); | 19867 | }); |
| | 19868 | |
| 19848 | if (try sema.typeRequiresComptime(block, src, field.ty)) { | 19869 | if (try sema.typeRequiresComptime(block, src, field.ty)) { |
| 19849 | try mod.errNoteNonLazy(field_src_loc, msg, "struct requires comptime because of this field", .{}); | 19870 | try mod.errNoteNonLazy(field_src_loc, msg, "struct requires comptime because of this field", .{}); |
| 19850 | try sema.explainWhyTypeIsComptime(block, src, msg, field_src_loc, field.ty); | 19871 | try sema.explainWhyTypeIsComptimeInner(block, src, msg, field_src_loc, field.ty, type_set); |
| 19851 | } | 19872 | } |
| 19852 | } | 19873 | } |
| 19853 | } | 19874 | } |
| ... | @@ -19855,6 +19876,8 @@ fn explainWhyTypeIsComptime( | ... | @@ -19855,6 +19876,8 @@ fn explainWhyTypeIsComptime( |
| 19855 | }, | 19876 | }, |
| 19856 | | 19877 | |
| 19857 | .Union => { | 19878 | .Union => { |
| | 19879 | if ((try type_set.getOrPutContext(sema.gpa, ty, .{ .mod = mod })).found_existing) return; |
| | 19880 | |
| 19858 | if (ty.cast(Type.Payload.Union)) |payload| { | 19881 | if (ty.cast(Type.Payload.Union)) |payload| { |
| 19859 | const union_obj = payload.data; | 19882 | const union_obj = payload.data; |
| 19860 | for (union_obj.fields.values()) |field, i| { | 19883 | for (union_obj.fields.values()) |field, i| { |
| ... | @@ -19862,9 +19885,10 @@ fn explainWhyTypeIsComptime( | ... | @@ -19862,9 +19885,10 @@ fn explainWhyTypeIsComptime( |
| 19862 | .index = i, | 19885 | .index = i, |
| 19863 | .range = .type, | 19886 | .range = .type, |
| 19864 | }); | 19887 | }); |
| | 19888 | |
| 19865 | if (try sema.typeRequiresComptime(block, src, field.ty)) { | 19889 | if (try sema.typeRequiresComptime(block, src, field.ty)) { |
| 19866 | try mod.errNoteNonLazy(field_src_loc, msg, "union requires comptime because of this field", .{}); | 19890 | try mod.errNoteNonLazy(field_src_loc, msg, "union requires comptime because of this field", .{}); |
| 19867 | try sema.explainWhyTypeIsComptime(block, src, msg, field_src_loc, field.ty); | 19891 | try sema.explainWhyTypeIsComptimeInner(block, src, msg, field_src_loc, field.ty, type_set); |
| 19868 | } | 19892 | } |
| 19869 | } | 19893 | } |
| 19870 | } | 19894 | } |