mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Sema: implement comptime error return traces
This commit is contained in:
parent
9e684e8d1a
commit
eeec34ccb6
@ -3479,6 +3479,9 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
|
|||||||
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
|
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
|
||||||
defer comptime_mutable_decls.deinit();
|
defer comptime_mutable_decls.deinit();
|
||||||
|
|
||||||
|
var comptime_err_ret_trace = std.ArrayList(SrcLoc).init(gpa);
|
||||||
|
defer comptime_err_ret_trace.deinit();
|
||||||
|
|
||||||
var sema: Sema = .{
|
var sema: Sema = .{
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
@ -3492,6 +3495,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
|
|||||||
.fn_ret_ty_ies = null,
|
.fn_ret_ty_ies = null,
|
||||||
.owner_func_index = .none,
|
.owner_func_index = .none,
|
||||||
.comptime_mutable_decls = &comptime_mutable_decls,
|
.comptime_mutable_decls = &comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = &comptime_err_ret_trace,
|
||||||
};
|
};
|
||||||
defer sema.deinit();
|
defer sema.deinit();
|
||||||
|
|
||||||
@ -3600,6 +3604,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
|||||||
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
|
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
|
||||||
defer comptime_mutable_decls.deinit();
|
defer comptime_mutable_decls.deinit();
|
||||||
|
|
||||||
|
var comptime_err_ret_trace = std.ArrayList(SrcLoc).init(gpa);
|
||||||
|
defer comptime_err_ret_trace.deinit();
|
||||||
|
|
||||||
var sema: Sema = .{
|
var sema: Sema = .{
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
@ -3613,6 +3620,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
|
|||||||
.fn_ret_ty_ies = null,
|
.fn_ret_ty_ies = null,
|
||||||
.owner_func_index = .none,
|
.owner_func_index = .none,
|
||||||
.comptime_mutable_decls = &comptime_mutable_decls,
|
.comptime_mutable_decls = &comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = &comptime_err_ret_trace,
|
||||||
.builtin_type_target_index = builtin_type_target_index,
|
.builtin_type_target_index = builtin_type_target_index,
|
||||||
};
|
};
|
||||||
defer sema.deinit();
|
defer sema.deinit();
|
||||||
@ -4451,6 +4459,9 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
|
|||||||
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
|
var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
|
||||||
defer comptime_mutable_decls.deinit();
|
defer comptime_mutable_decls.deinit();
|
||||||
|
|
||||||
|
var comptime_err_ret_trace = std.ArrayList(SrcLoc).init(gpa);
|
||||||
|
defer comptime_err_ret_trace.deinit();
|
||||||
|
|
||||||
// In the case of a generic function instance, this is the type of the
|
// In the case of a generic function instance, this is the type of the
|
||||||
// instance, which has comptime parameters elided. In other words, it is
|
// instance, which has comptime parameters elided. In other words, it is
|
||||||
// the runtime-known parameters only, not to be confused with the
|
// the runtime-known parameters only, not to be confused with the
|
||||||
@ -4473,6 +4484,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
|
|||||||
.owner_func_index = func_index,
|
.owner_func_index = func_index,
|
||||||
.branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota),
|
.branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota),
|
||||||
.comptime_mutable_decls = &comptime_mutable_decls,
|
.comptime_mutable_decls = &comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = &comptime_err_ret_trace,
|
||||||
};
|
};
|
||||||
defer sema.deinit();
|
defer sema.deinit();
|
||||||
|
|
||||||
|
|||||||
135
src/Sema.zig
135
src/Sema.zig
@ -34,6 +34,7 @@ func_index: InternPool.Index,
|
|||||||
func_is_naked: bool,
|
func_is_naked: bool,
|
||||||
/// Used to restore the error return trace when returning a non-error from a function.
|
/// Used to restore the error return trace when returning a non-error from a function.
|
||||||
error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none,
|
error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none,
|
||||||
|
comptime_err_ret_trace: *std.ArrayList(Module.SrcLoc),
|
||||||
/// When semantic analysis needs to know the return type of the function whose body
|
/// When semantic analysis needs to know the return type of the function whose body
|
||||||
/// is being analyzed, this `Type` should be used instead of going through `func`.
|
/// is being analyzed, this `Type` should be used instead of going through `func`.
|
||||||
/// This will correctly handle the case of a comptime/inline function call of a
|
/// This will correctly handle the case of a comptime/inline function call of a
|
||||||
@ -1569,7 +1570,22 @@ fn analyzeBodyInner(
|
|||||||
const inst_data = datas[@intFromEnum(inst)].pl_node;
|
const inst_data = datas[@intFromEnum(inst)].pl_node;
|
||||||
const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
|
const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
|
||||||
const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
|
const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
|
||||||
const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
|
|
||||||
|
// Create a temporary child block so that this loop is properly
|
||||||
|
// labeled for any .restore_err_ret_index instructions
|
||||||
|
var child_block = block.makeSubBlock();
|
||||||
|
|
||||||
|
var label: Block.Label = .{
|
||||||
|
.zir_block = inst,
|
||||||
|
.merges = undefined,
|
||||||
|
};
|
||||||
|
child_block.label = &label;
|
||||||
|
|
||||||
|
// Write these instructions directly into the parent block
|
||||||
|
child_block.instructions = block.instructions;
|
||||||
|
defer block.instructions = child_block.instructions;
|
||||||
|
|
||||||
|
const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse
|
||||||
break always_noreturn;
|
break always_noreturn;
|
||||||
if (inst == break_data.block_inst) {
|
if (inst == break_data.block_inst) {
|
||||||
break :blk try sema.resolveInst(break_data.operand);
|
break :blk try sema.resolveInst(break_data.operand);
|
||||||
@ -1585,13 +1601,22 @@ fn analyzeBodyInner(
|
|||||||
const inst_data = datas[@intFromEnum(inst)].pl_node;
|
const inst_data = datas[@intFromEnum(inst)].pl_node;
|
||||||
const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
|
const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
|
||||||
const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
|
const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
|
||||||
// If this block contains a function prototype, we need to reset the
|
|
||||||
// current list of parameters and restore it later.
|
// Create a temporary child block so that this block is properly
|
||||||
// Note: this probably needs to be resolved in a more general manner.
|
// labeled for any .restore_err_ret_index instructions
|
||||||
const prev_params = block.params;
|
var child_block = block.makeSubBlock();
|
||||||
block.params = .{};
|
|
||||||
defer block.params = prev_params;
|
var label: Block.Label = .{
|
||||||
const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
|
.zir_block = inst,
|
||||||
|
.merges = undefined,
|
||||||
|
};
|
||||||
|
child_block.label = &label;
|
||||||
|
|
||||||
|
// Write these instructions directly into the parent block
|
||||||
|
child_block.instructions = block.instructions;
|
||||||
|
defer block.instructions = child_block.instructions;
|
||||||
|
|
||||||
|
const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse
|
||||||
break always_noreturn;
|
break always_noreturn;
|
||||||
if (inst == break_data.block_inst) {
|
if (inst == break_data.block_inst) {
|
||||||
break :blk try sema.resolveInst(break_data.operand);
|
break :blk try sema.resolveInst(break_data.operand);
|
||||||
@ -2379,6 +2404,25 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn failWithComptimeErrorRetTrace(
|
||||||
|
sema: *Sema,
|
||||||
|
block: *Block,
|
||||||
|
src: LazySrcLoc,
|
||||||
|
name: InternPool.NullTerminatedString,
|
||||||
|
) CompileError {
|
||||||
|
const mod = sema.mod;
|
||||||
|
const msg = msg: {
|
||||||
|
const msg = try sema.errMsg(block, src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)});
|
||||||
|
errdefer msg.destroy(sema.gpa);
|
||||||
|
|
||||||
|
for (sema.comptime_err_ret_trace.items) |src_loc| {
|
||||||
|
try mod.errNoteNonLazy(src_loc, msg, "error returned here", .{});
|
||||||
|
}
|
||||||
|
break :msg msg;
|
||||||
|
};
|
||||||
|
return sema.failWithOwnedErrorMsg(block, msg);
|
||||||
|
}
|
||||||
|
|
||||||
/// We don't return a pointer to the new error note because the pointer
|
/// We don't return a pointer to the new error note because the pointer
|
||||||
/// becomes invalid when you add another one.
|
/// becomes invalid when you add another one.
|
||||||
fn errNote(
|
fn errNote(
|
||||||
@ -6534,10 +6578,12 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
|
|||||||
const gpa = sema.gpa;
|
const gpa = sema.gpa;
|
||||||
const src = sema.src;
|
const src = sema.src;
|
||||||
|
|
||||||
if (!block.ownerModule().error_tracing) return .none;
|
if (block.is_comptime or block.is_typeof) {
|
||||||
|
const index_val = try mod.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len);
|
||||||
|
return Air.internedToRef(index_val.toIntern());
|
||||||
|
}
|
||||||
|
|
||||||
if (block.is_comptime)
|
if (!block.ownerModule().error_tracing) return .none;
|
||||||
return .none;
|
|
||||||
|
|
||||||
const stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) {
|
const stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) {
|
||||||
error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
|
error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
|
||||||
@ -7498,6 +7544,14 @@ fn analyzeCall(
|
|||||||
try sema.ensureResultUsed(block, sema.fn_ret_ty, call_src);
|
try sema.ensureResultUsed(block, sema.fn_ret_ty, call_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_comptime_call or block.is_typeof) {
|
||||||
|
// Save the error trace as our first action in the function
|
||||||
|
// to match the behavior of runtime function calls.
|
||||||
|
const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&child_block);
|
||||||
|
sema.error_return_trace_index_on_fn_entry = error_return_trace_index;
|
||||||
|
child_block.error_return_trace_index = error_return_trace_index;
|
||||||
|
}
|
||||||
|
|
||||||
const result = result: {
|
const result = result: {
|
||||||
sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
|
sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
|
||||||
error.ComptimeReturn => break :result inlining.comptime_result,
|
error.ComptimeReturn => break :result inlining.comptime_result,
|
||||||
@ -7858,6 +7912,7 @@ fn instantiateGenericCall(
|
|||||||
.branch_quota = sema.branch_quota,
|
.branch_quota = sema.branch_quota,
|
||||||
.branch_count = sema.branch_count,
|
.branch_count = sema.branch_count,
|
||||||
.comptime_mutable_decls = sema.comptime_mutable_decls,
|
.comptime_mutable_decls = sema.comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = sema.comptime_err_ret_trace,
|
||||||
};
|
};
|
||||||
defer child_sema.deinit();
|
defer child_sema.deinit();
|
||||||
|
|
||||||
@ -8783,7 +8838,7 @@ fn analyzeErrUnionPayload(
|
|||||||
const payload_ty = err_union_ty.errorUnionPayload(mod);
|
const payload_ty = err_union_ty.errorUnionPayload(mod);
|
||||||
if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
|
if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
|
||||||
if (val.getErrorName(mod).unwrap()) |name| {
|
if (val.getErrorName(mod).unwrap()) |name| {
|
||||||
return sema.fail(block, src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)});
|
return sema.failWithComptimeErrorRetTrace(block, src, name);
|
||||||
}
|
}
|
||||||
return Air.internedToRef(mod.intern_pool.indexToKey(val.toIntern()).error_union.val.payload);
|
return Air.internedToRef(mod.intern_pool.indexToKey(val.toIntern()).error_union.val.payload);
|
||||||
}
|
}
|
||||||
@ -8861,7 +8916,7 @@ fn analyzeErrUnionPayloadPtr(
|
|||||||
}
|
}
|
||||||
if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
|
if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
|
||||||
if (val.getErrorName(mod).unwrap()) |name| {
|
if (val.getErrorName(mod).unwrap()) |name| {
|
||||||
return sema.fail(block, src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)});
|
return sema.failWithComptimeErrorRetTrace(block, src, name);
|
||||||
}
|
}
|
||||||
return Air.internedToRef((try mod.intern(.{ .ptr = .{
|
return Air.internedToRef((try mod.intern(.{ .ptr = .{
|
||||||
.ty = operand_pointer_ty.toIntern(),
|
.ty = operand_pointer_ty.toIntern(),
|
||||||
@ -13437,7 +13492,7 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I
|
|||||||
|
|
||||||
if (try sema.resolveDefinedValue(block, src, operand)) |val| {
|
if (try sema.resolveDefinedValue(block, src, operand)) |val| {
|
||||||
if (val.getErrorName(sema.mod).unwrap()) |name| {
|
if (val.getErrorName(sema.mod).unwrap()) |name| {
|
||||||
return sema.fail(block, src, "caught unexpected error '{}'", .{name.fmt(&sema.mod.intern_pool)});
|
return sema.failWithComptimeErrorRetTrace(block, src, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19227,15 +19282,9 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
|
|||||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].restore_err_ret_index;
|
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].restore_err_ret_index;
|
||||||
const src = sema.src; // TODO
|
const src = sema.src; // TODO
|
||||||
|
|
||||||
// This is only relevant at runtime.
|
|
||||||
if (start_block.is_comptime or start_block.is_typeof) return;
|
|
||||||
|
|
||||||
const mod = sema.mod;
|
const mod = sema.mod;
|
||||||
const ip = &mod.intern_pool;
|
const ip = &mod.intern_pool;
|
||||||
|
|
||||||
if (!ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
|
|
||||||
if (!start_block.ownerModule().error_tracing) return;
|
|
||||||
|
|
||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
@ -19263,9 +19312,29 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
|
|||||||
return; // No need to restore
|
return; // No need to restore
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const operand = try sema.resolveInstAllowNone(inst_data.operand);
|
||||||
|
|
||||||
|
if (start_block.is_comptime or start_block.is_typeof) {
|
||||||
|
const is_non_error = if (operand != .none) blk: {
|
||||||
|
const is_non_error_inst = try sema.analyzeIsNonErr(start_block, src, operand);
|
||||||
|
const cond_val = try sema.resolveDefinedValue(start_block, src, is_non_error_inst);
|
||||||
|
break :blk cond_val.?.toBool();
|
||||||
|
} else true; // no operand means pop unconditionally
|
||||||
|
|
||||||
|
if (is_non_error) return;
|
||||||
|
|
||||||
|
const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index);
|
||||||
|
const saved_index_int = saved_index_val.?.toUnsignedInt(mod);
|
||||||
|
assert(saved_index_int <= sema.comptime_err_ret_trace.items.len);
|
||||||
|
sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
|
||||||
|
if (!start_block.ownerModule().error_tracing) return;
|
||||||
|
|
||||||
assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere
|
assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere
|
||||||
|
|
||||||
const operand = try sema.resolveInstAllowNone(inst_data.operand);
|
|
||||||
return sema.popErrorReturnTrace(start_block, src, operand, saved_index);
|
return sema.popErrorReturnTrace(start_block, src, operand, saved_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19319,10 +19388,16 @@ fn analyzeRet(
|
|||||||
|
|
||||||
if (block.inlining) |inlining| {
|
if (block.inlining) |inlining| {
|
||||||
if (block.is_comptime) {
|
if (block.is_comptime) {
|
||||||
_ = try sema.resolveConstValue(block, src, operand, .{
|
const ret_val = try sema.resolveConstValue(block, src, operand, .{
|
||||||
.needed_comptime_reason = "value being returned at comptime must be comptime-known",
|
.needed_comptime_reason = "value being returned at comptime must be comptime-known",
|
||||||
});
|
});
|
||||||
inlining.comptime_result = operand;
|
inlining.comptime_result = operand;
|
||||||
|
|
||||||
|
if (sema.fn_ret_ty.isError(mod) and ret_val.getErrorName(mod) != .none) {
|
||||||
|
const src_decl = mod.declPtr(block.src_decl);
|
||||||
|
const src_loc = src.toSrcLoc(src_decl, mod);
|
||||||
|
try sema.comptime_err_ret_trace.append(src_loc);
|
||||||
|
}
|
||||||
return error.ComptimeReturn;
|
return error.ComptimeReturn;
|
||||||
}
|
}
|
||||||
// We are inlining a function call; rewrite the `ret` as a `break`.
|
// We are inlining a function call; rewrite the `ret` as a `break`.
|
||||||
@ -35467,6 +35542,9 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
|
|||||||
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
||||||
defer comptime_mutable_decls.deinit();
|
defer comptime_mutable_decls.deinit();
|
||||||
|
|
||||||
|
var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
|
||||||
|
defer comptime_err_ret_trace.deinit();
|
||||||
|
|
||||||
var sema: Sema = .{
|
var sema: Sema = .{
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
@ -35480,6 +35558,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
|
|||||||
.fn_ret_ty_ies = null,
|
.fn_ret_ty_ies = null,
|
||||||
.owner_func_index = .none,
|
.owner_func_index = .none,
|
||||||
.comptime_mutable_decls = &comptime_mutable_decls,
|
.comptime_mutable_decls = &comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = &comptime_err_ret_trace,
|
||||||
};
|
};
|
||||||
defer sema.deinit();
|
defer sema.deinit();
|
||||||
|
|
||||||
@ -36289,6 +36368,9 @@ fn semaStructFields(
|
|||||||
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
||||||
defer comptime_mutable_decls.deinit();
|
defer comptime_mutable_decls.deinit();
|
||||||
|
|
||||||
|
var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
|
||||||
|
defer comptime_err_ret_trace.deinit();
|
||||||
|
|
||||||
var sema: Sema = .{
|
var sema: Sema = .{
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
@ -36302,6 +36384,7 @@ fn semaStructFields(
|
|||||||
.fn_ret_ty_ies = null,
|
.fn_ret_ty_ies = null,
|
||||||
.owner_func_index = .none,
|
.owner_func_index = .none,
|
||||||
.comptime_mutable_decls = &comptime_mutable_decls,
|
.comptime_mutable_decls = &comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = &comptime_err_ret_trace,
|
||||||
};
|
};
|
||||||
defer sema.deinit();
|
defer sema.deinit();
|
||||||
|
|
||||||
@ -36543,6 +36626,9 @@ fn semaStructFieldInits(
|
|||||||
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
||||||
defer comptime_mutable_decls.deinit();
|
defer comptime_mutable_decls.deinit();
|
||||||
|
|
||||||
|
var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
|
||||||
|
defer comptime_err_ret_trace.deinit();
|
||||||
|
|
||||||
var sema: Sema = .{
|
var sema: Sema = .{
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
@ -36556,6 +36642,7 @@ fn semaStructFieldInits(
|
|||||||
.fn_ret_ty_ies = null,
|
.fn_ret_ty_ies = null,
|
||||||
.owner_func_index = .none,
|
.owner_func_index = .none,
|
||||||
.comptime_mutable_decls = &comptime_mutable_decls,
|
.comptime_mutable_decls = &comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = &comptime_err_ret_trace,
|
||||||
};
|
};
|
||||||
defer sema.deinit();
|
defer sema.deinit();
|
||||||
|
|
||||||
@ -36727,6 +36814,9 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
|
|||||||
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
|
||||||
defer comptime_mutable_decls.deinit();
|
defer comptime_mutable_decls.deinit();
|
||||||
|
|
||||||
|
var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
|
||||||
|
defer comptime_err_ret_trace.deinit();
|
||||||
|
|
||||||
var sema: Sema = .{
|
var sema: Sema = .{
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
@ -36740,6 +36830,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
|
|||||||
.fn_ret_ty_ies = null,
|
.fn_ret_ty_ies = null,
|
||||||
.owner_func_index = .none,
|
.owner_func_index = .none,
|
||||||
.comptime_mutable_decls = &comptime_mutable_decls,
|
.comptime_mutable_decls = &comptime_mutable_decls,
|
||||||
|
.comptime_err_ret_trace = &comptime_err_ret_trace,
|
||||||
};
|
};
|
||||||
defer sema.deinit();
|
defer sema.deinit();
|
||||||
|
|
||||||
|
|||||||
17
test/cases/compile_errors/comptime_err_ret_trace.zig
Normal file
17
test/cases/compile_errors/comptime_err_ret_trace.zig
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
fn inner() !void {
|
||||||
|
return error.SomethingBadHappened;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outer() !void {
|
||||||
|
return inner();
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
outer() catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
//
|
||||||
|
// :10:19: error: caught unexpected error 'SomethingBadHappened'
|
||||||
|
// :2:18: note: error returned here
|
||||||
|
// :6:5: note: error returned here
|
||||||
@ -19,4 +19,9 @@ pub export fn entry() void {
|
|||||||
// target=native
|
// target=native
|
||||||
//
|
//
|
||||||
// :9:48: error: caught unexpected error 'InvalidVersion'
|
// :9:48: error: caught unexpected error 'InvalidVersion'
|
||||||
|
// :?:?: note: error returned here
|
||||||
|
// :?:?: note: error returned here
|
||||||
|
// :?:?: note: error returned here
|
||||||
|
// :?:?: note: error returned here
|
||||||
|
// :?:?: note: error returned here
|
||||||
// :12:37: note: called from here
|
// :12:37: note: called from here
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user