@@ -20,9 +20,7 @@ lazy_static!{
20
20
"sentry::" ,
21
21
"sentry_types::" ,
22
22
// these are not modules but things like __rust_maybe_catch_panic
23
- // or _<T as core..convert..Into<U>>::into
24
23
"__rust_" ,
25
- "_<" ,
26
24
] ;
27
25
#[ cfg( feature = "with_failure" ) ] {
28
26
rv. push( "failure::" ) ;
@@ -39,7 +37,7 @@ lazy_static!{
39
37
rv. push( "failure::backtrace::Backtrace::new" ) ;
40
38
}
41
39
#[ cfg( feature = "with_log" ) ] {
42
- rv. push( "_ <sentry.. integrations.. log.. Logger as log.. Log>::log" ) ;
40
+ rv. push( "<sentry:: integrations:: log:: Logger as log:: Log>::log" ) ;
43
41
}
44
42
#[ cfg( feature = "with_error_chain" ) ] {
45
43
rv. push( "error_chain::make_backtrace" ) ;
@@ -50,7 +48,7 @@ lazy_static!{
50
48
#![ allow( unused_mut) ]
51
49
let mut rv = Vec :: new( ) ;
52
50
#[ cfg( feature = "with_error_chain" ) ] {
53
- rv. push( ( "error_chain::make_backtrace" , "_ <T as core.. convert.. Into<U>>::into" ) ) ;
51
+ rv. push( ( "error_chain::make_backtrace" , "<T as core:: convert:: Into<U>>::into" ) ) ;
54
52
}
55
53
rv
56
54
} ;
@@ -154,22 +152,26 @@ pub fn trim_stacktrace<F>(stacktrace: &mut Stacktrace, f: F)
154
152
where
155
153
F : Fn ( & Frame , & Stacktrace ) -> bool ,
156
154
{
157
- if let Some ( cutoff) = stacktrace. frames . iter ( ) . rev ( ) . position ( |frame| {
158
- if let Some ( ref func) = frame. function {
159
- WELL_KNOWN_BORDER_FRAMES . contains ( & func. as_str ( ) ) || f ( frame, stacktrace)
160
- } else {
161
- false
162
- }
163
- } ) {
155
+ let known_cutoff = stacktrace
156
+ . frames
157
+ . iter ( )
158
+ . rev ( )
159
+ . position ( |frame| match frame. function {
160
+ Some ( ref func) => is_well_known ( & func) || f ( frame, stacktrace) ,
161
+ None => false ,
162
+ } ) ;
163
+
164
+ if let Some ( cutoff) = known_cutoff {
164
165
let secondary = {
165
166
let func = stacktrace. frames [ stacktrace. frames . len ( ) - cutoff - 1 ]
166
167
. function
167
168
. as_ref ( )
168
169
. unwrap ( ) ;
170
+
169
171
SECONDARY_BORDER_FRAMES
170
172
. iter ( )
171
173
. filter_map ( |& ( primary, secondary) | {
172
- if primary == func {
174
+ if function_starts_with ( func, primary ) {
173
175
Some ( secondary)
174
176
} else {
175
177
None
@@ -180,13 +182,14 @@ where
180
182
stacktrace. frames . truncate ( trunc) ;
181
183
182
184
if let Some ( secondary) = secondary {
183
- if let Some ( cutoff) = stacktrace. frames . iter ( ) . rev ( ) . position ( |frame| {
184
- if let Some ( ref func) = frame. function {
185
- func. as_str ( ) == secondary
186
- } else {
187
- false
188
- }
189
- } ) {
185
+ let secondary_cutoff = stacktrace. frames . iter ( ) . rev ( ) . position ( |frame| match frame
186
+ . function
187
+ {
188
+ Some ( ref func) => function_starts_with ( & func, secondary) ,
189
+ None => false ,
190
+ } ) ;
191
+
192
+ if let Some ( cutoff) = secondary_cutoff {
190
193
let trunc = stacktrace. frames . len ( ) - cutoff - 1 ;
191
194
stacktrace. frames . truncate ( trunc) ;
192
195
}
@@ -202,13 +205,32 @@ pub fn is_sys_function(func: &str) -> bool {
202
205
. any ( |m| function_starts_with ( func, m) )
203
206
}
204
207
208
+ /// Checks if a function is a well-known system function
209
+ fn is_well_known ( func : & str ) -> bool {
210
+ WELL_KNOWN_BORDER_FRAMES
211
+ . iter ( )
212
+ . any ( |m| function_starts_with ( & func, m) )
213
+ }
214
+
205
215
/// Checks whether the function name starts with the given pattern.
206
216
///
207
217
/// In trait implementations, the original type name is wrapped in "_< ... >" and colons are
208
218
/// replaced with dots. This function accounts for differences while checking.
209
- pub fn function_starts_with ( mut func_name : & str , pattern : & str ) -> bool {
210
- if func_name. starts_with ( "_<" ) {
211
- func_name = & func_name[ 2 ..] ;
219
+ pub fn function_starts_with ( mut func_name : & str , mut pattern : & str ) -> bool {
220
+ if pattern. starts_with ( '<' ) {
221
+ while pattern. starts_with ( '<' ) {
222
+ pattern = & pattern[ 1 ..] ;
223
+
224
+ if func_name. starts_with ( '<' ) {
225
+ func_name = & func_name[ 1 ..] ;
226
+ } else if func_name. starts_with ( "_<" ) {
227
+ func_name = & func_name[ 2 ..] ;
228
+ } else {
229
+ return false ;
230
+ }
231
+ }
232
+ } else {
233
+ func_name = func_name. trim_left_matches ( '<' ) . trim_left_matches ( "_<" ) ;
212
234
}
213
235
214
236
if !func_name. is_char_boundary ( pattern. len ( ) ) {
@@ -250,4 +272,35 @@ mod tests {
250
272
"tokio::"
251
273
) ) ;
252
274
}
275
+
276
+ #[ test]
277
+ fn test_function_starts_with_newimpl ( ) {
278
+ assert ! ( function_starts_with(
279
+ "<futures::task_impl::Spawn<T>>::enter::{{closure}}" ,
280
+ "futures::"
281
+ ) ) ;
282
+
283
+ assert ! ( !function_starts_with(
284
+ "<futures::task_impl::Spawn<T>>::enter::{{closure}}" ,
285
+ "tokio::"
286
+ ) ) ;
287
+ }
288
+
289
+ #[ test]
290
+ fn test_function_starts_with_impl_pattern ( ) {
291
+ assert ! ( function_starts_with(
292
+ "_<futures..task_impl..Spawn<T>>::enter::_{{closure}}" ,
293
+ "<futures::"
294
+ ) ) ;
295
+
296
+ assert ! ( function_starts_with(
297
+ "<futures::task_impl::Spawn<T>>::enter::{{closure}}" ,
298
+ "<futures::"
299
+ ) ) ;
300
+
301
+ assert ! ( !function_starts_with(
302
+ "futures::task_impl::std::set" ,
303
+ "<futures::"
304
+ ) ) ;
305
+ }
253
306
}
0 commit comments