| author | |
| committer | |
| log | 7a251c4cb8082d080e23fb86fe20be6bf4c745a4 |
| tree | 9a5ec30eed4af6f82d459ad76dd982e009e130f7 |
| parent | 232077dcf90a19316261ac5745a2a947e538c3f5 |
4 files changed, 93 insertions(+), 85 deletions(-)
src/Compilation.zig+24-23| ... | @@ -2858,51 +2858,52 @@ pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Mod | ... | @@ -2858,51 +2858,52 @@ pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Mod |
| 2858 | var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .{}; | 2858 | var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .{}; |
| 2859 | defer ref_traces.deinit(gpa); | 2859 | defer ref_traces.deinit(gpa); |
| 2860 | 2860 | ||
| 2861 | for (module_err_msg.reference_trace) |module_reference| { | 2861 | const remaining_references: ?u32 = remaining: { |
| 2862 | if (module_reference.hidden != 0) { | 2862 | if (mod.comp.reference_trace) |_| { |
| 2863 | try ref_traces.append(gpa, .{ | 2863 | if (module_err_msg.hidden_references > 0) break :remaining module_err_msg.hidden_references; |
| 2864 | .decl_name = module_reference.hidden, | 2864 | } else { |
| 2865 | .src_loc = .none, | 2865 | if (module_err_msg.reference_trace.len > 0) break :remaining 0; |
| 2866 | }); | ||
| 2867 | break; | ||
| 2868 | } else if (module_reference.decl == .none) { | ||
| 2869 | try ref_traces.append(gpa, .{ | ||
| 2870 | .decl_name = 0, | ||
| 2871 | .src_loc = .none, | ||
| 2872 | }); | ||
| 2873 | break; | ||
| 2874 | } | 2866 | } |
| 2867 | break :remaining null; | ||
| 2868 | }; | ||
| 2869 | try ref_traces.ensureTotalCapacityPrecise(gpa, module_err_msg.reference_trace.len + | ||
| 2870 | @intFromBool(remaining_references != null)); | ||
| 2871 | |||
| 2872 | for (module_err_msg.reference_trace) |module_reference| { | ||
| 2875 | const source = try module_reference.src_loc.file_scope.getSource(gpa); | 2873 | const source = try module_reference.src_loc.file_scope.getSource(gpa); |
| 2876 | const span = try module_reference.src_loc.span(gpa); | 2874 | const span = try module_reference.src_loc.span(gpa); |
| 2877 | const loc = std.zig.findLineColumn(source.bytes, span.main); | 2875 | const loc = std.zig.findLineColumn(source.bytes, span.main); |
| 2878 | const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa); | 2876 | const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa); |
| 2879 | defer gpa.free(rt_file_path); | 2877 | defer gpa.free(rt_file_path); |
| 2880 | try ref_traces.append(gpa, .{ | 2878 | ref_traces.appendAssumeCapacity(.{ |
| 2881 | .decl_name = try eb.addString(ip.stringToSliceUnwrap(module_reference.decl).?), | 2879 | .decl_name = try eb.addString(ip.stringToSlice(module_reference.decl)), |
| 2882 | .src_loc = try eb.addSourceLocation(.{ | 2880 | .src_loc = try eb.addSourceLocation(.{ |
| 2883 | .src_path = try eb.addString(rt_file_path), | 2881 | .src_path = try eb.addString(rt_file_path), |
| 2884 | .span_start = span.start, | 2882 | .span_start = span.start, |
| 2885 | .span_main = span.main, | 2883 | .span_main = span.main, |
| 2886 | .span_end = span.end, | 2884 | .span_end = span.end, |
| 2887 | .line = @as(u32, @intCast(loc.line)), | 2885 | .line = @intCast(loc.line), |
| 2888 | .column = @as(u32, @intCast(loc.column)), | 2886 | .column = @intCast(loc.column), |
| 2889 | .source_line = 0, | 2887 | .source_line = 0, |
| 2890 | }), | 2888 | }), |
| 2891 | }); | 2889 | }); |
| 2892 | } | 2890 | } |
| 2891 | if (remaining_references) |remaining| ref_traces.appendAssumeCapacity( | ||
| 2892 | .{ .decl_name = remaining, .src_loc = .none }, | ||
| 2893 | ); | ||
| 2893 | 2894 | ||
| 2894 | const src_loc = try eb.addSourceLocation(.{ | 2895 | const src_loc = try eb.addSourceLocation(.{ |
| 2895 | .src_path = try eb.addString(file_path), | 2896 | .src_path = try eb.addString(file_path), |
| 2896 | .span_start = err_span.start, | 2897 | .span_start = err_span.start, |
| 2897 | .span_main = err_span.main, | 2898 | .span_main = err_span.main, |
| 2898 | .span_end = err_span.end, | 2899 | .span_end = err_span.end, |
| 2899 | .line = @as(u32, @intCast(err_loc.line)), | 2900 | .line = @intCast(err_loc.line), |
| 2900 | .column = @as(u32, @intCast(err_loc.column)), | 2901 | .column = @intCast(err_loc.column), |
| 2901 | .source_line = if (module_err_msg.src_loc.lazy == .entire_file) | 2902 | .source_line = if (module_err_msg.src_loc.lazy == .entire_file) |
| 2902 | 0 | 2903 | 0 |
| 2903 | else | 2904 | else |
| 2904 | try eb.addString(err_loc.source_line), | 2905 | try eb.addString(err_loc.source_line), |
| 2905 | .reference_trace_len = @as(u32, @intCast(ref_traces.items.len)), | 2906 | .reference_trace_len = @intCast(ref_traces.items.len), |
| 2906 | }); | 2907 | }); |
| 2907 | 2908 | ||
| 2908 | for (ref_traces.items) |rt| { | 2909 | for (ref_traces.items) |rt| { |
| ... | @@ -2928,8 +2929,8 @@ pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Mod | ... | @@ -2928,8 +2929,8 @@ pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Mod |
| 2928 | .span_start = span.start, | 2929 | .span_start = span.start, |
| 2929 | .span_main = span.main, | 2930 | .span_main = span.main, |
| 2930 | .span_end = span.end, | 2931 | .span_end = span.end, |
| 2931 | .line = @as(u32, @intCast(loc.line)), | 2932 | .line = @intCast(loc.line), |
| 2932 | .column = @as(u32, @intCast(loc.column)), | 2933 | .column = @intCast(loc.column), |
| 2933 | .source_line = if (err_loc.eql(loc)) 0 else try eb.addString(loc.source_line), | 2934 | .source_line = if (err_loc.eql(loc)) 0 else try eb.addString(loc.source_line), |
| 2934 | }), | 2935 | }), |
| 2935 | }, .{ .eb = eb }); | 2936 | }, .{ .eb = eb }); |
| ... | @@ -2938,7 +2939,7 @@ pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Mod | ... | @@ -2938,7 +2939,7 @@ pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Mod |
| 2938 | } | 2939 | } |
| 2939 | } | 2940 | } |
| 2940 | 2941 | ||
| 2941 | const notes_len = @as(u32, @intCast(notes.entries.len)); | 2942 | const notes_len: u32 = @intCast(notes.entries.len); |
| 2942 | 2943 | ||
| 2943 | try eb.addRootErrorMessage(.{ | 2944 | try eb.addRootErrorMessage(.{ |
| 2944 | .msg = try eb.addString(module_err_msg.msg), | 2945 | .msg = try eb.addString(module_err_msg.msg), |
src/Module.zig+2-2| ... | @@ -1519,11 +1519,11 @@ pub const ErrorMsg = struct { | ... | @@ -1519,11 +1519,11 @@ pub const ErrorMsg = struct { |
| 1519 | msg: []const u8, | 1519 | msg: []const u8, |
| 1520 | notes: []ErrorMsg = &.{}, | 1520 | notes: []ErrorMsg = &.{}, |
| 1521 | reference_trace: []Trace = &.{}, | 1521 | reference_trace: []Trace = &.{}, |
| 1522 | hidden_references: u32 = 0, | ||
| 1522 | 1523 | ||
| 1523 | pub const Trace = struct { | 1524 | pub const Trace = struct { |
| 1524 | decl: InternPool.OptionalNullTerminatedString, | 1525 | decl: InternPool.NullTerminatedString, |
| 1525 | src_loc: SrcLoc, | 1526 | src_loc: SrcLoc, |
| 1526 | hidden: u32 = 0, | ||
| 1527 | }; | 1527 | }; |
| 1528 | 1528 | ||
| 1529 | pub fn create( | 1529 | pub fn create( |
src/Sema.zig+50-60| ... | @@ -2396,80 +2396,69 @@ fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) | ... | @@ -2396,80 +2396,69 @@ fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) |
| 2396 | const gpa = sema.gpa; | 2396 | const gpa = sema.gpa; |
| 2397 | const mod = sema.mod; | 2397 | const mod = sema.mod; |
| 2398 | 2398 | ||
| 2399 | if (crash_report.is_enabled and mod.comp.debug_compile_errors) { | ||
| 2400 | if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation; | ||
| 2401 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | ||
| 2402 | wip_errors.init(gpa) catch unreachable; | ||
| 2403 | Compilation.addModuleErrorMsg(mod, &wip_errors, err_msg.*) catch unreachable; | ||
| 2404 | std.debug.print("compile error during Sema:\n", .{}); | ||
| 2405 | var error_bundle = wip_errors.toOwnedBundle("") catch unreachable; | ||
| 2406 | error_bundle.renderToStdErr(.{ .ttyconf = .no_color }); | ||
| 2407 | crash_report.compilerPanic("unexpected compile error occurred", null, null); | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | ref: { | 2399 | ref: { |
| 2411 | errdefer err_msg.destroy(gpa); | 2400 | errdefer err_msg.destroy(gpa); |
| 2412 | if (err_msg.src_loc.lazy == .unneeded) { | 2401 | if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation; |
| 2413 | return error.NeededSourceLocation; | 2402 | |
| 2403 | if (crash_report.is_enabled and mod.comp.debug_compile_errors) { | ||
| 2404 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | ||
| 2405 | wip_errors.init(gpa) catch unreachable; | ||
| 2406 | Compilation.addModuleErrorMsg(mod, &wip_errors, err_msg.*) catch unreachable; | ||
| 2407 | std.debug.print("compile error during Sema:\n", .{}); | ||
| 2408 | var error_bundle = wip_errors.toOwnedBundle("") catch unreachable; | ||
| 2409 | error_bundle.renderToStdErr(.{ .ttyconf = .no_color }); | ||
| 2410 | crash_report.compilerPanic("unexpected compile error occurred", null, null); | ||
| 2414 | } | 2411 | } |
| 2412 | |||
| 2415 | try mod.failed_decls.ensureUnusedCapacity(gpa, 1); | 2413 | try mod.failed_decls.ensureUnusedCapacity(gpa, 1); |
| 2416 | try mod.failed_files.ensureUnusedCapacity(gpa, 1); | 2414 | try mod.failed_files.ensureUnusedCapacity(gpa, 1); |
| 2417 | 2415 | ||
| 2418 | var func_index: InternPool.Index = .none; | ||
| 2419 | if (block) |start_block| { | 2416 | if (block) |start_block| { |
| 2420 | var block_it = start_block; | 2417 | var block_it = start_block; |
| 2421 | while (block_it.inlining) |inlining| { | 2418 | while (block_it.inlining) |inlining| { |
| 2422 | func_index = inlining.func; | 2419 | try sema.errNote( |
| 2420 | inlining.call_block, | ||
| 2421 | inlining.call_src, | ||
| 2422 | err_msg, | ||
| 2423 | "called from here", | ||
| 2424 | .{}, | ||
| 2425 | ); | ||
| 2423 | block_it = inlining.call_block; | 2426 | block_it = inlining.call_block; |
| 2424 | try sema.errNote(block_it, inlining.call_src, err_msg, "called from here", .{}); | ||
| 2425 | } | 2427 | } |
| 2426 | } | ||
| 2427 | 2428 | ||
| 2428 | const max_references = blk: { | 2429 | const max_references = refs: { |
| 2429 | if (mod.comp.reference_trace) |num| break :blk num; | 2430 | if (mod.comp.reference_trace) |num| break :refs num; |
| 2430 | // Do not add multiple traces without explicit request. | 2431 | // Do not add multiple traces without explicit request. |
| 2431 | if (mod.failed_decls.count() != 0) break :ref; | 2432 | if (mod.failed_decls.count() > 0) break :ref; |
| 2432 | break :blk default_reference_trace_len; | 2433 | break :refs default_reference_trace_len; |
| 2433 | }; | 2434 | }; |
| 2434 | 2435 | ||
| 2435 | var referenced_by = if (sema.owner_func_index != .none) | 2436 | var referenced_by = if (sema.owner_func_index != .none) |
| 2436 | mod.funcOwnerDeclIndex(sema.owner_func_index) | 2437 | mod.funcOwnerDeclIndex(sema.owner_func_index) |
| 2437 | else | 2438 | else |
| 2438 | sema.owner_decl_index; | 2439 | sema.owner_decl_index; |
| 2439 | var reference_stack = std.ArrayList(Module.ErrorMsg.Trace).init(gpa); | 2440 | var reference_stack = std.ArrayList(Module.ErrorMsg.Trace).init(gpa); |
| 2440 | defer reference_stack.deinit(); | 2441 | defer reference_stack.deinit(); |
| 2441 | 2442 | ||
| 2442 | // Avoid infinite loops. | 2443 | // Avoid infinite loops. |
| 2443 | var seen = std.AutoHashMap(Decl.Index, void).init(gpa); | 2444 | var seen = std.AutoHashMap(Decl.Index, void).init(gpa); |
| 2444 | defer seen.deinit(); | 2445 | defer seen.deinit(); |
| 2445 | 2446 | ||
| 2446 | var cur_reference_trace: u32 = 0; | 2447 | while (mod.reference_table.get(referenced_by)) |ref| { |
| 2447 | while (sema.mod.reference_table.get(referenced_by)) |ref| : (cur_reference_trace += 1) { | 2448 | const gop = try seen.getOrPut(ref.referencer); |
| 2448 | const gop = try seen.getOrPut(ref.referencer); | 2449 | if (gop.found_existing) break; |
| 2449 | if (gop.found_existing) break; | 2450 | if (reference_stack.items.len < max_references) { |
| 2450 | if (cur_reference_trace < max_references) { | 2451 | const decl = mod.declPtr(ref.referencer); |
| 2451 | const decl = sema.mod.declPtr(ref.referencer); | 2452 | try reference_stack.append(.{ |
| 2452 | try reference_stack.append(.{ | 2453 | .decl = decl.name, |
| 2453 | .decl = decl.name.toOptional(), | 2454 | .src_loc = ref.src.toSrcLoc(decl, mod), |
| 2454 | .src_loc = ref.src.toSrcLoc(decl, mod), | 2455 | }); |
| 2455 | }); | 2456 | } |
| 2457 | referenced_by = ref.referencer; | ||
| 2456 | } | 2458 | } |
| 2457 | referenced_by = ref.referencer; | 2459 | err_msg.reference_trace = try reference_stack.toOwnedSlice(); |
| 2458 | } | 2460 | err_msg.hidden_references = @intCast(seen.count() -| max_references); |
| 2459 | if (sema.mod.comp.reference_trace == null and cur_reference_trace > 0) { | ||
| 2460 | try reference_stack.append(.{ | ||
| 2461 | .decl = .none, | ||
| 2462 | .src_loc = undefined, | ||
| 2463 | .hidden = 0, | ||
| 2464 | }); | ||
| 2465 | } else if (cur_reference_trace > max_references) { | ||
| 2466 | try reference_stack.append(.{ | ||
| 2467 | .decl = undefined, | ||
| 2468 | .src_loc = undefined, | ||
| 2469 | .hidden = cur_reference_trace - max_references, | ||
| 2470 | }); | ||
| 2471 | } | 2461 | } |
| 2472 | err_msg.reference_trace = try reference_stack.toOwnedSlice(); | ||
| 2473 | } | 2462 | } |
| 2474 | const ip = &mod.intern_pool; | 2463 | const ip = &mod.intern_pool; |
| 2475 | if (sema.owner_func_index != .none) { | 2464 | if (sema.owner_func_index != .none) { |
| ... | @@ -7399,7 +7388,8 @@ fn analyzeCall( | ... | @@ -7399,7 +7388,8 @@ fn analyzeCall( |
| 7399 | var block_it = block; | 7388 | var block_it = block; |
| 7400 | while (block_it.inlining) |parent_inlining| { | 7389 | while (block_it.inlining) |parent_inlining| { |
| 7401 | if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) { | 7390 | if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) { |
| 7402 | return sema.fail(block, call_src, "inline call is recursive", .{}); | 7391 | const err_msg = try sema.errMsg(block, call_src, "inline call is recursive", .{}); |
| 7392 | return sema.failWithOwnedErrorMsg(null, err_msg); | ||
| 7403 | } | 7393 | } |
| 7404 | block_it = parent_inlining.call_block; | 7394 | block_it = parent_inlining.call_block; |
| 7405 | } | 7395 | } |
test/cases/compile_errors/recursive_inline_fn.zig+17| ... | @@ -11,8 +11,25 @@ pub export fn entry() void { | ... | @@ -11,8 +11,25 @@ pub export fn entry() void { |
| 11 | _ = foo(x) == 20; | 11 | _ = foo(x) == 20; |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | inline fn first() void { | ||
| 15 | second(); | ||
| 16 | } | ||
| 17 | |||
| 18 | inline fn second() void { | ||
| 19 | third(); | ||
| 20 | } | ||
| 21 | |||
| 22 | inline fn third() void { | ||
| 23 | first(); | ||
| 24 | } | ||
| 25 | |||
| 26 | pub export fn entry2() void { | ||
| 27 | first(); | ||
| 28 | } | ||
| 29 | |||
| 14 | // error | 30 | // error |
| 15 | // backend=stage2 | 31 | // backend=stage2 |
| 16 | // target=native | 32 | // target=native |
| 17 | // | 33 | // |
| 18 | // :5:27: error: inline call is recursive | 34 | // :5:27: error: inline call is recursive |
| 35 | // :23:10: error: inline call is recursive |