authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-22 19:00:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-22 19:05:56-07:00
loge03095f167cf0cd8c1424bff0de3c0a7b5f66b18
tree5981b50b570382137f1cf4c1eb2f528cc6962f21
parentd86678778a6bcc31dc3cb92a286c278de1214c38

stage2: remove 2 assertions that were too aggressive

* `Type.hasCodeGenBits` this function is used to find out if it ever got sent to a linker backend for lowering. In the case that a struct never has its struct fields resolved, this will be false. In such a case, no corresponding `freeDecl` needs to be issued to the linker backend. So instead of asserting the fields of a struct are resolved, this function now returns `false` for this case. * `Module.clearDecl` there was logic that asserted when there is no outdated_decls map, any dependants of a Decl being cleared had to be in the deletion set. However there is a possible scenario where the dependant is not in the deletion set *yet* because there is a Decl which depends on it, about to be deleted. If it were added to an outdated_decls map, it would be subsequently removed from the map when it gets deleted recursively through its dependency being deleted. These issues were uncovered via unrelated changes which are the two commits immediately preceding this one.

2 files changed, 2 insertions(+), 11 deletions(-)

src/Module.zig-7
...@@ -3758,13 +3758,6 @@ pub fn clearDecl(...@@ -3758,13 +3758,6 @@ pub fn clearDecl(
3758 dep.removeDependency(decl);3758 dep.removeDependency(decl);
3759 if (outdated_decls) |map| {3759 if (outdated_decls) |map| {
3760 map.putAssumeCapacity(dep, {});3760 map.putAssumeCapacity(dep, {});
3761 } else if (std.debug.runtime_safety) {
3762 // If `outdated_decls` is `null`, it means we're being called from
3763 // `Compilation` after `performAllTheWork` and we cannot queue up any
3764 // more work. `dep` must necessarily be another Decl that is no longer
3765 // being referenced, and will be in the `deletion_set`. Otherwise,
3766 // something has gone wrong.
3767 assert(mod.deletion_set.contains(dep));
3768 }3761 }
3769 }3762 }
3770 decl.dependants.clearRetainingCapacity();3763 decl.dependants.clearRetainingCapacity();
src/type.zig+2-4
...@@ -1336,6 +1336,8 @@ pub const Type = extern union {...@@ -1336,6 +1336,8 @@ pub const Type = extern union {
1336 }1336 }
1337 }1337 }
13381338
1339 /// For structs and unions, if the type does not have their fields resolved
1340 /// this will return `false`.
1339 pub fn hasCodeGenBits(self: Type) bool {1341 pub fn hasCodeGenBits(self: Type) bool {
1340 return switch (self.tag()) {1342 return switch (self.tag()) {
1341 .u1,1343 .u1,
...@@ -1400,14 +1402,10 @@ pub const Type = extern union {...@@ -1400,14 +1402,10 @@ pub const Type = extern union {
1400 => true,1402 => true,
14011403
1402 .@"struct" => {1404 .@"struct" => {
1403 // TODO introduce lazy value mechanism
1404 const struct_obj = self.castTag(.@"struct").?.data;1405 const struct_obj = self.castTag(.@"struct").?.data;
1405 if (struct_obj.known_has_bits) {1406 if (struct_obj.known_has_bits) {
1406 return true;1407 return true;
1407 }1408 }
1408 assert(struct_obj.status == .have_field_types or
1409 struct_obj.status == .layout_wip or
1410 struct_obj.status == .have_layout);
1411 for (struct_obj.fields.values()) |value| {1409 for (struct_obj.fields.values()) |value| {
1412 if (value.ty.hasCodeGenBits())1410 if (value.ty.hasCodeGenBits())
1413 return true;1411 return true;