@@ -458,17 +458,18 @@ function show_method_candidates(io::IO, ex::MethodError, @nospecialize kwargs=()
458
458
end
459
459
end
460
460
461
+ # Contains file name and file number. Gets set when a backtrace
462
+ # or methodlist is shown. Used by the REPL to make it possible to open
463
+ # the location of a stackframe/method in the editor.
464
+ global LAST_SHOWN_LINE_INFOS = Tuple{String, Int}[]
465
+
461
466
function show_trace_entry (io, frame, n; prefix = " " )
467
+ push! (LAST_SHOWN_LINE_INFOS, (string (frame. file), frame. line))
462
468
print (io, " \n " , prefix)
463
469
show (io, frame, full_path= true )
464
470
n > 1 && print (io, " (repeats " , n, " times)" )
465
471
end
466
472
467
- # Contains file name and file number. Gets set when a backtrace
468
- # or methodlist is shown. Used by the REPL to make it possible to open
469
- # the location of a stackframe/method in the editor.
470
- global LAST_SHOWN_LINE_INFOS = Tuple{String, Int}[]
471
-
472
473
# In case the line numbers in the source code have changed since the code was compiled,
473
474
# allow packages to set a callback function that corrects them.
474
475
# (Used by Revise and perhaps other packages.)
@@ -489,6 +490,10 @@ function show_reduced_backtrace(io::IO, t::Vector, with_prefix::Bool)
489
490
frame appears just before. =#
490
491
491
492
displayed_stackframes = []
493
+ repeated_cycle = Tuple{Int,Int,Int}[]
494
+ # First: line to introuce the "cycle repetition" message
495
+ # Second: length of the cycle
496
+ # Third: number of repetitions
492
497
frame_counter = 1
493
498
while frame_counter < length (t)
494
499
(last_frame, n) = t[frame_counter]
@@ -507,11 +512,10 @@ function show_reduced_backtrace(io::IO, t::Vector, with_prefix::Bool)
507
512
while i < length (t) && t[i] == t[j]
508
513
i+= 1 ; j+= 1
509
514
end
510
- if j >= frame_counter
515
+ if j >= frame_counter- 1
511
516
#= At least one cycle repeated =#
512
517
repetitions = div (i - frame_counter + 1 , cycle_length)
513
- print (io, " \n ... (the last " , cycle_length, " lines are repeated " ,
514
- repetitions, " more time" , repetitions> 1 ? " s)" : " )" )
518
+ push! (repeated_cycle, (length (displayed_stackframes), cycle_length, repetitions))
515
519
frame_counter += cycle_length * repetitions - 1
516
520
break
517
521
end
@@ -524,13 +528,24 @@ function show_reduced_backtrace(io::IO, t::Vector, with_prefix::Bool)
524
528
525
529
try invokelatest (update_stackframes_callback[], displayed_stackframes) catch end
526
530
527
- for (frame, n) in displayed_stackframes
531
+ push! (repeated_cycle, (0 ,0 ,0 )) # repeated_cycle is never empty
532
+ frame_counter = 1
533
+ for i in 1 : length (displayed_stackframes)
534
+ (frame, n) = displayed_stackframes[i]
528
535
if with_prefix
529
- show_trace_entry (io, frame, n, prefix = string (" [" , frame_counter- 1 , " ] " ))
530
- push! (LAST_SHOWN_LINE_INFOS, (string (frame. file), frame. line))
536
+ show_trace_entry (io, frame, n, prefix = string (" [" , frame_counter, " ] " ))
531
537
else
532
538
show_trace_entry (io, frame, n)
533
539
end
540
+ while repeated_cycle[1 ][1 ] == i # never empty because of the initial (0,0,0)
541
+ cycle_length = repeated_cycle[1 ][2 ]
542
+ repetitions = repeated_cycle[1 ][3 ]
543
+ popfirst! (repeated_cycle)
544
+ print (io, " \n ... (the last " , cycle_length, " lines are repeated " ,
545
+ repetitions, " more time" , repetitions> 1 ? " s)" : " )" )
546
+ frame_counter += cycle_length * repetitions
547
+ end
548
+ frame_counter += 1
534
549
end
535
550
end
536
551
@@ -555,7 +570,6 @@ function show_backtrace(io::IO, t::Vector)
555
570
for (last_frame, n) in filtered
556
571
frame_counter += 1
557
572
show_trace_entry (IOContext (io, :backtrace => true ), last_frame, n, prefix = string (" [" , frame_counter, " ] " ))
558
- push! (LAST_SHOWN_LINE_INFOS, (string (last_frame. file), last_frame. line))
559
573
end
560
574
return
561
575
end
0 commit comments