@@ -2216,6 +2216,11 @@ impl HumanEmitter {
22162216                show_code_change
22172217            { 
22182218                for  part in  parts { 
2219+                     let  snippet = if  let  Ok ( snippet)  = sm. span_to_snippet ( part. span )  { 
2220+                         snippet
2221+                     }  else  { 
2222+                         String :: new ( ) 
2223+                     } ; 
22192224                    let  span_start_pos = sm. lookup_char_pos ( part. span . lo ( ) ) . col_display ; 
22202225                    let  span_end_pos = sm. lookup_char_pos ( part. span . hi ( ) ) . col_display ; 
22212226
@@ -2263,13 +2268,80 @@ impl HumanEmitter {
22632268                    } 
22642269                    if  let  DisplaySuggestion :: Diff  = show_code_change { 
22652270                        // Colorize removal with red in diff format. 
2266-                         buffer. set_style_range ( 
2267-                             row_num - 2 , 
2268-                             ( padding as  isize  + span_start_pos as  isize )  as  usize , 
2269-                             ( padding as  isize  + span_end_pos as  isize )  as  usize , 
2270-                             Style :: Removal , 
2271-                             true , 
2272-                         ) ; 
2271+ 
2272+                         // Below, there's some tricky buffer indexing going on. `row_num` at this 
2273+                         // point corresponds to: 
2274+                         // 
2275+                         //    | 
2276+                         // LL | CODE 
2277+                         //    | ++++  <- `row_num` 
2278+                         // 
2279+                         // in the buffer. When we have a diff format output, we end up with 
2280+                         // 
2281+                         //    | 
2282+                         // LL - OLDER   <- row_num - 2 
2283+                         // LL + NEWER 
2284+                         //    |         <- row_num 
2285+                         // 
2286+                         // The `row_num - 2` is to select the buffer line that has the "old version 
2287+                         // of the diff" at that point. When the removal is a single line, `i` is 
2288+                         // `0`, `newlines` is `1` so `(newlines - i - 1)` ends up being `0`, so row 
2289+                         // points at `LL - OLDER`. When the removal corresponds to multiple lines, 
2290+                         // we end up with `newlines > 1` and `i` being `0..newlines - 1`. 
2291+                         // 
2292+                         //    | 
2293+                         // LL - OLDER   <- row_num - 2 - (newlines - last_i - 1) 
2294+                         // LL - CODE 
2295+                         // LL - BEING 
2296+                         // LL - REMOVED <- row_num - 2 - (newlines - first_i - 1) 
2297+                         // LL + NEWER 
2298+                         //    |         <- row_num 
2299+ 
2300+                         let  newlines = snippet. lines ( ) . count ( ) ; 
2301+                         if  newlines > 0  && row_num > newlines { 
2302+                             // Account for removals where the part being removed spans multiple 
2303+                             // lines. 
2304+                             // FIXME: We check the number of rows because in some cases, like in 
2305+                             // `tests/ui/lint/invalid-nan-comparison-suggestion.rs`, the rendered 
2306+                             // suggestion will only show the first line of code being replaced. The 
2307+                             // proper way of doing this would be to change the suggestion rendering 
2308+                             // logic to show the whole prior snippet, but the current output is not 
2309+                             // too bad to begin with, so we side-step that issue here. 
2310+                             for  ( i,  line)  in  snippet. lines ( ) . enumerate ( )  { 
2311+                                 let  line = normalize_whitespace ( line) ; 
2312+                                 let  row = row_num - 2  - ( newlines - i - 1 ) ; 
2313+                                 // On the first line, we highlight between the start of the part 
2314+                                 // span, and the end of that line. 
2315+                                 // On the last line, we highlight between the start of the line, and 
2316+                                 // the column of the part span end. 
2317+                                 // On all others, we highlight the whole line. 
2318+                                 let  start = if  i == 0  { 
2319+                                     ( padding as  isize  + span_start_pos as  isize )  as  usize 
2320+                                 }  else  { 
2321+                                     padding
2322+                                 } ; 
2323+                                 let  end = if  i == 0  { 
2324+                                     ( padding as  isize 
2325+                                         + span_start_pos as  isize 
2326+                                         + line. len ( )  as  isize ) 
2327+                                         as  usize 
2328+                                 }  else  if  i == newlines - 1  { 
2329+                                     ( padding as  isize  + span_end_pos as  isize )  as  usize 
2330+                                 }  else  { 
2331+                                     ( padding as  isize  + line. len ( )  as  isize )  as  usize 
2332+                                 } ; 
2333+                                 buffer. set_style_range ( row,  start,  end,  Style :: Removal ,  true ) ; 
2334+                             } 
2335+                         }  else  { 
2336+                             // The removed code fits all in one line. 
2337+                             buffer. set_style_range ( 
2338+                                 row_num - 2 , 
2339+                                 ( padding as  isize  + span_start_pos as  isize )  as  usize , 
2340+                                 ( padding as  isize  + span_end_pos as  isize )  as  usize , 
2341+                                 Style :: Removal , 
2342+                                 true , 
2343+                             ) ; 
2344+                         } 
22732345                    } 
22742346
22752347                    // length of the code after substitution 
0 commit comments