diff options
| author | zooster <r00ster91@proton.me> | 2022-08-06 19:32:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-06 19:32:42 +0200 |
| commit | 3debd6b732556832e58491cb153e1fee2cc8876b (patch) | |
| tree | 6ae912f0b6163d0efa7f081bb66fe9556d41ddd8 /src | |
| parent | 943f4eb515ec03499cf7b37d80b964e15502bfc8 (diff) | |
| parent | 94662591d617226caabcb6c7319d703f1e41a880 (diff) | |
| download | zig-3debd6b732556832e58491cb153e1fee2cc8876b.tar.gz zig-3debd6b732556832e58491cb153e1fee2cc8876b.zip | |
Merge branch 'master' into nicedocs
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 76c077c103..8c2125026d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -19764,6 +19764,8 @@ fn validateRunTimeType( }; } +const TypeSet = std.HashMapUnmanaged(Type, void, Type.HashContext64, std.hash_map.default_max_load_percentage); + fn explainWhyTypeIsComptime( sema: *Sema, block: *Block, @@ -19772,6 +19774,22 @@ fn explainWhyTypeIsComptime( src_loc: Module.SrcLoc, ty: Type, ) CompileError!void { + var type_set = TypeSet{}; + defer type_set.deinit(sema.gpa); + + try sema.resolveTypeFully(block, src, ty); + return sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty, &type_set); +} + +fn explainWhyTypeIsComptimeInner( + sema: *Sema, + block: *Block, + src: LazySrcLoc, + msg: *Module.ErrorMsg, + src_loc: Module.SrcLoc, + ty: Type, + type_set: *TypeSet, +) CompileError!void { const mod = sema.mod; switch (ty.zigTypeTag()) { .Bool, @@ -19808,7 +19826,7 @@ fn explainWhyTypeIsComptime( }, .Array, .Vector => { - try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType()); + try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.elemType(), type_set); }, .Pointer => { const elem_ty = ty.elemType2(); @@ -19826,18 +19844,20 @@ fn explainWhyTypeIsComptime( } return; } - try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType()); + try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.elemType(), type_set); }, .Optional => { var buf: Type.Payload.ElemType = undefined; - try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.optionalChild(&buf)); + try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.optionalChild(&buf), type_set); }, .ErrorUnion => { - try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.errorUnionPayload()); + try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.errorUnionPayload(), type_set); }, .Struct => { + if ((try type_set.getOrPutContext(sema.gpa, ty, .{ .mod = mod })).found_existing) return; + if (ty.castTag(.@"struct")) |payload| { const struct_obj = payload.data; for (struct_obj.fields.values()) |field, i| { @@ -19845,9 +19865,10 @@ fn explainWhyTypeIsComptime( .index = i, .range = .type, }); + if (try sema.typeRequiresComptime(block, src, field.ty)) { try mod.errNoteNonLazy(field_src_loc, msg, "struct requires comptime because of this field", .{}); - try sema.explainWhyTypeIsComptime(block, src, msg, field_src_loc, field.ty); + try sema.explainWhyTypeIsComptimeInner(block, src, msg, field_src_loc, field.ty, type_set); } } } @@ -19855,6 +19876,8 @@ fn explainWhyTypeIsComptime( }, .Union => { + if ((try type_set.getOrPutContext(sema.gpa, ty, .{ .mod = mod })).found_existing) return; + if (ty.cast(Type.Payload.Union)) |payload| { const union_obj = payload.data; for (union_obj.fields.values()) |field, i| { @@ -19862,9 +19885,10 @@ fn explainWhyTypeIsComptime( .index = i, .range = .type, }); + if (try sema.typeRequiresComptime(block, src, field.ty)) { try mod.errNoteNonLazy(field_src_loc, msg, "union requires comptime because of this field", .{}); - try sema.explainWhyTypeIsComptime(block, src, msg, field_src_loc, field.ty); + try sema.explainWhyTypeIsComptimeInner(block, src, msg, field_src_loc, field.ty, type_set); } } } |
