Skip to content

Commit 70aec8d

Browse files
authored
Rollup merge of #87976 - estebank:fix-suggestion-span-coloring, r=m-ou-se
Account for tabs when highlighting multiline code suggestions Address `'\t'` case in #87972. Before: ![Screen Shot 2021-08-12 at 8 52 27 AM](https://user-images.githubusercontent.com/1606434/129228214-e5cfd203-9aa8-41c7-acd9-ce255ef8a21e.png) After: ![Screen Shot 2021-08-12 at 8 52 15 AM](https://user-images.githubusercontent.com/1606434/129228236-57c951fc-c8cf-4901-989f-b9b5aa5eebca.png)
2 parents 52c881f + 955e913 commit 70aec8d

File tree

2 files changed

+57
-26
lines changed

2 files changed

+57
-26
lines changed

compiler/rustc_errors/src/emitter.rs

+20-19
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,7 @@ impl EmitterWriter {
16231623
let line_start = sm.lookup_char_pos(parts[0].span.lo()).line;
16241624
draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
16251625
let mut lines = complete.lines();
1626-
for (line_pos, (line, parts)) in
1626+
for (line_pos, (line, highlight_parts)) in
16271627
lines.by_ref().zip(highlights).take(MAX_SUGGESTION_HIGHLIGHT_LINES).enumerate()
16281628
{
16291629
// Print the span column to avoid confusion
@@ -1658,7 +1658,7 @@ impl EmitterWriter {
16581658
);
16591659
buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition);
16601660
} else if is_multiline {
1661-
match &parts[..] {
1661+
match &highlight_parts[..] {
16621662
[SubstitutionHighlight { start: 0, end }] if *end == line.len() => {
16631663
buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition);
16641664
}
@@ -1676,16 +1676,24 @@ impl EmitterWriter {
16761676
// print the suggestion
16771677
buffer.append(row_num, &replace_tabs(line), Style::NoStyle);
16781678

1679-
if is_multiline {
1680-
for SubstitutionHighlight { start, end } in parts {
1681-
buffer.set_style_range(
1682-
row_num,
1683-
max_line_num_len + 3 + start,
1684-
max_line_num_len + 3 + end,
1685-
Style::Addition,
1686-
true,
1687-
);
1688-
}
1679+
// Colorize addition/replacements with green.
1680+
for &SubstitutionHighlight { start, end } in highlight_parts {
1681+
// Account for tabs when highlighting (#87972).
1682+
let tabs: usize = line
1683+
.chars()
1684+
.take(start)
1685+
.map(|ch| match ch {
1686+
'\t' => 3,
1687+
_ => 0,
1688+
})
1689+
.sum();
1690+
buffer.set_style_range(
1691+
row_num,
1692+
max_line_num_len + 3 + start + tabs,
1693+
max_line_num_len + 3 + end + tabs,
1694+
Style::Addition,
1695+
true,
1696+
);
16891697
}
16901698
row_num += 1;
16911699
}
@@ -1723,13 +1731,6 @@ impl EmitterWriter {
17231731
assert!(underline_start >= 0 && underline_end >= 0);
17241732
let padding: usize = max_line_num_len + 3;
17251733
for p in underline_start..underline_end {
1726-
// Colorize addition/replacements with green.
1727-
buffer.set_style(
1728-
row_num - 1,
1729-
(padding as isize + p) as usize,
1730-
Style::Addition,
1731-
true,
1732-
);
17331734
if !show_diff {
17341735
// If this is a replacement, underline with `^`, if this is an addition
17351736
// underline with `+`.

compiler/rustc_errors/src/lib.rs

+37-7
Original file line numberDiff line numberDiff line change
@@ -283,16 +283,21 @@ impl CodeSuggestion {
283283
let mut buf = String::new();
284284

285285
let mut line_highlight = vec![];
286+
// We need to keep track of the difference between the existing code and the added
287+
// or deleted code in order to point at the correct column *after* substitution.
288+
let mut acc = 0;
286289
for part in &substitution.parts {
287290
let cur_lo = sm.lookup_char_pos(part.span.lo());
288291
if prev_hi.line == cur_lo.line {
289292
let mut count =
290293
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo));
291294
while count > 0 {
292295
highlights.push(std::mem::take(&mut line_highlight));
296+
acc = 0;
293297
count -= 1;
294298
}
295299
} else {
300+
acc = 0;
296301
highlights.push(std::mem::take(&mut line_highlight));
297302
let mut count = push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
298303
while count > 0 {
@@ -316,18 +321,43 @@ impl CodeSuggestion {
316321
}
317322
}
318323
// Add a whole line highlight per line in the snippet.
324+
let len: isize = part
325+
.snippet
326+
.split('\n')
327+
.next()
328+
.unwrap_or(&part.snippet)
329+
.chars()
330+
.map(|c| match c {
331+
'\t' => 4,
332+
_ => 1,
333+
})
334+
.sum();
319335
line_highlight.push(SubstitutionHighlight {
320-
start: cur_lo.col.0,
321-
end: cur_lo.col.0
322-
+ part.snippet.split('\n').next().unwrap_or(&part.snippet).len(),
336+
start: (cur_lo.col.0 as isize + acc) as usize,
337+
end: (cur_lo.col.0 as isize + acc + len) as usize,
323338
});
339+
buf.push_str(&part.snippet);
340+
let cur_hi = sm.lookup_char_pos(part.span.hi());
341+
if prev_hi.line == cur_lo.line {
342+
// Account for the difference between the width of the current code and the
343+
// snippet being suggested, so that the *later* suggestions are correctly
344+
// aligned on the screen.
345+
acc += len as isize - (cur_hi.col.0 - cur_lo.col.0) as isize;
346+
}
347+
prev_hi = cur_hi;
348+
prev_line = sf.get_line(prev_hi.line - 1);
324349
for line in part.snippet.split('\n').skip(1) {
350+
acc = 0;
325351
highlights.push(std::mem::take(&mut line_highlight));
326-
line_highlight.push(SubstitutionHighlight { start: 0, end: line.len() });
352+
let end: usize = line
353+
.chars()
354+
.map(|c| match c {
355+
'\t' => 4,
356+
_ => 1,
357+
})
358+
.sum();
359+
line_highlight.push(SubstitutionHighlight { start: 0, end });
327360
}
328-
buf.push_str(&part.snippet);
329-
prev_hi = sm.lookup_char_pos(part.span.hi());
330-
prev_line = sf.get_line(prev_hi.line - 1);
331361
}
332362
highlights.push(std::mem::take(&mut line_highlight));
333363
let only_capitalization = is_case_difference(sm, &buf, bounding_span);

0 commit comments

Comments
 (0)