diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-07-16 23:17:19 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-07-18 19:02:06 -0700 |
| commit | d15e8f8017758fb77dd6e839ef3f39b174522c5c (patch) | |
| tree | 4c5f00b6e84312945f40a9f6e011e03a12ca1847 /src | |
| parent | e1935d4d16778e4284d981e5de096155b4887128 (diff) | |
| download | zig-d15e8f8017758fb77dd6e839ef3f39b174522c5c.tar.gz zig-d15e8f8017758fb77dd6e839ef3f39b174522c5c.zip | |
Sema: resolve inferred error set with function state in_progress
This way dependency loops are reported instead of the compiler crashing.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 23 | ||||
| -rw-r--r-- | src/Sema.zig | 24 |
2 files changed, 37 insertions, 10 deletions
diff --git a/src/Module.zig b/src/Module.zig index 83449f093b..45536547d8 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5348,6 +5348,27 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato sema.air_extra.appendSliceAssumeCapacity(inner_block.instructions.items); sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index; + // Resolving inferred error sets is done *before* setting the function + // state to success, so that "unable to resolve inferred error set" errors + // can be emitted here. + if (sema.fn_ret_ty_ies) |ies| { + sema.resolveInferredErrorSetPtr(&inner_block, LazySrcLoc.nodeOffset(0), ies) catch |err| switch (err) { + error.NeededSourceLocation => unreachable, + error.GenericPoison => unreachable, + error.ComptimeReturn => unreachable, + error.ComptimeBreak => unreachable, + error.AnalysisFail => { + // In this case our function depends on a type that had a compile error. + // We should not try to lower this function. + decl.analysis = .dependency_failure; + return error.AnalysisFail; + }, + else => |e| return e, + }; + assert(ies.resolved != .none); + ip.funcIesResolved(func_index).* = ies.resolved; + } + func.analysis(ip).state = .success; // 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 // 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. - sema.resolveFnTypes(&inner_block, LazySrcLoc.nodeOffset(0), fn_ty) catch |err| switch (err) { + sema.resolveFnTypes(fn_ty) catch |err| switch (err) { error.NeededSourceLocation => unreachable, error.GenericPoison => unreachable, error.ComptimeReturn => unreachable, diff --git a/src/Sema.zig b/src/Sema.zig index e02e99faf2..3f59548b47 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -30619,12 +30619,13 @@ fn analyzeIsNonErrComptimeOnly( ies.func == func_index) { // Try to avoid resolving inferred error set if possible. - if (ies.errors.count() != 0) break :blk; + if (ies.errors.count() != 0) return .none; switch (ies.resolved) { - .anyerror_type => break :blk, + .anyerror_type => return .none, .none => {}, - else => if (ip.indexToKey(ies.resolved).error_set_type.names.len != 0) { - break :blk; + else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) { + 0 => return .bool_true, + else => return .none, }, } for (ies.inferred_error_sets.keys()) |other_ies_index| { @@ -30633,10 +30634,10 @@ fn analyzeIsNonErrComptimeOnly( try sema.resolveInferredErrorSet(block, src, other_ies_index); if (other_resolved == .anyerror_type) { ies.resolved = .anyerror_type; - break :blk; + return .none; } if (ip.indexToKey(other_resolved).error_set_type.names.len != 0) - break :blk; + return .none; } return .bool_true; } @@ -33113,16 +33114,21 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { }; } -pub fn resolveFnTypes(sema: *Sema, block: *Block, src: LazySrcLoc, fn_ty: Type) CompileError!void { +pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void { const mod = sema.mod; const ip = &mod.intern_pool; - const fn_ty_info = mod.typeToFunc(fn_ty).?; if (sema.fn_ret_ty_ies) |ies| { try sema.resolveInferredErrorSetPtr(block, src, ies); assert(ies.resolved != .none); ip.funcIesResolved(sema.func_index).* = ies.resolved; } +} + +pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void { + const mod = sema.mod; + const ip = &mod.intern_pool; + const fn_ty_info = mod.typeToFunc(fn_ty).?; try sema.resolveTypeFully(fn_ty_info.return_type.toType()); @@ -34111,7 +34117,7 @@ fn resolveInferredErrorSet( return final_resolved_ty; } -fn resolveInferredErrorSetPtr( +pub fn resolveInferredErrorSetPtr( sema: *Sema, block: *Block, src: LazySrcLoc, |
