aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-07-16 23:17:19 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-07-18 19:02:06 -0700
commitd15e8f8017758fb77dd6e839ef3f39b174522c5c (patch)
tree4c5f00b6e84312945f40a9f6e011e03a12ca1847 /src
parente1935d4d16778e4284d981e5de096155b4887128 (diff)
downloadzig-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.zig23
-rw-r--r--src/Sema.zig24
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,