@@ -2073,20 +2073,85 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
20732073                        continue ; 
20742074                    } 
20752075                } ) ; 
2076+ 
2077+                 struct  Lifetime ( Span ,  String ) ; 
2078+                 impl  Lifetime  { 
2079+                     fn  is_unnamed ( & self )  -> bool  { 
2080+                         self . 1 . starts_with ( '&' )  && !self . 1 . starts_with ( "&'" ) 
2081+                     } 
2082+                     fn  is_underscore ( & self )  -> bool  { 
2083+                         self . 1 . starts_with ( "&'_ " ) 
2084+                     } 
2085+                     fn  is_named ( & self )  -> bool  { 
2086+                         self . 1 . starts_with ( "&'" ) 
2087+                     } 
2088+                     fn  suggestion ( & self ,  sugg :  String )  -> Option < ( Span ,  String ) >  { 
2089+                         Some ( 
2090+                             match  ( 
2091+                                 self . is_unnamed ( ) , 
2092+                                 self . is_underscore ( ) , 
2093+                                 self . is_named ( ) , 
2094+                                 sugg. starts_with ( "&" ) , 
2095+                             )  { 
2096+                                 ( true ,  _,  _,  false )  => ( self . span_unnamed_borrow ( ) ,  sugg) , 
2097+                                 ( true ,  _,  _,  true )  => { 
2098+                                     ( self . span_unnamed_borrow ( ) ,  sugg[ 1 ..] . to_string ( ) ) 
2099+                                 } 
2100+                                 ( _,  true ,  _,  false )  => { 
2101+                                     ( self . span_underscore_borrow ( ) ,  sugg. trim ( ) . to_string ( ) ) 
2102+                                 } 
2103+                                 ( _,  true ,  _,  true )  => { 
2104+                                     ( self . span_underscore_borrow ( ) ,  sugg[ 1 ..] . trim ( ) . to_string ( ) ) 
2105+                                 } 
2106+                                 ( _,  _,  true ,  false )  => { 
2107+                                     ( self . span_named_borrow ( ) ,  sugg. trim ( ) . to_string ( ) ) 
2108+                                 } 
2109+                                 ( _,  _,  true ,  true )  => { 
2110+                                     ( self . span_named_borrow ( ) ,  sugg[ 1 ..] . trim ( ) . to_string ( ) ) 
2111+                                 } 
2112+                                 _ => return  None , 
2113+                             } , 
2114+                         ) 
2115+                     } 
2116+                     fn  span_unnamed_borrow ( & self )  -> Span  { 
2117+                         let  lo = self . 0 . lo ( )  + BytePos ( 1 ) ; 
2118+                         self . 0 . with_lo ( lo) . with_hi ( lo) 
2119+                     } 
2120+                     fn  span_named_borrow ( & self )  -> Span  { 
2121+                         let  lo = self . 0 . lo ( )  + BytePos ( 1 ) ; 
2122+                         self . 0 . with_lo ( lo) 
2123+                     } 
2124+                     fn  span_underscore_borrow ( & self )  -> Span  { 
2125+                         let  lo = self . 0 . lo ( )  + BytePos ( 1 ) ; 
2126+                         let  hi = lo + BytePos ( 2 ) ; 
2127+                         self . 0 . with_lo ( lo) . with_hi ( hi) 
2128+                     } 
2129+                 } 
2130+ 
20762131                for  param in  params { 
20772132                    if  let  Ok ( snippet)  = self . tcx . sess . source_map ( ) . span_to_snippet ( param. span )  { 
2078-                         if  snippet. starts_with ( '&' )  && !snippet. starts_with ( "&'" )  { 
2079-                             introduce_suggestion
2080-                                 . push ( ( param. span ,  format ! ( "&'a {}" ,  & snippet[ 1 ..] ) ) ) ; 
2081-                         }  else  if  let  Some ( stripped)  = snippet. strip_prefix ( "&'_ " )  { 
2082-                             introduce_suggestion. push ( ( param. span ,  format ! ( "&'a {}" ,  & stripped) ) ) ; 
2133+                         if  let  Some ( ( span,  sugg) )  =
2134+                             Lifetime ( param. span ,  snippet) . suggestion ( "'a " . to_string ( ) ) 
2135+                         { 
2136+                             introduce_suggestion. push ( ( span,  sugg) ) ; 
20832137                        } 
20842138                    } 
20852139                } 
2086-                 for  ( ( span,  _) ,  sugg)  in  spans_with_counts. iter ( ) . copied ( ) . zip ( suggs. iter ( ) )  { 
2087-                     if  let  Some ( sugg)  = sugg { 
2088-                         introduce_suggestion. push ( ( span,  sugg. to_string ( ) ) ) ; 
2089-                     } 
2140+                 for  ( span,  sugg)  in  spans_with_counts. iter ( ) . copied ( ) . zip ( suggs. iter ( ) ) . filter_map ( 
2141+                     |( ( span,  _) ,  sugg) | match  & sugg { 
2142+                         Some ( sugg)  => Some ( ( span,  sugg. to_string ( ) ) ) , 
2143+                         _ => None , 
2144+                     } , 
2145+                 )  { 
2146+                     let  ( span,  sugg)  = self 
2147+                         . tcx 
2148+                         . sess 
2149+                         . source_map ( ) 
2150+                         . span_to_snippet ( span) 
2151+                         . ok ( ) 
2152+                         . and_then ( |snippet| Lifetime ( span,  snippet) . suggestion ( sugg. clone ( ) ) ) 
2153+                         . unwrap_or ( ( span,  sugg) ) ; 
2154+                     introduce_suggestion. push ( ( span,  sugg. to_string ( ) ) ) ; 
20902155                } 
20912156                err. multipart_suggestion_with_style ( 
20922157                    & msg, 
@@ -2159,7 +2224,8 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
21592224                for  ( ( span,  _) ,  snippet)  in  spans_with_counts. iter ( ) . copied ( ) . zip ( snippets. iter ( ) )  { 
21602225                    match  snippet. as_deref ( )  { 
21612226                        Some ( "" )  => spans_suggs. push ( ( span,  "'lifetime, " . to_string ( ) ) ) , 
2162-                         Some ( "&" )  => spans_suggs. push ( ( span,  "&'lifetime " . to_string ( ) ) ) , 
2227+                         Some ( "&" )  => spans_suggs
2228+                             . push ( ( span. with_lo ( span. lo ( )  + BytePos ( 1 ) ) ,  "'lifetime " . to_string ( ) ) ) , 
21632229                        _ => { } 
21642230                    } 
21652231                } 
0 commit comments