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(...@@ -21547,6 +21547,8 @@ fn resolveUnionLayout(
21547 union_obj.status = .have_layout;21547 union_obj.status = .have_layout;
21548}21548}
2154921549
21550/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
21551/// be resolved.
21550pub fn resolveTypeFully(21552pub fn resolveTypeFully(
21551 sema: *Sema,21553 sema: *Sema,
21552 block: *Block,21554 block: *Block,
...@@ -21595,18 +21597,29 @@ fn resolveStructFully(...@@ -21595,18 +21597,29 @@ fn resolveStructFully(
21595 const resolved_ty = try sema.resolveTypeFields(block, src, ty);21597 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
21596 const payload = resolved_ty.castTag(.@"struct") orelse return;21598 const payload = resolved_ty.castTag(.@"struct") orelse return;
21597 const struct_obj = payload.data;21599 const struct_obj = payload.data;
21600
21598 switch (struct_obj.status) {21601 switch (struct_obj.status) {
21599 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},21602 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
21600 .fully_resolved_wip, .fully_resolved => return,21603 .fully_resolved_wip, .fully_resolved => return,
21601 }21604 }
2160221605
21603 // After we have resolve struct layout we have to go over the fields again to21606 log.debug("resolveStructFully {*} ('{s}')", .{
21604 // make sure pointer fields get their child types resolved as well21607 struct_obj.owner_decl, struct_obj.owner_decl.name,
21605 struct_obj.status = .fully_resolved_wip;21608 });
21606 for (struct_obj.fields.values()) |field| {21609
21607 try sema.resolveTypeFully(block, src, field.ty);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;
21608 }21622 }
21609 struct_obj.status = .fully_resolved;
2161021623
21611 // And let's not forget comptime-only status.21624 // And let's not forget comptime-only status.
21612 _ = try sema.typeRequiresComptime(block, src, ty);21625 _ = try sema.typeRequiresComptime(block, src, ty);
...@@ -21627,12 +21640,19 @@ fn resolveUnionFully(...@@ -21627,12 +21640,19 @@ fn resolveUnionFully(
21627 .fully_resolved_wip, .fully_resolved => return,21640 .fully_resolved_wip, .fully_resolved => return,
21628 }21641 }
2162921642
21630 // Same goes for unions (see comment about structs)21643 {
21631 union_obj.status = .fully_resolved_wip;21644 // After we have resolve union layout we have to go over the fields again to
21632 for (union_obj.fields.values()) |field| {21645 // make sure pointer fields get their child types resolved as well.
21633 try sema.resolveTypeFully(block, src, field.ty);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;
21634 }21655 }
21635 union_obj.status = .fully_resolved;
2163621656
21637 // And let's not forget comptime-only status.21657 // And let's not forget comptime-only status.
21638 _ = try sema.typeRequiresComptime(block, src, ty);21658 _ = try sema.typeRequiresComptime(block, src, ty);