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...@@ -5348,6 +5348,27 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
5348 sema.air_extra.appendSliceAssumeCapacity(inner_block.instructions.items);5348 sema.air_extra.appendSliceAssumeCapacity(inner_block.instructions.items);
5349 sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index;5349 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
5351 func.analysis(ip).state = .success;5372 func.analysis(ip).state = .success;
53525373
5353 // Finally we must resolve the return type and parameter types so that backends5374 // 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...@@ -5355,7 +5376,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
5355 // Crucially, this happens *after* we set the function state to success above,5376 // Crucially, this happens *after* we set the function state to success above,
5356 // so that dependencies on the function body will now be satisfied rather than5377 // so that dependencies on the function body will now be satisfied rather than
5357 // result in circular dependency errors.5378 // 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) {
5359 error.NeededSourceLocation => unreachable,5380 error.NeededSourceLocation => unreachable,
5360 error.GenericPoison => unreachable,5381 error.GenericPoison => unreachable,
5361 error.ComptimeReturn => unreachable,5382 error.ComptimeReturn => unreachable,
src/Sema.zig+15-9
...@@ -30619,12 +30619,13 @@ fn analyzeIsNonErrComptimeOnly(...@@ -30619,12 +30619,13 @@ fn analyzeIsNonErrComptimeOnly(
30619 ies.func == func_index)30619 ies.func == func_index)
30620 {30620 {
30621 // Try to avoid resolving inferred error set if possible.30621 // 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;
30623 switch (ies.resolved) {30623 switch (ies.resolved) {
30624 .anyerror_type => break :blk,30624 .anyerror_type => return .none,
30625 .none => {},30625 .none => {},
30626 else => if (ip.indexToKey(ies.resolved).error_set_type.names.len != 0) {30626 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
30627 break :blk;30627 0 => return .bool_true,
30628 else => return .none,
30628 },30629 },
30629 }30630 }
30630 for (ies.inferred_error_sets.keys()) |other_ies_index| {30631 for (ies.inferred_error_sets.keys()) |other_ies_index| {
...@@ -30633,10 +30634,10 @@ fn analyzeIsNonErrComptimeOnly(...@@ -30633,10 +30634,10 @@ fn analyzeIsNonErrComptimeOnly(
30633 try sema.resolveInferredErrorSet(block, src, other_ies_index);30634 try sema.resolveInferredErrorSet(block, src, other_ies_index);
30634 if (other_resolved == .anyerror_type) {30635 if (other_resolved == .anyerror_type) {
30635 ies.resolved = .anyerror_type;30636 ies.resolved = .anyerror_type;
30636 break :blk;30637 return .none;
30637 }30638 }
30638 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)30639 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30639 break :blk;30640 return .none;
30640 }30641 }
30641 return .bool_true;30642 return .bool_true;
30642 }30643 }
...@@ -33113,16 +33114,21 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {...@@ -33113,16 +33114,21 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
33113 };33114 };
33114}33115}
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 {
33117 const mod = sema.mod;33118 const mod = sema.mod;
33118 const ip = &mod.intern_pool;33119 const ip = &mod.intern_pool;
33119 const fn_ty_info = mod.typeToFunc(fn_ty).?;
3312033120
33121 if (sema.fn_ret_ty_ies) |ies| {33121 if (sema.fn_ret_ty_ies) |ies| {
33122 try sema.resolveInferredErrorSetPtr(block, src, ies);33122 try sema.resolveInferredErrorSetPtr(block, src, ies);
33123 assert(ies.resolved != .none);33123 assert(ies.resolved != .none);
33124 ip.funcIesResolved(sema.func_index).* = ies.resolved;33124 ip.funcIesResolved(sema.func_index).* = ies.resolved;
33125 }33125 }
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
33127 try sema.resolveTypeFully(fn_ty_info.return_type.toType());33133 try sema.resolveTypeFully(fn_ty_info.return_type.toType());
3312833134
...@@ -34111,7 +34117,7 @@ fn resolveInferredErrorSet(...@@ -34111,7 +34117,7 @@ fn resolveInferredErrorSet(
34111 return final_resolved_ty;34117 return final_resolved_ty;
34112}34118}
3411334119
34114fn resolveInferredErrorSetPtr(34120pub fn resolveInferredErrorSetPtr(
34115 sema: *Sema,34121 sema: *Sema,
34116 block: *Block,34122 block: *Block,
34117 src: LazySrcLoc,34123 src: LazySrcLoc,