authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-16 23:17:19-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-18 19:02:06-07:00
logd15e8f8017758fb77dd6e839ef3f39b174522c5c
tree4c5f00b6e84312945f40a9f6e011e03a12ca1847
parente1935d4d16778e4284d981e5de096155b4887128

Sema: resolve inferred error set with function state in_progress

This way dependency loops are reported instead of the compiler crashing.

2 files changed, 37 insertions(+), 10 deletions(-)

src/Module.zig+22-1
......@@ -5348,6 +5348,27 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
53485348 sema.air_extra.appendSliceAssumeCapacity(inner_block.instructions.items);
53495349 sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index;
53505350
5351 // Resolving inferred error sets is done *before* setting the function
5352 // state to success, so that "unable to resolve inferred error set" errors
5353 // can be emitted here.
5354 if (sema.fn_ret_ty_ies) |ies| {
5355 sema.resolveInferredErrorSetPtr(&inner_block, LazySrcLoc.nodeOffset(0), ies) catch |err| switch (err) {
5356 error.NeededSourceLocation => unreachable,
5357 error.GenericPoison => unreachable,
5358 error.ComptimeReturn => unreachable,
5359 error.ComptimeBreak => unreachable,
5360 error.AnalysisFail => {
5361 // In this case our function depends on a type that had a compile error.
5362 // We should not try to lower this function.
5363 decl.analysis = .dependency_failure;
5364 return error.AnalysisFail;
5365 },
5366 else => |e| return e,
5367 };
5368 assert(ies.resolved != .none);
5369 ip.funcIesResolved(func_index).* = ies.resolved;
5370 }
5371
53515372 func.analysis(ip).state = .success;
53525373
53535374 // Finally we must resolve the return type and parameter types so that backends
......@@ -5355,7 +5376,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
53555376 // Crucially, this happens *after* we set the function state to success above,
53565377 // so that dependencies on the function body will now be satisfied rather than
53575378 // result in circular dependency errors.
5358 sema.resolveFnTypes(&inner_block, LazySrcLoc.nodeOffset(0), fn_ty) catch |err| switch (err) {
5379 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
53595380 error.NeededSourceLocation => unreachable,
53605381 error.GenericPoison => unreachable,
53615382 error.ComptimeReturn => unreachable,
src/Sema.zig+15-9
......@@ -30619,12 +30619,13 @@ fn analyzeIsNonErrComptimeOnly(
3061930619 ies.func == func_index)
3062030620 {
3062130621 // Try to avoid resolving inferred error set if possible.
30622 if (ies.errors.count() != 0) break :blk;
30622 if (ies.errors.count() != 0) return .none;
3062330623 switch (ies.resolved) {
30624 .anyerror_type => break :blk,
30624 .anyerror_type => return .none,
3062530625 .none => {},
30626 else => if (ip.indexToKey(ies.resolved).error_set_type.names.len != 0) {
30627 break :blk;
30626 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
30627 0 => return .bool_true,
30628 else => return .none,
3062830629 },
3062930630 }
3063030631 for (ies.inferred_error_sets.keys()) |other_ies_index| {
......@@ -30633,10 +30634,10 @@ fn analyzeIsNonErrComptimeOnly(
3063330634 try sema.resolveInferredErrorSet(block, src, other_ies_index);
3063430635 if (other_resolved == .anyerror_type) {
3063530636 ies.resolved = .anyerror_type;
30636 break :blk;
30637 return .none;
3063730638 }
3063830639 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30639 break :blk;
30640 return .none;
3064030641 }
3064130642 return .bool_true;
3064230643 }
......@@ -33113,16 +33114,21 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
3311333114 };
3311433115}
3311533116
33116pub fn resolveFnTypes(sema: *Sema, block: *Block, src: LazySrcLoc, fn_ty: Type) CompileError!void {
33117pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void {
3311733118 const mod = sema.mod;
3311833119 const ip = &mod.intern_pool;
33119 const fn_ty_info = mod.typeToFunc(fn_ty).?;
3312033120
3312133121 if (sema.fn_ret_ty_ies) |ies| {
3312233122 try sema.resolveInferredErrorSetPtr(block, src, ies);
3312333123 assert(ies.resolved != .none);
3312433124 ip.funcIesResolved(sema.func_index).* = ies.resolved;
3312533125 }
33126}
33127
33128pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
33129 const mod = sema.mod;
33130 const ip = &mod.intern_pool;
33131 const fn_ty_info = mod.typeToFunc(fn_ty).?;
3312633132
3312733133 try sema.resolveTypeFully(fn_ty_info.return_type.toType());
3312833134
......@@ -34111,7 +34117,7 @@ fn resolveInferredErrorSet(
3411134117 return final_resolved_ty;
3411234118}
3411334119
34114fn resolveInferredErrorSetPtr(
34120pub fn resolveInferredErrorSetPtr(
3411534121 sema: *Sema,
3411634122 block: *Block,
3411734123 src: LazySrcLoc,