mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Merge pull request #23907 from mlugg/ref-trace
compiler: reference trace fixes
This commit is contained in:
commit
9064907b34
29 changed files with 253 additions and 150 deletions
|
|
@ -750,7 +750,7 @@ fn runStepNames(
|
|||
if (run.prominent_compile_errors and total_compile_errors > 0) {
|
||||
for (step_stack.keys()) |s| {
|
||||
if (s.result_error_bundle.errorMessageCount() > 0) {
|
||||
s.result_error_bundle.renderToStdErr(.{ .ttyconf = ttyconf, .include_reference_trace = (b.reference_trace orelse 0) > 0 });
|
||||
s.result_error_bundle.renderToStdErr(.{ .ttyconf = ttyconf });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1129,11 +1129,7 @@ fn workerMakeOneStep(
|
|||
defer std.debug.unlockStdErr();
|
||||
|
||||
const gpa = b.allocator;
|
||||
const options: std.zig.ErrorBundle.RenderOptions = .{
|
||||
.ttyconf = run.ttyconf,
|
||||
.include_reference_trace = (b.reference_trace orelse 0) > 0,
|
||||
};
|
||||
printErrorMessages(gpa, s, options, run.stderr, run.prominent_compile_errors) catch {};
|
||||
printErrorMessages(gpa, s, .{ .ttyconf = run.ttyconf }, run.stderr, run.prominent_compile_errors) catch {};
|
||||
}
|
||||
|
||||
handle_result: {
|
||||
|
|
|
|||
|
|
@ -3328,7 +3328,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
|||
if (comp.zcu) |zcu| zcu_errors: {
|
||||
for (zcu.failed_files.keys(), zcu.failed_files.values()) |file, error_msg| {
|
||||
if (error_msg) |msg| {
|
||||
try addModuleErrorMsg(zcu, &bundle, msg.*);
|
||||
try addModuleErrorMsg(zcu, &bundle, msg.*, false);
|
||||
} else {
|
||||
// Must be ZIR or Zoir errors. Note that this may include AST errors.
|
||||
_ = try file.getTree(gpa); // Tree must be loaded.
|
||||
|
|
@ -3378,6 +3378,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
|||
break :s entries.slice();
|
||||
};
|
||||
defer sorted_failed_analysis.deinit(gpa);
|
||||
var added_any_analysis_error = false;
|
||||
for (sorted_failed_analysis.items(.key), sorted_failed_analysis.items(.value)) |anal_unit, error_msg| {
|
||||
if (comp.incremental) {
|
||||
const refs = try zcu.resolveReferences();
|
||||
|
|
@ -3389,7 +3390,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
|||
zcu.fmtAnalUnit(anal_unit),
|
||||
});
|
||||
|
||||
try addModuleErrorMsg(zcu, &bundle, error_msg.*);
|
||||
try addModuleErrorMsg(zcu, &bundle, error_msg.*, added_any_analysis_error);
|
||||
added_any_analysis_error = true;
|
||||
|
||||
if (zcu.cimport_errors.get(anal_unit)) |errors| {
|
||||
for (errors.getMessages()) |err_msg_index| {
|
||||
const err_msg = errors.getErrorMessage(err_msg_index);
|
||||
|
|
@ -3412,13 +3415,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
|||
}
|
||||
}
|
||||
for (zcu.failed_codegen.values()) |error_msg| {
|
||||
try addModuleErrorMsg(zcu, &bundle, error_msg.*);
|
||||
try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
|
||||
}
|
||||
for (zcu.failed_types.values()) |error_msg| {
|
||||
try addModuleErrorMsg(zcu, &bundle, error_msg.*);
|
||||
try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
|
||||
}
|
||||
for (zcu.failed_exports.values()) |value| {
|
||||
try addModuleErrorMsg(zcu, &bundle, value.*);
|
||||
try addModuleErrorMsg(zcu, &bundle, value.*, false);
|
||||
}
|
||||
|
||||
const actual_error_count = zcu.intern_pool.global_error_set.getNamesFromMainThread().len;
|
||||
|
|
@ -3527,7 +3530,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
|||
// We don't actually include the error here if `!include_compile_log_sources`.
|
||||
// The sorting above was still necessary, though, to get `log_text` in the right order.
|
||||
if (include_compile_log_sources) {
|
||||
try addModuleErrorMsg(zcu, &bundle, messages.items[0]);
|
||||
try addModuleErrorMsg(zcu, &bundle, messages.items[0], false);
|
||||
}
|
||||
|
||||
break :compile_log_text try log_text.toOwnedSlice(gpa);
|
||||
|
|
@ -3631,10 +3634,14 @@ pub const ErrorNoteHashContext = struct {
|
|||
}
|
||||
};
|
||||
|
||||
const default_reference_trace_len = 2;
|
||||
pub fn addModuleErrorMsg(
|
||||
zcu: *Zcu,
|
||||
eb: *ErrorBundle.Wip,
|
||||
module_err_msg: Zcu.ErrorMsg,
|
||||
/// If `-freference-trace` is not specified, we only want to show the one reference trace.
|
||||
/// So, this is whether we have already emitted an error with a reference trace.
|
||||
already_added_error: bool,
|
||||
) !void {
|
||||
const gpa = eb.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
|
@ -3657,45 +3664,44 @@ pub fn addModuleErrorMsg(
|
|||
var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty;
|
||||
defer ref_traces.deinit(gpa);
|
||||
|
||||
if (module_err_msg.reference_trace_root.unwrap()) |rt_root| {
|
||||
rt: {
|
||||
const rt_root = module_err_msg.reference_trace_root.unwrap() orelse break :rt;
|
||||
const max_references = zcu.comp.reference_trace orelse refs: {
|
||||
if (already_added_error) break :rt;
|
||||
break :refs default_reference_trace_len;
|
||||
};
|
||||
|
||||
const all_references = try zcu.resolveReferences();
|
||||
|
||||
var seen: std.AutoHashMapUnmanaged(InternPool.AnalUnit, void) = .empty;
|
||||
defer seen.deinit(gpa);
|
||||
|
||||
const max_references = zcu.comp.reference_trace orelse Sema.default_reference_trace_len;
|
||||
|
||||
var referenced_by = rt_root;
|
||||
while (all_references.get(referenced_by)) |maybe_ref| {
|
||||
const ref = maybe_ref orelse break;
|
||||
const gop = try seen.getOrPut(gpa, ref.referencer);
|
||||
if (gop.found_existing) break;
|
||||
if (ref_traces.items.len < max_references) skip: {
|
||||
const src = ref.src.upgrade(zcu);
|
||||
const source = try src.file_scope.getSource(gpa);
|
||||
const span = try src.span(gpa);
|
||||
const loc = std.zig.findLineColumn(source.bytes, span.main);
|
||||
const rt_file_path = try src.file_scope.fullPath(gpa);
|
||||
defer gpa.free(rt_file_path);
|
||||
const name = switch (ref.referencer.unwrap()) {
|
||||
if (ref_traces.items.len < max_references) {
|
||||
var last_call_src = ref.src;
|
||||
var opt_inline_frame = ref.inline_frame;
|
||||
while (opt_inline_frame.unwrap()) |inline_frame| {
|
||||
const f = inline_frame.ptr(zcu).*;
|
||||
const func_nav = ip.indexToKey(f.callee).func.owner_nav;
|
||||
const func_name = ip.getNav(func_nav).name.toSlice(ip);
|
||||
try addReferenceTraceFrame(zcu, eb, &ref_traces, func_name, last_call_src, true);
|
||||
last_call_src = f.call_src;
|
||||
opt_inline_frame = f.parent;
|
||||
}
|
||||
const root_name: ?[]const u8 = switch (ref.referencer.unwrap()) {
|
||||
.@"comptime" => "comptime",
|
||||
.nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip),
|
||||
.type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
|
||||
.func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip),
|
||||
.memoized_state => break :skip,
|
||||
.memoized_state => null,
|
||||
};
|
||||
try ref_traces.append(gpa, .{
|
||||
.decl_name = try eb.addString(name),
|
||||
.src_loc = try eb.addSourceLocation(.{
|
||||
.src_path = try eb.addString(rt_file_path),
|
||||
.span_start = span.start,
|
||||
.span_main = span.main,
|
||||
.span_end = span.end,
|
||||
.line = @intCast(loc.line),
|
||||
.column = @intCast(loc.column),
|
||||
.source_line = 0,
|
||||
}),
|
||||
});
|
||||
if (root_name) |n| {
|
||||
try addReferenceTraceFrame(zcu, eb, &ref_traces, n, last_call_src, false);
|
||||
}
|
||||
}
|
||||
referenced_by = ref.referencer;
|
||||
}
|
||||
|
|
@ -3775,6 +3781,35 @@ pub fn addModuleErrorMsg(
|
|||
}
|
||||
}
|
||||
|
||||
fn addReferenceTraceFrame(
|
||||
zcu: *Zcu,
|
||||
eb: *ErrorBundle.Wip,
|
||||
ref_traces: *std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace),
|
||||
name: []const u8,
|
||||
lazy_src: Zcu.LazySrcLoc,
|
||||
inlined: bool,
|
||||
) !void {
|
||||
const gpa = zcu.gpa;
|
||||
const src = lazy_src.upgrade(zcu);
|
||||
const source = try src.file_scope.getSource(gpa);
|
||||
const span = try src.span(gpa);
|
||||
const loc = std.zig.findLineColumn(source.bytes, span.main);
|
||||
const rt_file_path = try src.file_scope.fullPath(gpa);
|
||||
defer gpa.free(rt_file_path);
|
||||
try ref_traces.append(gpa, .{
|
||||
.decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }),
|
||||
.src_loc = try eb.addSourceLocation(.{
|
||||
.src_path = try eb.addString(rt_file_path),
|
||||
.span_start = span.start,
|
||||
.span_main = span.main,
|
||||
.span_end = span.end,
|
||||
.line = @intCast(loc.line),
|
||||
.column = @intCast(loc.column),
|
||||
.source_line = 0,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void {
|
||||
const gpa = eb.gpa;
|
||||
const src_path = try file.fullPath(gpa);
|
||||
|
|
|
|||
126
src/Sema.zig
126
src/Sema.zig
|
|
@ -191,7 +191,6 @@ const LowerZon = @import("Sema/LowerZon.zig");
|
|||
const arith = @import("Sema/arith.zig");
|
||||
|
||||
pub const default_branch_quota = 1000;
|
||||
pub const default_reference_trace_len = 2;
|
||||
|
||||
pub const InferredErrorSet = struct {
|
||||
/// The function body from which this error set originates.
|
||||
|
|
@ -445,10 +444,31 @@ pub const Block = struct {
|
|||
pub const Inlining = struct {
|
||||
call_block: *Block,
|
||||
call_src: LazySrcLoc,
|
||||
has_comptime_args: bool,
|
||||
func: InternPool.Index,
|
||||
|
||||
/// Populated lazily by `refFrame`.
|
||||
ref_frame: Zcu.InlineReferenceFrame.Index.Optional = .none,
|
||||
|
||||
/// If `true`, the following fields are `undefined`. This doesn't represent a true inline
|
||||
/// call, but rather a generic call analyzing the instantiation's generic type bodies.
|
||||
is_generic_instantiation: bool,
|
||||
|
||||
has_comptime_args: bool,
|
||||
comptime_result: Air.Inst.Ref,
|
||||
merges: Merges,
|
||||
|
||||
fn refFrame(inlining: *Inlining, zcu: *Zcu) Allocator.Error!Zcu.InlineReferenceFrame.Index {
|
||||
if (inlining.ref_frame == .none) {
|
||||
inlining.ref_frame = (try zcu.addInlineReferenceFrame(.{
|
||||
.callee = inlining.func,
|
||||
.call_src = inlining.call_src,
|
||||
.parent = if (inlining.call_block.inlining) |parent_inlining| p: {
|
||||
break :p (try parent_inlining.refFrame(zcu)).toOptional();
|
||||
} else .none,
|
||||
})).toOptional();
|
||||
}
|
||||
return inlining.ref_frame.unwrap().?;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Merges = struct {
|
||||
|
|
@ -2580,7 +2600,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
|
|||
if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) {
|
||||
var wip_errors: std.zig.ErrorBundle.Wip = undefined;
|
||||
wip_errors.init(gpa) catch @panic("out of memory");
|
||||
Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*) catch @panic("out of memory");
|
||||
Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory");
|
||||
std.debug.print("compile error during Sema:\n", .{});
|
||||
var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
|
||||
error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
|
||||
|
|
@ -2590,20 +2610,17 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
|
|||
if (block) |start_block| {
|
||||
var block_it = start_block;
|
||||
while (block_it.inlining) |inlining| {
|
||||
try sema.errNote(
|
||||
inlining.call_src,
|
||||
err_msg,
|
||||
"called from here",
|
||||
.{},
|
||||
);
|
||||
const note_str = note: {
|
||||
if (inlining.is_generic_instantiation) break :note "generic function instantiated here";
|
||||
if (inlining.call_block.isComptime()) break :note "called at comptime here";
|
||||
break :note "called inline here";
|
||||
};
|
||||
try sema.errNote(inlining.call_src, err_msg, "{s}", .{note_str});
|
||||
block_it = inlining.call_block;
|
||||
}
|
||||
}
|
||||
|
||||
const use_ref_trace = if (zcu.comp.reference_trace) |n| n > 0 else zcu.failed_analysis.count() == 0;
|
||||
if (use_ref_trace) {
|
||||
err_msg.reference_trace_root = sema.owner.toOptional();
|
||||
}
|
||||
|
||||
const gop = try zcu.failed_analysis.getOrPut(gpa, sema.owner);
|
||||
if (gop.found_existing) {
|
||||
|
|
@ -4291,7 +4308,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
|
|||
if (zcu.intern_pool.isFuncBody(val)) {
|
||||
const ty = Type.fromInterned(zcu.intern_pool.typeOf(val));
|
||||
if (try ty.fnHasRuntimeBitsSema(pt)) {
|
||||
try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = val }));
|
||||
try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = val }));
|
||||
try zcu.ensureFuncBodyAnalysisQueued(val);
|
||||
}
|
||||
}
|
||||
|
|
@ -6619,7 +6636,7 @@ pub fn analyzeExport(
|
|||
if (options.linkage == .internal)
|
||||
return;
|
||||
|
||||
try sema.ensureNavResolved(src, orig_nav_index, .fully);
|
||||
try sema.ensureNavResolved(block, src, orig_nav_index, .fully);
|
||||
|
||||
const exported_nav_index = switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) {
|
||||
.variable => |v| v.owner_nav,
|
||||
|
|
@ -6648,7 +6665,7 @@ pub fn analyzeExport(
|
|||
return sema.fail(block, src, "export target cannot be extern", .{});
|
||||
}
|
||||
|
||||
try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index);
|
||||
try sema.maybeQueueFuncBodyAnalysis(block, src, exported_nav_index);
|
||||
|
||||
try sema.exports.append(gpa, .{
|
||||
.opts = options,
|
||||
|
|
@ -6896,7 +6913,7 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
|||
.no_embedded_nulls,
|
||||
);
|
||||
const nav_index = try sema.lookupIdentifier(block, src, decl_name);
|
||||
return sema.analyzeNavRef(src, nav_index);
|
||||
return sema.analyzeNavRef(block, src, nav_index);
|
||||
}
|
||||
|
||||
fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
|
|
@ -6992,7 +7009,7 @@ fn lookupInNamespace(
|
|||
}
|
||||
|
||||
for (usingnamespaces.items) |sub_ns_nav| {
|
||||
try sema.ensureNavResolved(src, sub_ns_nav, .fully);
|
||||
try sema.ensureNavResolved(block, src, sub_ns_nav, .fully);
|
||||
const sub_ns_ty = Type.fromInterned(ip.getNav(sub_ns_nav).status.fully_resolved.val);
|
||||
const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu));
|
||||
try checked_namespaces.put(gpa, sub_ns, {});
|
||||
|
|
@ -7724,10 +7741,11 @@ fn analyzeCall(
|
|||
var generic_inlining: Block.Inlining = if (func_ty_info.is_generic) .{
|
||||
.call_block = block,
|
||||
.call_src = call_src,
|
||||
.has_comptime_args = false, // unused by error reporting
|
||||
.func = .none, // unused by error reporting
|
||||
.comptime_result = .none, // unused by error reporting
|
||||
.merges = undefined, // unused because we'll never `return`
|
||||
.func = func_val.?.toIntern(),
|
||||
.is_generic_instantiation = true, // this allows the following fields to be `undefined`
|
||||
.has_comptime_args = undefined,
|
||||
.comptime_result = undefined,
|
||||
.merges = undefined,
|
||||
} else undefined;
|
||||
|
||||
// This is the block in which we evaluate generic function components: that is, generic parameter
|
||||
|
|
@ -8003,7 +8021,7 @@ fn analyzeCall(
|
|||
ref_func: {
|
||||
const runtime_func_val = try sema.resolveValue(runtime_func) orelse break :ref_func;
|
||||
if (!ip.isFuncBody(runtime_func_val.toIntern())) break :ref_func;
|
||||
try sema.addReferenceEntry(call_src, .wrap(.{ .func = runtime_func_val.toIntern() }));
|
||||
try sema.addReferenceEntry(block, call_src, .wrap(.{ .func = runtime_func_val.toIntern() }));
|
||||
try zcu.ensureFuncBodyAnalysisQueued(runtime_func_val.toIntern());
|
||||
}
|
||||
|
||||
|
|
@ -8205,10 +8223,11 @@ fn analyzeCall(
|
|||
var inlining: Block.Inlining = .{
|
||||
.call_block = block,
|
||||
.call_src = call_src,
|
||||
.func = func_val.?.toIntern(),
|
||||
.is_generic_instantiation = false,
|
||||
.has_comptime_args = for (args) |a| {
|
||||
if (try sema.isComptimeKnown(a)) break true;
|
||||
} else false,
|
||||
.func = func_val.?.toIntern(),
|
||||
.comptime_result = undefined,
|
||||
.merges = .{
|
||||
.block_inst = block_inst,
|
||||
|
|
@ -8239,7 +8258,10 @@ fn analyzeCall(
|
|||
if (!inlining.has_comptime_args) {
|
||||
var block_it = block;
|
||||
while (block_it.inlining) |parent_inlining| {
|
||||
if (!parent_inlining.has_comptime_args and parent_inlining.func == func_val.?.toIntern()) {
|
||||
if (!parent_inlining.is_generic_instantiation and
|
||||
!parent_inlining.has_comptime_args and
|
||||
parent_inlining.func == func_val.?.toIntern())
|
||||
{
|
||||
return sema.fail(block, call_src, "inline call is recursive", .{});
|
||||
}
|
||||
block_it = parent_inlining.call_block;
|
||||
|
|
@ -17258,7 +17280,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
|
|||
.@"comptime" => |index| return Air.internedToRef(index),
|
||||
.runtime => |index| index,
|
||||
.nav_val => |nav| return sema.analyzeNavVal(block, src, nav),
|
||||
.nav_ref => |nav| return sema.analyzeNavRef(src, nav),
|
||||
.nav_ref => |nav| return sema.analyzeNavRef(block, src, nav),
|
||||
};
|
||||
|
||||
// The comptime case is handled already above. Runtime case below.
|
||||
|
|
@ -18411,7 +18433,7 @@ fn typeInfoNamespaceDecls(
|
|||
if (zcu.analysis_in_progress.contains(.wrap(.{ .nav_val = nav }))) {
|
||||
continue;
|
||||
}
|
||||
try sema.ensureNavResolved(src, nav, .fully);
|
||||
try sema.ensureNavResolved(block, src, nav, .fully);
|
||||
const namespace_ty = Type.fromInterned(ip.getNav(nav).status.fully_resolved.val);
|
||||
try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces);
|
||||
}
|
||||
|
|
@ -19443,6 +19465,7 @@ fn analyzeRet(
|
|||
};
|
||||
|
||||
if (block.inlining) |inlining| {
|
||||
assert(!inlining.is_generic_instantiation); // can't `return` in a generic param/ret ty expr
|
||||
if (block.isComptime()) {
|
||||
const ret_val = try sema.resolveConstValue(block, operand_src, operand, null);
|
||||
inlining.comptime_result = operand;
|
||||
|
|
@ -27936,7 +27959,7 @@ fn namespaceLookupRef(
|
|||
decl_name: InternPool.NullTerminatedString,
|
||||
) CompileError!?Air.Inst.Ref {
|
||||
const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null;
|
||||
return try sema.analyzeNavRef(src, nav);
|
||||
return try sema.analyzeNavRef(block, src, nav);
|
||||
}
|
||||
|
||||
fn namespaceLookupVal(
|
||||
|
|
@ -29099,7 +29122,7 @@ fn coerceExtra(
|
|||
.@"extern" => |e| e.owner_nav,
|
||||
else => unreachable,
|
||||
};
|
||||
const inst_as_ptr = try sema.analyzeNavRef(inst_src, fn_nav);
|
||||
const inst_as_ptr = try sema.analyzeNavRef(block, inst_src, fn_nav);
|
||||
return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
|
||||
}
|
||||
|
||||
|
|
@ -30752,7 +30775,7 @@ fn coerceVarArgParam(
|
|||
.@"fn" => fn_ptr: {
|
||||
const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
|
||||
const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
|
||||
break :fn_ptr try sema.analyzeNavRef(inst_src, fn_nav);
|
||||
break :fn_ptr try sema.analyzeNavRef(block, inst_src, fn_nav);
|
||||
},
|
||||
.array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
|
||||
.float => float: {
|
||||
|
|
@ -31762,12 +31785,13 @@ fn analyzeNavVal(
|
|||
src: LazySrcLoc,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const ref = try sema.analyzeNavRefInner(src, nav_index, false);
|
||||
const ref = try sema.analyzeNavRefInner(block, src, nav_index, false);
|
||||
return sema.analyzeLoad(block, src, ref, src);
|
||||
}
|
||||
|
||||
fn addReferenceEntry(
|
||||
sema: *Sema,
|
||||
opt_block: ?*Block,
|
||||
src: LazySrcLoc,
|
||||
referenced_unit: AnalUnit,
|
||||
) !void {
|
||||
|
|
@ -31775,10 +31799,12 @@ fn addReferenceEntry(
|
|||
if (!zcu.comp.incremental and zcu.comp.reference_trace == 0) return;
|
||||
const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);
|
||||
if (gop.found_existing) return;
|
||||
// TODO: we need to figure out how to model inline calls here.
|
||||
// They aren't references in the analysis sense, but ought to show up in the reference trace!
|
||||
// Would representing inline calls in the reference table cause excessive memory usage?
|
||||
try zcu.addUnitReference(sema.owner, referenced_unit, src);
|
||||
try zcu.addUnitReference(sema.owner, referenced_unit, src, inline_frame: {
|
||||
const block = opt_block orelse break :inline_frame .none;
|
||||
const inlining = block.inlining orelse break :inline_frame .none;
|
||||
const frame = try inlining.refFrame(zcu);
|
||||
break :inline_frame frame.toOptional();
|
||||
});
|
||||
}
|
||||
|
||||
pub fn addTypeReferenceEntry(
|
||||
|
|
@ -31797,7 +31823,7 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M
|
|||
const pt = sema.pt;
|
||||
|
||||
const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
|
||||
try sema.addReferenceEntry(src, unit);
|
||||
try sema.addReferenceEntry(null, src, unit);
|
||||
try sema.declareDependency(.{ .memoized_state = stage });
|
||||
|
||||
if (pt.zcu.analysis_in_progress.contains(unit)) {
|
||||
|
|
@ -31806,7 +31832,7 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M
|
|||
try pt.ensureMemoizedStateUpToDate(stage);
|
||||
}
|
||||
|
||||
pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {
|
||||
pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
|
@ -31829,7 +31855,7 @@ pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav
|
|||
.type => .{ .nav_ty = nav_index },
|
||||
.fully => .{ .nav_val = nav_index },
|
||||
});
|
||||
try sema.addReferenceEntry(src, anal_unit);
|
||||
try sema.addReferenceEntry(block, src, anal_unit);
|
||||
|
||||
if (zcu.analysis_in_progress.contains(anal_unit)) {
|
||||
return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{
|
||||
|
|
@ -31859,25 +31885,25 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
|
|||
} }));
|
||||
}
|
||||
|
||||
fn analyzeNavRef(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref {
|
||||
return sema.analyzeNavRefInner(src, nav_index, true);
|
||||
fn analyzeNavRef(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref {
|
||||
return sema.analyzeNavRefInner(block, src, nav_index, true);
|
||||
}
|
||||
|
||||
/// Analyze a reference to the `Nav` at the given index. Ensures the underlying `Nav` is analyzed.
|
||||
/// If this pointer will be used directly, `is_ref` must be `true`.
|
||||
/// If this pointer will be immediately loaded (i.e. a `decl_val` instruction), `is_ref` must be `false`.
|
||||
fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.Nav.Index, is_ref: bool) CompileError!Air.Inst.Ref {
|
||||
fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_index: InternPool.Nav.Index, is_ref: bool) CompileError!Air.Inst.Ref {
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
try sema.ensureNavResolved(src, orig_nav_index, if (is_ref) .type else .fully);
|
||||
try sema.ensureNavResolved(block, src, orig_nav_index, if (is_ref) .type else .fully);
|
||||
|
||||
const nav_index = nav: {
|
||||
if (ip.getNav(orig_nav_index).isExternOrFn(ip)) {
|
||||
// Getting a pointer to this `Nav` might mean we actually get a pointer to something else!
|
||||
// We need to resolve the value to know for sure.
|
||||
if (is_ref) try sema.ensureNavResolved(src, orig_nav_index, .fully);
|
||||
if (is_ref) try sema.ensureNavResolved(block, src, orig_nav_index, .fully);
|
||||
switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) {
|
||||
.func => |f| break :nav f.owner_nav,
|
||||
.@"extern" => |e| break :nav e.owner_nav,
|
||||
|
|
@ -31901,7 +31927,7 @@ fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.N
|
|||
},
|
||||
});
|
||||
if (is_ref) {
|
||||
try sema.maybeQueueFuncBodyAnalysis(src, nav_index);
|
||||
try sema.maybeQueueFuncBodyAnalysis(block, src, nav_index);
|
||||
}
|
||||
return Air.internedToRef((try pt.intern(.{ .ptr = .{
|
||||
.ty = ptr_ty.toIntern(),
|
||||
|
|
@ -31910,7 +31936,7 @@ fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.N
|
|||
} })));
|
||||
}
|
||||
|
||||
fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void {
|
||||
fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void {
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
|
@ -31918,16 +31944,16 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPoo
|
|||
// To avoid forcing too much resolution, let's first resolve the type, and check if it's a function.
|
||||
// If it is, we can resolve the *value*, and queue analysis as needed.
|
||||
|
||||
try sema.ensureNavResolved(src, nav_index, .type);
|
||||
try sema.ensureNavResolved(block, src, nav_index, .type);
|
||||
const nav_ty: Type = .fromInterned(ip.getNav(nav_index).typeOf(ip));
|
||||
if (nav_ty.zigTypeTag(zcu) != .@"fn") return;
|
||||
if (!try nav_ty.fnHasRuntimeBitsSema(pt)) return;
|
||||
|
||||
try sema.ensureNavResolved(src, nav_index, .fully);
|
||||
try sema.ensureNavResolved(block, src, nav_index, .fully);
|
||||
const nav_val = zcu.navValue(nav_index);
|
||||
if (!ip.isFuncBody(nav_val.toIntern())) return;
|
||||
|
||||
try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() }));
|
||||
try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = nav_val.toIntern() }));
|
||||
try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern());
|
||||
}
|
||||
|
||||
|
|
@ -31943,8 +31969,8 @@ fn analyzeRef(
|
|||
|
||||
if (try sema.resolveValue(operand)) |val| {
|
||||
switch (zcu.intern_pool.indexToKey(val.toIntern())) {
|
||||
.@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav),
|
||||
.func => |f| return sema.analyzeNavRef(src, f.owner_nav),
|
||||
.@"extern" => |e| return sema.analyzeNavRef(block, src, e.owner_nav),
|
||||
.func => |f| return sema.analyzeNavRef(block, src, f.owner_nav),
|
||||
else => return uavRef(sema, val.toIntern()),
|
||||
}
|
||||
}
|
||||
|
|
@ -35508,7 +35534,7 @@ fn resolveInferredErrorSet(
|
|||
}
|
||||
// In this case we are dealing with the actual InferredErrorSet object that
|
||||
// corresponds to the function, not one created to track an inline/comptime call.
|
||||
try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index }));
|
||||
try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = func_index }));
|
||||
try pt.ensureFuncBodyUpToDate(func_index);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ fn loadComptimePtrInner(
|
|||
|
||||
const base_val: MutableValue = switch (ptr.base_addr) {
|
||||
.nav => |nav| val: {
|
||||
try sema.ensureNavResolved(src, nav, .fully);
|
||||
try sema.ensureNavResolved(block, src, nav, .fully);
|
||||
const val = ip.getNav(nav).status.fully_resolved.val;
|
||||
switch (ip.indexToKey(val)) {
|
||||
.variable => return .runtime_load,
|
||||
|
|
|
|||
80
src/Zcu.zig
80
src/Zcu.zig
|
|
@ -215,6 +215,9 @@ all_references: std.ArrayListUnmanaged(Reference) = .empty,
|
|||
/// Freelist of indices in `all_references`.
|
||||
free_references: std.ArrayListUnmanaged(u32) = .empty,
|
||||
|
||||
inline_reference_frames: std.ArrayListUnmanaged(InlineReferenceFrame) = .empty,
|
||||
free_inline_reference_frames: std.ArrayListUnmanaged(InlineReferenceFrame.Index) = .empty,
|
||||
|
||||
/// Key is the `AnalUnit` *performing* the reference. This representation allows
|
||||
/// incremental updates to quickly delete references caused by a specific `AnalUnit`.
|
||||
/// Value is index into `all_type_reference` of the first reference triggered by the unit.
|
||||
|
|
@ -583,6 +586,42 @@ pub const Reference = struct {
|
|||
next: u32,
|
||||
/// The source location of the reference.
|
||||
src: LazySrcLoc,
|
||||
/// If not `.none`, this is the index of the `InlineReferenceFrame` which should appear
|
||||
/// between the referencer and `referenced` in the reference trace. These frames represent
|
||||
/// inline calls, which do not create actual references (since they happen in the caller's
|
||||
/// `AnalUnit`), but do show in the reference trace.
|
||||
inline_frame: InlineReferenceFrame.Index.Optional,
|
||||
};
|
||||
|
||||
pub const InlineReferenceFrame = struct {
|
||||
/// The inline *callee*; that is, the function which was called inline.
|
||||
/// The *caller* is either `parent`, or else the unit causing the original `Reference`.
|
||||
callee: InternPool.Index,
|
||||
/// The source location of the inline call, in the *caller*.
|
||||
call_src: LazySrcLoc,
|
||||
/// If not `.none`, a frame which should appear directly below this one.
|
||||
/// This will be the "parent" inline call; this frame's `callee` is our caller.
|
||||
parent: InlineReferenceFrame.Index.Optional,
|
||||
|
||||
pub const Index = enum(u32) {
|
||||
_,
|
||||
pub fn ptr(idx: Index, zcu: *Zcu) *InlineReferenceFrame {
|
||||
return &zcu.inline_reference_frames.items[@intFromEnum(idx)];
|
||||
}
|
||||
pub fn toOptional(idx: Index) Optional {
|
||||
return @enumFromInt(@intFromEnum(idx));
|
||||
}
|
||||
pub const Optional = enum(u32) {
|
||||
none = std.math.maxInt(u32),
|
||||
_,
|
||||
pub fn unwrap(opt: Optional) ?Index {
|
||||
return switch (opt) {
|
||||
.none => null,
|
||||
_ => @enumFromInt(@intFromEnum(opt)),
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pub const TypeReference = struct {
|
||||
|
|
@ -3440,12 +3479,28 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
|
|||
var idx = kv.value;
|
||||
|
||||
while (idx != std.math.maxInt(u32)) {
|
||||
const ref = zcu.all_references.items[idx];
|
||||
zcu.free_references.append(gpa, idx) catch {
|
||||
// This space will be reused eventually, so we need not propagate this error.
|
||||
// Just leak it for now, and let GC reclaim it later on.
|
||||
break :unit_refs;
|
||||
};
|
||||
idx = zcu.all_references.items[idx].next;
|
||||
idx = ref.next;
|
||||
|
||||
var opt_inline_frame = ref.inline_frame;
|
||||
while (opt_inline_frame.unwrap()) |inline_frame| {
|
||||
// The same inline frame could be used multiple times by one unit. We need to
|
||||
// detect this case to avoid adding it to `free_inline_reference_frames` more
|
||||
// than once. We do that by setting `parent` to itself as a marker.
|
||||
if (inline_frame.ptr(zcu).parent == inline_frame.toOptional()) break;
|
||||
zcu.free_inline_reference_frames.append(gpa, inline_frame) catch {
|
||||
// This space will be reused eventually, so we need not propagate this error.
|
||||
// Just leak it for now, and let GC reclaim it later on.
|
||||
break :unit_refs;
|
||||
};
|
||||
opt_inline_frame = inline_frame.ptr(zcu).parent;
|
||||
inline_frame.ptr(zcu).parent = inline_frame.toOptional(); // signal to code above
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3480,7 +3535,22 @@ pub fn deleteUnitCompileLogs(zcu: *Zcu, anal_unit: AnalUnit) void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit, ref_src: LazySrcLoc) Allocator.Error!void {
|
||||
pub fn addInlineReferenceFrame(zcu: *Zcu, frame: InlineReferenceFrame) Allocator.Error!Zcu.InlineReferenceFrame.Index {
|
||||
const frame_idx: InlineReferenceFrame.Index = zcu.free_inline_reference_frames.pop() orelse idx: {
|
||||
_ = try zcu.inline_reference_frames.addOne(zcu.gpa);
|
||||
break :idx @enumFromInt(zcu.inline_reference_frames.items.len - 1);
|
||||
};
|
||||
frame_idx.ptr(zcu).* = frame;
|
||||
return frame_idx;
|
||||
}
|
||||
|
||||
pub fn addUnitReference(
|
||||
zcu: *Zcu,
|
||||
src_unit: AnalUnit,
|
||||
referenced_unit: AnalUnit,
|
||||
ref_src: LazySrcLoc,
|
||||
inline_frame: InlineReferenceFrame.Index.Optional,
|
||||
) Allocator.Error!void {
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
zcu.clearCachedResolvedReferences();
|
||||
|
|
@ -3500,6 +3570,7 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit
|
|||
.referenced = referenced_unit,
|
||||
.next = if (gop.found_existing) gop.value_ptr.* else std.math.maxInt(u32),
|
||||
.src = ref_src,
|
||||
.inline_frame = inline_frame,
|
||||
};
|
||||
|
||||
gop.value_ptr.* = @intCast(ref_idx);
|
||||
|
|
@ -3828,7 +3899,10 @@ pub fn unionTagFieldIndex(zcu: *const Zcu, loaded_union: InternPool.LoadedUnionT
|
|||
|
||||
pub const ResolvedReference = struct {
|
||||
referencer: AnalUnit,
|
||||
/// If `inline_frame` is not `.none`, this is the *deepest* source location in the chain of
|
||||
/// inline calls. For source locations further up the inline call stack, consult `inline_frame`.
|
||||
src: LazySrcLoc,
|
||||
inline_frame: InlineReferenceFrame.Index.Optional,
|
||||
};
|
||||
|
||||
/// Returns a mapping from an `AnalUnit` to where it is referenced.
|
||||
|
|
@ -4037,6 +4111,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
try unit_queue.put(gpa, ref.referenced, .{
|
||||
.referencer = unit,
|
||||
.src = ref.src,
|
||||
.inline_frame = ref.inline_frame,
|
||||
});
|
||||
}
|
||||
ref_idx = ref.next;
|
||||
|
|
@ -4055,6 +4130,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
try type_queue.put(gpa, ref.referenced, .{
|
||||
.referencer = unit,
|
||||
.src = ref.src,
|
||||
.inline_frame = .none,
|
||||
});
|
||||
}
|
||||
ref_idx = ref.next;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ export fn entry() usize {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:14: error: overflow of integer type 'u16' with value '65540'
|
||||
// :1:14: note: called from here
|
||||
// :1:14: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@ pub export fn entry() void {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :11:5: error: expected 0 argument(s), found 1
|
||||
// :1:12: note: function declared here
|
||||
// :17:19: note: called from here
|
||||
// :17:19: note: called inline here
|
||||
|
|
|
|||
|
|
@ -10,4 +10,4 @@ export fn entry() usize {
|
|||
// error
|
||||
//
|
||||
// :3:16: error: division by zero here causes illegal behavior
|
||||
// :1:14: note: called from here
|
||||
// :1:14: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ pub fn bar() u8 {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :6:12: error: expected error union type, found 'u8'
|
||||
// :2:8: note: called from here
|
||||
// :2:8: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ comptime {
|
|||
//
|
||||
// :7:16: error: captured value contains reference to comptime var
|
||||
// :16:30: note: 'wrapper.ptr' points to comptime var declared here
|
||||
// :17:29: note: called from here
|
||||
// :17:29: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ export fn entry() void {
|
|||
}
|
||||
|
||||
// error
|
||||
// target=native
|
||||
//
|
||||
// :4:5: error: unreachable code
|
||||
// :4:25: note: control flow is diverted here
|
||||
// :4:25: error: aoeu
|
||||
// :1:36: note: called from here
|
||||
// :1:36: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ pub export fn entry() void {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :9:48: error: caught unexpected error 'InvalidVersion'
|
||||
// :?:?: note: error returned here
|
||||
|
|
@ -24,4 +22,4 @@ pub export fn entry() void {
|
|||
// :?:?: note: error returned here
|
||||
// :?:?: note: error returned here
|
||||
// :?:?: note: error returned here
|
||||
// :12:37: note: called from here
|
||||
// :12:37: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -25,5 +25,5 @@ fn Type(comptime n: usize) type {
|
|||
//
|
||||
// :21:16: error: evaluation exceeded 1001 backwards branches
|
||||
// :21:16: note: use @setEvalBranchQuota() to raise the branch limit from 1001
|
||||
// :16:34: note: called from here
|
||||
// :8:15: note: called from here
|
||||
// :16:34: note: called at comptime here
|
||||
// :8:15: note: generic function instantiated here
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ pub fn is(comptime id: std.builtin.TypeId) TraitFn {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :8:48: error: expected type 'type', found 'bool'
|
||||
// :5:21: note: called from here
|
||||
// :5:21: note: generic function instantiated here
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
// error
|
||||
// backend=stage2
|
||||
// target=x86_64-linux
|
||||
// output_mode=Exe
|
||||
//
|
||||
// : error: root source file struct 'tmp' has no member named 'main'
|
||||
// : note: struct declared here
|
||||
// : note: called from here
|
||||
// : note: called from here
|
||||
// : note: called inline here
|
||||
// : note: called inline here
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ comptime {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :5:17: error: missing struct field: b
|
||||
// :1:11: note: struct declared here
|
||||
// :9:15: note: called from here
|
||||
// :9:15: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ export fn entry() usize {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:14: error: overflow of integer type 'u16' with value '1800000'
|
||||
// :1:14: note: called from here
|
||||
// :1:14: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ export fn entry() usize {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:12: error: overflow of integer type 'i8' with value '128'
|
||||
// :1:14: note: called from here
|
||||
// :1:14: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -11,4 +11,4 @@ fn makeLlamas(count: usize) [count]u8 {}
|
|||
//
|
||||
// :8:30: error: unable to resolve comptime value
|
||||
// :8:30: note: array length must be comptime-known
|
||||
// :2:31: note: called from here
|
||||
// :2:31: note: generic function instantiated here
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
fn main() void {}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=x86_64-linux
|
||||
// output_mode=Exe
|
||||
//
|
||||
// : error: 'main' is not marked 'pub'
|
||||
// :1:1: note: declared here
|
||||
// : note: called from here
|
||||
// : note: called from here
|
||||
// : note: called inline here
|
||||
// : note: called inline here
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ pub export fn entry2() void {
|
|||
// error
|
||||
//
|
||||
// :5:27: error: inline call is recursive
|
||||
// :12:12: note: called from here
|
||||
// :12:12: note: called inline here
|
||||
// :24:10: error: inline call is recursive
|
||||
// :20:10: note: called from here
|
||||
// :16:11: note: called from here
|
||||
// :28:10: note: called from here
|
||||
// :20:10: note: called inline here
|
||||
// :16:11: note: called inline here
|
||||
// :28:10: note: called inline here
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ fn assert(ok: bool) void {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :10:14: error: reached unreachable code
|
||||
// :6:20: note: called from here
|
||||
// :6:20: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ comptime {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:12: error: expected type 'fn () void', found 'type'
|
||||
// :1:10: note: function return type declared here
|
||||
// :5:12: note: called from here
|
||||
// :5:12: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ var rt: u32 = undefined;
|
|||
// :10:12: note: call to function with comptime-only return type 'type' is evaluated at comptime
|
||||
// :13:10: note: return type declared here
|
||||
// :10:12: note: types are not available at runtime
|
||||
// :2:8: note: called from here
|
||||
// :2:8: note: called inline here
|
||||
// :19:8: error: unable to evaluate comptime expression
|
||||
// :19:5: note: operation is runtime due to this operand
|
||||
// :6:8: note: called at comptime from here
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@ export fn entry() void {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :13:30: error: expected type 'u32', found 'i32'
|
||||
// :13:30: note: unsigned 32-bit int cannot represent all possible signed 32-bit values
|
||||
// :17:33: note: called from here
|
||||
// :17:33: note: called inline here
|
||||
|
|
|
|||
|
|
@ -36,10 +36,9 @@ export fn d() callconv(.naked) noreturn {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
//
|
||||
// :2:5: error: local variable in naked function
|
||||
// :10:5: error: local variable in naked function
|
||||
// :23:5: error: local variable in naked function
|
||||
// :30:13: error: local variable in naked function
|
||||
// :35:12: note: called from here
|
||||
// :35:12: note: called inline here
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@ fn incr(x: *comptime_int) void {
|
|||
//
|
||||
// :8:9: error: store to comptime variable depends on runtime condition
|
||||
// :3:9: note: runtime condition here
|
||||
// :4:22: note: called from here
|
||||
// :4:22: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ export fn entry() usize {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:14: error: overflow of integer type 'u16' with value '-10'
|
||||
// :1:14: note: called from here
|
||||
// :1:14: note: called at comptime here
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ export fn entry() void {
|
|||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :4:9: error: reached unreachable code
|
||||
// :8:21: note: called from here
|
||||
// :8:21: note: called at comptime here
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue