@@ -20,9 +20,7 @@ lazy_static!{
2020 "sentry::" ,
2121 "sentry_types::" ,
2222 // these are not modules but things like __rust_maybe_catch_panic
23- // or _<T as core..convert..Into<U>>::into
2423 "__rust_" ,
25- "_<" ,
2624 ] ;
2725 #[ cfg( feature = "with_failure" ) ] {
2826 rv. push( "failure::" ) ;
@@ -39,7 +37,7 @@ lazy_static!{
3937 rv. push( "failure::backtrace::Backtrace::new" ) ;
4038 }
4139 #[ 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" ) ;
4341 }
4442 #[ cfg( feature = "with_error_chain" ) ] {
4543 rv. push( "error_chain::make_backtrace" ) ;
@@ -50,7 +48,7 @@ lazy_static!{
5048 #![ allow( unused_mut) ]
5149 let mut rv = Vec :: new( ) ;
5250 #[ 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" ) ) ;
5452 }
5553 rv
5654 } ;
@@ -154,22 +152,26 @@ pub fn trim_stacktrace<F>(stacktrace: &mut Stacktrace, f: F)
154152where
155153 F : Fn ( & Frame , & Stacktrace ) -> bool ,
156154{
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 {
164165 let secondary = {
165166 let func = stacktrace. frames [ stacktrace. frames . len ( ) - cutoff - 1 ]
166167 . function
167168 . as_ref ( )
168169 . unwrap ( ) ;
170+
169171 SECONDARY_BORDER_FRAMES
170172 . iter ( )
171173 . filter_map ( |& ( primary, secondary) | {
172- if primary == func {
174+ if function_starts_with ( func, primary ) {
173175 Some ( secondary)
174176 } else {
175177 None
@@ -180,13 +182,14 @@ where
180182 stacktrace. frames . truncate ( trunc) ;
181183
182184 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 {
190193 let trunc = stacktrace. frames . len ( ) - cutoff - 1 ;
191194 stacktrace. frames . truncate ( trunc) ;
192195 }
@@ -202,13 +205,32 @@ pub fn is_sys_function(func: &str) -> bool {
202205 . any ( |m| function_starts_with ( func, m) )
203206}
204207
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+
205215/// Checks whether the function name starts with the given pattern.
206216///
207217/// In trait implementations, the original type name is wrapped in "_< ... >" and colons are
208218/// 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 ( "_<" ) ;
212234 }
213235
214236 if !func_name. is_char_boundary ( pattern. len ( ) ) {
@@ -250,4 +272,35 @@ mod tests {
250272 "tokio::"
251273 ) ) ;
252274 }
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+ }
253306}
0 commit comments