@@ -2216,6 +2216,11 @@ impl HumanEmitter {
2216
2216
show_code_change
2217
2217
{
2218
2218
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
+ } ;
2219
2224
let span_start_pos = sm. lookup_char_pos ( part. span . lo ( ) ) . col_display ;
2220
2225
let span_end_pos = sm. lookup_char_pos ( part. span . hi ( ) ) . col_display ;
2221
2226
@@ -2263,13 +2268,52 @@ impl HumanEmitter {
2263
2268
}
2264
2269
if let DisplaySuggestion :: Diff = show_code_change {
2265
2270
// 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
+ let newlines = snippet. lines ( ) . count ( ) ;
2273
+ if newlines > 0 && row_num > newlines {
2274
+ // Account for removals where the part being removed spans multiple
2275
+ // lines.
2276
+ // FIXME: We check the number of rows because in some cases, like in
2277
+ // `tests/ui/lint/invalid-nan-comparison-suggestion.rs`, the rendered
2278
+ // suggestion will only show the first line of code being replaced. The
2279
+ // proper way of doing this would be to change the suggestion rendering
2280
+ // logic to show the whole prior snippet, but the current output is not
2281
+ // too bad to begin with, so we side-step that issue here.
2282
+ for ( i, line) in snippet. lines ( ) . enumerate ( ) {
2283
+ let line = normalize_whitespace ( line) ;
2284
+ let row = row_num - 2 - ( newlines - i - 1 ) ;
2285
+ // On the first line, we highlight between the start of the part
2286
+ // span, and the end of that line.
2287
+ // On the last line, we highlight between the start of the line, and
2288
+ // the column of the part span end.
2289
+ // On all others, we highlight the whole line.
2290
+ let start = if i == 0 {
2291
+ ( padding as isize + span_start_pos as isize ) as usize
2292
+ } else {
2293
+ padding
2294
+ } ;
2295
+ let end = if i == 0 {
2296
+ ( padding as isize
2297
+ + span_start_pos as isize
2298
+ + line. len ( ) as isize )
2299
+ as usize
2300
+ } else if i == newlines - 1 {
2301
+ ( padding as isize + span_end_pos as isize ) as usize
2302
+ } else {
2303
+ ( padding as isize + line. len ( ) as isize ) as usize
2304
+ } ;
2305
+ buffer. set_style_range ( row, start, end, Style :: Removal , true ) ;
2306
+ }
2307
+ } else {
2308
+ // The removed code fits all in one line.
2309
+ buffer. set_style_range (
2310
+ row_num - 2 ,
2311
+ ( padding as isize + span_start_pos as isize ) as usize ,
2312
+ ( padding as isize + span_end_pos as isize ) as usize ,
2313
+ Style :: Removal ,
2314
+ true ,
2315
+ ) ;
2316
+ }
2273
2317
}
2274
2318
2275
2319
// length of the code after substitution
0 commit comments