1
1
use std:: mem;
2
2
3
+ use rustc_data_structures:: fx:: FxHashSet ;
3
4
use rustc_errors:: { Diag , DiagArgName , DiagArgValue , DiagMessage , IntoDiagArg } ;
4
5
use rustc_middle:: mir:: AssertKind ;
5
6
use rustc_middle:: mir:: interpret:: { AllocId , Provenance , ReportedErrorInfo } ;
@@ -9,7 +10,7 @@ use rustc_middle::ty::{ConstInt, TyCtxt};
9
10
use rustc_span:: { Span , Symbol } ;
10
11
11
12
use super :: CompileTimeMachine ;
12
- use crate :: errors:: { self , FrameNote , ReportErrorExt } ;
13
+ use crate :: errors:: { FrameNote , ReportErrorExt } ;
13
14
use crate :: interpret:: {
14
15
CtfeProvenance , ErrorHandled , Frame , InterpErrorInfo , InterpErrorKind , MachineStopType ,
15
16
Pointer , err_inval, err_machine_stop,
@@ -93,7 +94,7 @@ impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
93
94
pub fn get_span_and_frames < ' tcx > (
94
95
tcx : TyCtxtAt < ' tcx > ,
95
96
stack : & [ Frame < ' tcx , impl Provenance , impl Sized > ] ,
96
- ) -> ( Span , Vec < errors :: FrameNote > ) {
97
+ ) -> ( Span , Vec < FrameNote > ) {
97
98
let mut stacktrace = Frame :: generate_stacktrace_from_stack ( stack) ;
98
99
// Filter out `requires_caller_location` frames.
99
100
stacktrace. retain ( |frame| !frame. instance . def . requires_caller_location ( * tcx) ) ;
@@ -104,8 +105,8 @@ pub fn get_span_and_frames<'tcx>(
104
105
// Add notes to the backtrace. Don't print a single-line backtrace though.
105
106
if stacktrace. len ( ) > 1 {
106
107
// Helper closure to print duplicated lines.
107
- let mut add_frame = |mut frame : errors :: FrameNote | {
108
- frames. push ( errors :: FrameNote { times : 0 , ..frame. clone ( ) } ) ;
108
+ let mut add_frame = |mut frame : FrameNote | {
109
+ frames. push ( FrameNote { times : 0 , ..frame. clone ( ) } ) ;
109
110
// Don't print [... additional calls ...] if the number of lines is small
110
111
if frame. times < 3 {
111
112
let times = frame. times ;
@@ -116,21 +117,19 @@ pub fn get_span_and_frames<'tcx>(
116
117
}
117
118
} ;
118
119
119
- let mut last_frame: Option < errors:: FrameNote > = None ;
120
+ let mut last_frame: Option < FrameNote > = None ;
121
+ let mut seen = FxHashSet :: default ( ) ;
120
122
for frame_info in & stacktrace {
121
123
let frame = frame_info. as_note ( * tcx) ;
122
124
match last_frame. as_mut ( ) {
123
- Some ( last_frame)
124
- if last_frame. span == frame. span
125
- && last_frame. where_ == frame. where_
126
- && last_frame. instance == frame. instance =>
127
- {
125
+ Some ( last_frame) if !seen. insert ( frame. clone ( ) ) => {
128
126
last_frame. times += 1 ;
129
127
}
130
128
Some ( last_frame) => {
131
129
add_frame ( mem:: replace ( last_frame, frame) ) ;
132
130
}
133
131
None => {
132
+ seen. insert ( frame. clone ( ) ) ;
134
133
last_frame = Some ( frame) ;
135
134
}
136
135
}
@@ -219,7 +218,7 @@ pub(super) fn lint<'tcx, L>(
219
218
tcx : TyCtxtAt < ' tcx > ,
220
219
machine : & CompileTimeMachine < ' tcx > ,
221
220
lint : & ' static rustc_session:: lint:: Lint ,
222
- decorator : impl FnOnce ( Vec < errors :: FrameNote > ) -> L ,
221
+ decorator : impl FnOnce ( Vec < FrameNote > ) -> L ,
223
222
) where
224
223
L : for < ' a > rustc_errors:: LintDiagnostic < ' a , ( ) > ,
225
224
{
0 commit comments