mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 22:04:21 +00:00
Sema: resolve inferred error set with function state in_progress
This way dependency loops are reported instead of the compiler crashing.
This commit is contained in:
parent
e1935d4d16
commit
d15e8f8017
2 changed files with 37 additions and 10 deletions
|
|
@ -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.appendSliceAssumeCapacity(inner_block.instructions.items);
|
||||||
sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index;
|
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;
|
func.analysis(ip).state = .success;
|
||||||
|
|
||||||
// Finally we must resolve the return type and parameter types so that backends
|
// 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,
|
// 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
|
// so that dependencies on the function body will now be satisfied rather than
|
||||||
// result in circular dependency errors.
|
// 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.NeededSourceLocation => unreachable,
|
||||||
error.GenericPoison => unreachable,
|
error.GenericPoison => unreachable,
|
||||||
error.ComptimeReturn => unreachable,
|
error.ComptimeReturn => unreachable,
|
||||||
|
|
|
||||||
24
src/Sema.zig
24
src/Sema.zig
|
|
@ -30619,12 +30619,13 @@ fn analyzeIsNonErrComptimeOnly(
|
||||||
ies.func == func_index)
|
ies.func == func_index)
|
||||||
{
|
{
|
||||||
// Try to avoid resolving inferred error set if possible.
|
// 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) {
|
switch (ies.resolved) {
|
||||||
.anyerror_type => break :blk,
|
.anyerror_type => return .none,
|
||||||
.none => {},
|
.none => {},
|
||||||
else => if (ip.indexToKey(ies.resolved).error_set_type.names.len != 0) {
|
else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
|
||||||
break :blk;
|
0 => return .bool_true,
|
||||||
|
else => return .none,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for (ies.inferred_error_sets.keys()) |other_ies_index| {
|
for (ies.inferred_error_sets.keys()) |other_ies_index| {
|
||||||
|
|
@ -30633,10 +30634,10 @@ fn analyzeIsNonErrComptimeOnly(
|
||||||
try sema.resolveInferredErrorSet(block, src, other_ies_index);
|
try sema.resolveInferredErrorSet(block, src, other_ies_index);
|
||||||
if (other_resolved == .anyerror_type) {
|
if (other_resolved == .anyerror_type) {
|
||||||
ies.resolved = .anyerror_type;
|
ies.resolved = .anyerror_type;
|
||||||
break :blk;
|
return .none;
|
||||||
}
|
}
|
||||||
if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
|
if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
|
||||||
break :blk;
|
return .none;
|
||||||
}
|
}
|
||||||
return .bool_true;
|
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 mod = sema.mod;
|
||||||
const ip = &mod.intern_pool;
|
const ip = &mod.intern_pool;
|
||||||
const fn_ty_info = mod.typeToFunc(fn_ty).?;
|
|
||||||
|
|
||||||
if (sema.fn_ret_ty_ies) |ies| {
|
if (sema.fn_ret_ty_ies) |ies| {
|
||||||
try sema.resolveInferredErrorSetPtr(block, src, ies);
|
try sema.resolveInferredErrorSetPtr(block, src, ies);
|
||||||
assert(ies.resolved != .none);
|
assert(ies.resolved != .none);
|
||||||
ip.funcIesResolved(sema.func_index).* = ies.resolved;
|
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());
|
try sema.resolveTypeFully(fn_ty_info.return_type.toType());
|
||||||
|
|
||||||
|
|
@ -34111,7 +34117,7 @@ fn resolveInferredErrorSet(
|
||||||
return final_resolved_ty;
|
return final_resolved_ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolveInferredErrorSetPtr(
|
pub fn resolveInferredErrorSetPtr(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
block: *Block,
|
block: *Block,
|
||||||
src: LazySrcLoc,
|
src: LazySrcLoc,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue