Sema: introduce a type resolution queue

That happens after a function body is analyzed. This prevents circular
dependency compile errors and yet a way to mark types that need to be
fully resolved before a given function is sent to the codegen backend.
This commit is contained in:
Andrew Kelley
2022-03-23 18:45:51 -07:00
parent 57539a26b4
commit 7378ce67da
5 changed files with 82 additions and 44 deletions

View File

@@ -4837,6 +4837,9 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem
// Finally we must resolve the return type and parameter types so that backends
// have full access to type information.
// Crucially, this happens *after* we set the function state to success above,
// so that dependencies on the function body will now be satisfied rather than
// result in circular dependency errors.
const src: LazySrcLoc = .{ .node_offset = 0 };
sema.resolveFnTypes(&inner_block, src, fn_ty_info) catch |err| switch (err) {
error.NeededSourceLocation => unreachable,
@@ -4847,6 +4850,20 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem
else => |e| return e,
};
// Similarly, resolve any queued up types that were requested to be resolved for
// the backends.
for (sema.types_to_resolve.items) |inst_ref| {
const ty = sema.getTmpAir().getRefType(inst_ref);
sema.resolveTypeFully(&inner_block, src, ty) catch |err| switch (err) {
error.NeededSourceLocation => unreachable,
error.GenericPoison => unreachable,
error.ComptimeReturn => unreachable,
error.ComptimeBreak => unreachable,
error.AnalysisFail => {},
else => |e| return e,
};
}
return Air{
.instructions = sema.air_instructions.toOwnedSlice(),
.extra = sema.air_extra.toOwnedSlice(gpa),