aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzooster <r00ster91@proton.me>2022-08-06 19:32:42 +0200
committerGitHub <noreply@github.com>2022-08-06 19:32:42 +0200
commit3debd6b732556832e58491cb153e1fee2cc8876b (patch)
tree6ae912f0b6163d0efa7f081bb66fe9556d41ddd8 /src
parent943f4eb515ec03499cf7b37d80b964e15502bfc8 (diff)
parent94662591d617226caabcb6c7319d703f1e41a880 (diff)
downloadzig-3debd6b732556832e58491cb153e1fee2cc8876b.tar.gz
zig-3debd6b732556832e58491cb153e1fee2cc8876b.zip
Merge branch 'master' into nicedocs
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig36
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);
}
}
}