@@ -1874,6 +1874,7 @@ impl Renderer {
18741874                show_code_change
18751875            { 
18761876                for  part in  parts { 
1877+                     let  snippet = sm. span_to_snippet ( part. span . clone ( ) ) . unwrap_or_default ( ) ; 
18771878                    let  ( span_start,  span_end)  = sm. span_to_locations ( part. span . clone ( ) ) ; 
18781879                    let  span_start_pos = span_start. display ; 
18791880                    let  span_end_pos = span_end. display ; 
@@ -1932,13 +1933,86 @@ impl Renderer {
19321933                    } 
19331934                    if  let  DisplaySuggestion :: Diff  = show_code_change { 
19341935                        // Colorize removal with red in diff format. 
1935-                         buffer. set_style_range ( 
1936-                             row_num - 2 , 
1937-                             ( padding as  isize  + span_start_pos as  isize )  as  usize , 
1938-                             ( padding as  isize  + span_end_pos as  isize )  as  usize , 
1939-                             ElementStyle :: Removal , 
1940-                             true , 
1941-                         ) ; 
1936+ 
1937+                         // Below, there's some tricky buffer indexing going on. `row_num` at this 
1938+                         // point corresponds to: 
1939+                         // 
1940+                         //    | 
1941+                         // LL | CODE 
1942+                         //    | ++++  <- `row_num` 
1943+                         // 
1944+                         // in the buffer. When we have a diff format output, we end up with 
1945+                         // 
1946+                         //    | 
1947+                         // LL - OLDER   <- row_num - 2 
1948+                         // LL + NEWER 
1949+                         //    |         <- row_num 
1950+                         // 
1951+                         // The `row_num - 2` is to select the buffer line that has the "old version 
1952+                         // of the diff" at that point. When the removal is a single line, `i` is 
1953+                         // `0`, `newlines` is `1` so `(newlines - i - 1)` ends up being `0`, so row 
1954+                         // points at `LL - OLDER`. When the removal corresponds to multiple lines, 
1955+                         // we end up with `newlines > 1` and `i` being `0..newlines - 1`. 
1956+                         // 
1957+                         //    | 
1958+                         // LL - OLDER   <- row_num - 2 - (newlines - last_i - 1) 
1959+                         // LL - CODE 
1960+                         // LL - BEING 
1961+                         // LL - REMOVED <- row_num - 2 - (newlines - first_i - 1) 
1962+                         // LL + NEWER 
1963+                         //    |         <- row_num 
1964+ 
1965+                         let  newlines = snippet. lines ( ) . count ( ) ; 
1966+                         if  newlines > 0  && row_num > newlines { 
1967+                             // Account for removals where the part being removed spans multiple 
1968+                             // lines. 
1969+                             // FIXME: We check the number of rows because in some cases, like in 
1970+                             // `tests/ui/lint/invalid-nan-comparison-suggestion.rs`, the rendered 
1971+                             // suggestion will only show the first line of code being replaced. The 
1972+                             // proper way of doing this would be to change the suggestion rendering 
1973+                             // logic to show the whole prior snippet, but the current output is not 
1974+                             // too bad to begin with, so we side-step that issue here. 
1975+                             for  ( i,  line)  in  snippet. lines ( ) . enumerate ( )  { 
1976+                                 let  line = normalize_whitespace ( line) ; 
1977+                                 let  row = row_num - 2  - ( newlines - i - 1 ) ; 
1978+                                 // On the first line, we highlight between the start of the part 
1979+                                 // span, and the end of that line. 
1980+                                 // On the last line, we highlight between the start of the line, and 
1981+                                 // the column of the part span end. 
1982+                                 // On all others, we highlight the whole line. 
1983+                                 let  start = if  i == 0  { 
1984+                                     ( padding as  isize  + span_start_pos as  isize )  as  usize 
1985+                                 }  else  { 
1986+                                     padding
1987+                                 } ; 
1988+                                 let  end = if  i == 0  { 
1989+                                     ( padding as  isize 
1990+                                         + span_start_pos as  isize 
1991+                                         + line. len ( )  as  isize ) 
1992+                                         as  usize 
1993+                                 }  else  if  i == newlines - 1  { 
1994+                                     ( padding as  isize  + span_end_pos as  isize )  as  usize 
1995+                                 }  else  { 
1996+                                     ( padding as  isize  + line. len ( )  as  isize )  as  usize 
1997+                                 } ; 
1998+                                 buffer. set_style_range ( 
1999+                                     row, 
2000+                                     start, 
2001+                                     end, 
2002+                                     ElementStyle :: Removal , 
2003+                                     true , 
2004+                                 ) ; 
2005+                             } 
2006+                         }  else  { 
2007+                             // The removed code fits all in one line. 
2008+                             buffer. set_style_range ( 
2009+                                 row_num - 2 , 
2010+                                 ( padding as  isize  + span_start_pos as  isize )  as  usize , 
2011+                                 ( padding as  isize  + span_end_pos as  isize )  as  usize , 
2012+                                 ElementStyle :: Removal , 
2013+                                 true , 
2014+                             ) ; 
2015+                         } 
19422016                    } 
19432017
19442018                    // length of the code after substitution 
0 commit comments