@@ -629,26 +629,41 @@ impl SourceMap {
629629 }
630630
631631 /// Extends the given `Span` to just after the previous occurrence of `pat` when surrounded by
632- /// whitespace. Returns the same span if no character could be found or if an error occurred
633- /// while retrieving the code snippet.
634- pub fn span_extend_to_prev_str ( & self , sp : Span , pat : & str , accept_newlines : bool ) -> Span {
632+ /// whitespace. Returns None if the pattern could not be found or if an error occurred while
633+ /// retrieving the code snippet.
634+ pub fn span_extend_to_prev_str (
635+ & self ,
636+ sp : Span ,
637+ pat : & str ,
638+ accept_newlines : bool ,
639+ include_whitespace : bool ,
640+ ) -> Option < Span > {
635641 // assure that the pattern is delimited, to avoid the following
636642 // fn my_fn()
637643 // ^^^^ returned span without the check
638644 // ---------- correct span
645+ let prev_source = self . span_to_prev_source ( sp) . ok ( ) ?;
639646 for ws in & [ " " , "\t " , "\n " ] {
640647 let pat = pat. to_owned ( ) + ws;
641- if let Ok ( prev_source) = self . span_to_prev_source ( sp) {
642- let prev_source = prev_source. rsplit ( & pat) . next ( ) . unwrap_or ( "" ) . trim_start ( ) ;
643- if prev_source. is_empty ( ) && sp. lo ( ) . 0 != 0 {
644- return sp. with_lo ( BytePos ( sp. lo ( ) . 0 - 1 ) ) ;
645- } else if accept_newlines || !prev_source. contains ( '\n' ) {
646- return sp. with_lo ( BytePos ( sp. lo ( ) . 0 - prev_source. len ( ) as u32 ) ) ;
648+ if let Some ( pat_pos) = prev_source. rfind ( & pat) {
649+ let just_after_pat_pos = pat_pos + pat. len ( ) - 1 ;
650+ let just_after_pat_plus_ws = if include_whitespace {
651+ just_after_pat_pos
652+ + prev_source[ just_after_pat_pos..]
653+ . find ( |c : char | !c. is_whitespace ( ) )
654+ . unwrap_or ( 0 )
655+ } else {
656+ just_after_pat_pos
657+ } ;
658+ let len = prev_source. len ( ) - just_after_pat_plus_ws;
659+ let prev_source = & prev_source[ just_after_pat_plus_ws..] ;
660+ if accept_newlines || !prev_source. trim_start ( ) . contains ( '\n' ) {
661+ return Some ( sp. with_lo ( BytePos ( sp. lo ( ) . 0 - len as u32 ) ) ) ;
647662 }
648663 }
649664 }
650665
651- sp
666+ None
652667 }
653668
654669 /// Returns the source snippet as `String` after the given `Span`.
@@ -927,7 +942,7 @@ impl SourceMap {
927942 }
928943
929944 pub fn generate_fn_name_span ( & self , span : Span ) -> Option < Span > {
930- let prev_span = self . span_extend_to_prev_str ( span, "fn" , true ) ;
945+ let prev_span = self . span_extend_to_prev_str ( span, "fn" , true , true ) . unwrap_or ( span ) ;
931946 if let Ok ( snippet) = self . span_to_snippet ( prev_span) {
932947 debug ! (
933948 "generate_fn_name_span: span={:?}, prev_span={:?}, snippet={:?}" ,
@@ -968,8 +983,7 @@ impl SourceMap {
968983 pub fn generate_local_type_param_snippet ( & self , span : Span ) -> Option < ( Span , String ) > {
969984 // Try to extend the span to the previous "fn" keyword to retrieve the function
970985 // signature.
971- let sugg_span = self . span_extend_to_prev_str ( span, "fn" , false ) ;
972- if sugg_span != span {
986+ if let Some ( sugg_span) = self . span_extend_to_prev_str ( span, "fn" , false , true ) {
973987 if let Ok ( snippet) = self . span_to_snippet ( sugg_span) {
974988 // Consume the function name.
975989 let mut offset = snippet
0 commit comments