@@ -2262,8 +2262,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2262
2262
const pt : Zcu.PerThread = .activate (zcu , .main );
2263
2263
defer pt .deactivate ();
2264
2264
2265
- zcu .compile_log_text .shrinkAndFree (gpa , 0 );
2266
-
2267
2265
zcu .skip_analysis_this_update = false ;
2268
2266
2269
2267
// Make sure std.zig is inside the import_table. We unconditionally need
@@ -3323,30 +3321,15 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3323
3321
err : * ? Error ,
3324
3322
3325
3323
const Error = @typeInfo (
3326
- @typeInfo (@TypeOf (Zcu .SrcLoc . span )).@"fn" .return_type .? ,
3324
+ @typeInfo (@TypeOf (Zcu .LazySrcLoc . lessThan )).@"fn" .return_type .? ,
3327
3325
).error_union .error_set ;
3328
3326
3329
3327
pub fn lessThan (ctx : @This (), lhs_index : usize , rhs_index : usize ) bool {
3330
- if (ctx .err .* ) | _ | return lhs_index < rhs_index ;
3331
- const lhs_src_loc = ctx .errors [lhs_index ].src_loc .upgradeOrLost (ctx .zcu ) orelse {
3332
- // LHS source location lost, so should never be referenced. Just sort it to the end.
3333
- return false ;
3334
- };
3335
- const rhs_src_loc = ctx .errors [rhs_index ].src_loc .upgradeOrLost (ctx .zcu ) orelse {
3336
- // RHS source location lost, so should never be referenced. Just sort it to the end.
3337
- return true ;
3338
- };
3339
- return if (lhs_src_loc .file_scope != rhs_src_loc .file_scope ) std .mem .order (
3340
- u8 ,
3341
- lhs_src_loc .file_scope .sub_file_path ,
3342
- rhs_src_loc .file_scope .sub_file_path ,
3343
- ).compare (.lt ) else (lhs_src_loc .span (ctx .zcu .gpa ) catch | e | {
3344
- ctx .err .* = e ;
3345
- return lhs_index < rhs_index ;
3346
- }).main < (rhs_src_loc .span (ctx .zcu .gpa ) catch | e | {
3328
+ if (ctx .err .* != null ) return lhs_index < rhs_index ;
3329
+ return ctx .errors [lhs_index ].src_loc .lessThan (ctx .errors [rhs_index ].src_loc , ctx .zcu ) catch | e | {
3347
3330
ctx .err .* = e ;
3348
3331
return lhs_index < rhs_index ;
3349
- }). main ;
3332
+ };
3350
3333
}
3351
3334
};
3352
3335
@@ -3450,28 +3433,76 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3450
3433
3451
3434
try comp .link_diags .addMessagesToBundle (& bundle , comp .bin_file );
3452
3435
3453
- if (comp .zcu ) | zcu | {
3454
- if (! zcu .skip_analysis_this_update and bundle .root_list .items .len == 0 and zcu .compile_log_sources .count () != 0 ) {
3455
- const values = zcu .compile_log_sources .values ();
3456
- // First one will be the error; subsequent ones will be notes.
3457
- const src_loc = values [0 ].src ();
3458
- const err_msg : Zcu.ErrorMsg = .{
3459
- .src_loc = src_loc ,
3460
- .msg = "found compile log statement" ,
3461
- .notes = try gpa .alloc (Zcu .ErrorMsg , zcu .compile_log_sources .count () - 1 ),
3462
- };
3463
- defer gpa .free (err_msg .notes );
3436
+ const compile_log_text : []const u8 = compile_log_text : {
3437
+ const zcu = comp .zcu orelse break :compile_log_text "" ;
3438
+ if (zcu .skip_analysis_this_update ) break :compile_log_text "" ;
3439
+ if (zcu .compile_logs .count () == 0 ) break :compile_log_text "" ;
3440
+
3441
+ // If there are no other errors, we include a "found compile log statement" error.
3442
+ // Otherwise, we just show the compile log output, with no error.
3443
+ const include_compile_log_sources = bundle .root_list .items .len == 0 ;
3444
+
3445
+ const refs = try zcu .resolveReferences ();
3446
+
3447
+ var messages : std .ArrayListUnmanaged (Zcu .ErrorMsg ) = .empty ;
3448
+ defer messages .deinit (gpa );
3449
+ for (zcu .compile_logs .keys (), zcu .compile_logs .values ()) | logging_unit , compile_log | {
3450
+ if (! refs .contains (logging_unit )) continue ;
3451
+ try messages .append (gpa , .{
3452
+ .src_loc = compile_log .src (),
3453
+ .msg = undefined , // populated later
3454
+ .notes = &.{},
3455
+ // We actually clear this later for most of these, but we populate
3456
+ // this field for now to avoid having to allocate more data to track
3457
+ // which compile log text this corresponds to.
3458
+ .reference_trace_root = logging_unit .toOptional (),
3459
+ });
3460
+ }
3464
3461
3465
- for (values [1.. ], err_msg .notes ) | src_info , * note | {
3466
- note .* = .{
3467
- .src_loc = src_info .src (),
3468
- .msg = "also here" ,
3462
+ if (messages .items .len == 0 ) break :compile_log_text "" ;
3463
+
3464
+ // Okay, there *are* referenced compile logs. Sort them into a consistent order.
3465
+
3466
+ const SortContext = struct {
3467
+ err : * ? Error ,
3468
+ zcu : * Zcu ,
3469
+ const Error = @typeInfo (
3470
+ @typeInfo (@TypeOf (Zcu .LazySrcLoc .lessThan )).@"fn" .return_type .? ,
3471
+ ).error_union .error_set ;
3472
+ fn lessThan (ctx : @This (), lhs : Zcu .ErrorMsg , rhs : Zcu .ErrorMsg ) bool {
3473
+ if (ctx .err .* != null ) return false ;
3474
+ return lhs .src_loc .lessThan (rhs .src_loc , ctx .zcu ) catch | e | {
3475
+ ctx .err .* = e ;
3476
+ return false ;
3469
3477
};
3470
3478
}
3479
+ };
3480
+ var sort_err : ? SortContext.Error = null ;
3481
+ std .mem .sort (Zcu .ErrorMsg , messages .items , @as (SortContext , .{ .err = & sort_err , .zcu = zcu }), SortContext .lessThan );
3482
+ if (sort_err ) | e | return e ;
3483
+
3484
+ var log_text : std .ArrayListUnmanaged (u8 ) = .empty ;
3485
+ defer log_text .deinit (gpa );
3486
+
3487
+ // Index 0 will be the root message; the rest will be notes.
3488
+ // Only the actual message, i.e. index 0, will retain its reference trace.
3489
+ try appendCompileLogLines (& log_text , zcu , messages .items [0 ].reference_trace_root .unwrap ().? );
3490
+ messages .items [0 ].notes = messages .items [1.. ];
3491
+ messages .items [0 ].msg = "found compile log statement" ;
3492
+ for (messages .items [1.. ]) | * note | {
3493
+ try appendCompileLogLines (& log_text , zcu , note .reference_trace_root .unwrap ().? );
3494
+ note .reference_trace_root = .none ; // notes don't have reference traces
3495
+ note .msg = "also here" ;
3496
+ }
3471
3497
3472
- try addModuleErrorMsg (zcu , & bundle , err_msg );
3498
+ // We don't actually include the error here if `!include_compile_log_sources`.
3499
+ // The sorting above was still necessary, though, to get `log_text` in the right order.
3500
+ if (include_compile_log_sources ) {
3501
+ try addModuleErrorMsg (zcu , & bundle , messages .items [0 ]);
3473
3502
}
3474
- }
3503
+
3504
+ break :compile_log_text try log_text .toOwnedSlice (gpa );
3505
+ };
3475
3506
3476
3507
// TODO: eventually, this should be behind `std.debug.runtime_safety`. But right now, this is a
3477
3508
// very common way for incremental compilation bugs to manifest, so let's always check it.
@@ -3497,10 +3528,24 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3497
3528
}
3498
3529
};
3499
3530
3500
- const compile_log_text = if (comp .zcu ) | m | m .compile_log_text .items else "" ;
3501
3531
return bundle .toOwnedBundle (compile_log_text );
3502
3532
}
3503
3533
3534
+ /// Writes all compile log lines belonging to `logging_unit` into `log_text` using `zcu.gpa`.
3535
+ fn appendCompileLogLines (log_text : * std .ArrayListUnmanaged (u8 ), zcu : * Zcu , logging_unit : InternPool .AnalUnit ) Allocator .Error ! void {
3536
+ const gpa = zcu .gpa ;
3537
+ const ip = & zcu .intern_pool ;
3538
+ var opt_line_idx = zcu .compile_logs .get (logging_unit ).? .first_line .toOptional ();
3539
+ while (opt_line_idx .unwrap ()) | line_idx | {
3540
+ const line = line_idx .get (zcu ).* ;
3541
+ opt_line_idx = line .next ;
3542
+ const line_slice = line .data .toSlice (ip );
3543
+ try log_text .ensureUnusedCapacity (gpa , line_slice .len + 1 );
3544
+ log_text .appendSliceAssumeCapacity (line_slice );
3545
+ log_text .appendAssumeCapacity ('\n ' );
3546
+ }
3547
+ }
3548
+
3504
3549
fn anyErrors (comp : * Compilation ) bool {
3505
3550
return (totalErrorCount (comp ) catch return true ) != 0 ;
3506
3551
}
0 commit comments