authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-05 23:12:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-05 23:16:35-07:00
logdd9782a8bc6f4af458a04cea2619f55e749c39ee
tree6831c36a68b0e52428c15c85ce6815b09636feed
parentac873367b9d68e1d7b4cf4e5efbe179960dc7557

Sema: fix handling compile errors during circular dependency error

Previously, Zig would try to generate a function whose type contained structs or unions which had not been fully resolved due to circular dependency errors. With this commit, `resolveTypeFully` will be sure to return `error.AnalysisFail` even in this scenario, leading to proper display of compilation errors instead of a crash.

1 files changed, 31 insertions(+), 11 deletions(-)

src/Sema.zig+31-11
......@@ -21547,6 +21547,8 @@ fn resolveUnionLayout(
2154721547 union_obj.status = .have_layout;
2154821548}
2154921549
21550/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
21551/// be resolved.
2155021552pub fn resolveTypeFully(
2155121553 sema: *Sema,
2155221554 block: *Block,
......@@ -21595,18 +21597,29 @@ fn resolveStructFully(
2159521597 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
2159621598 const payload = resolved_ty.castTag(.@"struct") orelse return;
2159721599 const struct_obj = payload.data;
21600
2159821601 switch (struct_obj.status) {
2159921602 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
2160021603 .fully_resolved_wip, .fully_resolved => return,
2160121604 }
2160221605
21603 // After we have resolve struct layout we have to go over the fields again to
21604 // make sure pointer fields get their child types resolved as well
21605 struct_obj.status = .fully_resolved_wip;
21606 for (struct_obj.fields.values()) |field| {
21607 try sema.resolveTypeFully(block, src, field.ty);
21606 log.debug("resolveStructFully {*} ('{s}')", .{
21607 struct_obj.owner_decl, struct_obj.owner_decl.name,
21608 });
21609
21610 {
21611 // After we have resolve struct layout we have to go over the fields again to
21612 // make sure pointer fields get their child types resolved as well.
21613 // See also similar code for unions.
21614 const prev_status = struct_obj.status;
21615 errdefer struct_obj.status = prev_status;
21616
21617 struct_obj.status = .fully_resolved_wip;
21618 for (struct_obj.fields.values()) |field| {
21619 try sema.resolveTypeFully(block, src, field.ty);
21620 }
21621 struct_obj.status = .fully_resolved;
2160821622 }
21609 struct_obj.status = .fully_resolved;
2161021623
2161121624 // And let's not forget comptime-only status.
2161221625 _ = try sema.typeRequiresComptime(block, src, ty);
......@@ -21627,12 +21640,19 @@ fn resolveUnionFully(
2162721640 .fully_resolved_wip, .fully_resolved => return,
2162821641 }
2162921642
21630 // Same goes for unions (see comment about structs)
21631 union_obj.status = .fully_resolved_wip;
21632 for (union_obj.fields.values()) |field| {
21633 try sema.resolveTypeFully(block, src, field.ty);
21643 {
21644 // After we have resolve union layout we have to go over the fields again to
21645 // make sure pointer fields get their child types resolved as well.
21646 // See also similar code for structs.
21647 const prev_status = union_obj.status;
21648 errdefer union_obj.status = prev_status;
21649
21650 union_obj.status = .fully_resolved_wip;
21651 for (union_obj.fields.values()) |field| {
21652 try sema.resolveTypeFully(block, src, field.ty);
21653 }
21654 union_obj.status = .fully_resolved;
2163421655 }
21635 union_obj.status = .fully_resolved;
2163621656
2163721657 // And let's not forget comptime-only status.
2163821658 _ = try sema.typeRequiresComptime(block, src, ty);