diff options
| author | Esteban Kuber <esteban@kuber.com.ar> | 2021-08-12 19:33:19 +0000 |
|---|---|---|
| committer | Esteban Kuber <esteban@kuber.com.ar> | 2021-08-23 11:58:18 +0000 |
| commit | 75fd1bf1e60dd140f2ba46a4252195ea2a9b9c89 (patch) | |
| tree | 32f6be36a9355624b61881031919242dbc29bbb3 /compiler/rustc_errors/src | |
| parent | 33fdb797f59421c7bbecaa4588ed5d7a31a9494a (diff) | |
| download | rust-75fd1bf1e60dd140f2ba46a4252195ea2a9b9c89.tar.gz rust-75fd1bf1e60dd140f2ba46a4252195ea2a9b9c89.zip | |
Account for tabs when highlighting multiline code suggestions
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/emitter.rs | 48 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 22 |
2 files changed, 45 insertions, 25 deletions
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 07c864c93a1..645b81b9540 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1623,7 +1623,7 @@ impl EmitterWriter { let line_start = sm.lookup_char_pos(parts[0].span.lo()).line; draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1); let mut lines = complete.lines(); - for (line_pos, (line, parts)) in + for (line_pos, (line, highlight_parts)) in lines.by_ref().zip(highlights).take(MAX_SUGGESTION_HIGHLIGHT_LINES).enumerate() { // Print the span column to avoid confusion @@ -1658,7 +1658,7 @@ impl EmitterWriter { ); buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition); } else if is_multiline { - match &parts[..] { + match &highlight_parts[..] { [SubstitutionHighlight { start: 0, end }] if *end == line.len() => { buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition); } @@ -1676,16 +1676,33 @@ impl EmitterWriter { // print the suggestion buffer.append(row_num, &replace_tabs(line), Style::NoStyle); - if is_multiline { - for SubstitutionHighlight { start, end } in parts { - buffer.set_style_range( - row_num, - max_line_num_len + 3 + start, - max_line_num_len + 3 + end, - Style::Addition, - true, - ); - } + // Colorize addition/replacements with green. + for &SubstitutionHighlight { start, end } in highlight_parts { + // Account for tabs when highlighting (#87972). + let start: usize = line + .chars() + .take(start) + .map(|ch| match ch { + '\t' => 4, + _ => 1, + }) + .sum(); + + let end: usize = line + .chars() + .take(end) + .map(|ch| match ch { + '\t' => 4, + _ => 1, + }) + .sum(); + buffer.set_style_range( + row_num, + max_line_num_len + 3 + start, + max_line_num_len + 3 + end, + Style::Addition, + true, + ); } row_num += 1; } @@ -1723,13 +1740,6 @@ impl EmitterWriter { assert!(underline_start >= 0 && underline_end >= 0); let padding: usize = max_line_num_len + 3; for p in underline_start..underline_end { - // Colorize addition/replacements with green. - buffer.set_style( - row_num - 1, - (padding as isize + p) as usize, - Style::Addition, - true, - ); if !show_diff { // If this is a replacement, underline with `^`, if this is an addition // underline with `+`. diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index ec29d8016dd..cae4a6b4723 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -283,6 +283,9 @@ impl CodeSuggestion { let mut buf = String::new(); let mut line_highlight = vec![]; + // We need to keep track of the difference between the existing code and the added + // or deleted code in order to point at the correct column *after* substitution. + let mut acc = 0; for part in &substitution.parts { let cur_lo = sm.lookup_char_pos(part.span.lo()); if prev_hi.line == cur_lo.line { @@ -290,6 +293,7 @@ impl CodeSuggestion { push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo)); while count > 0 { highlights.push(std::mem::take(&mut line_highlight)); + acc = 0; count -= 1; } } else { @@ -297,6 +301,7 @@ impl CodeSuggestion { let mut count = push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None); while count > 0 { highlights.push(std::mem::take(&mut line_highlight)); + acc = 0; count -= 1; } // push lines between the previous and current span (if any) @@ -305,6 +310,7 @@ impl CodeSuggestion { buf.push_str(line.as_ref()); buf.push('\n'); highlights.push(std::mem::take(&mut line_highlight)); + acc = 0; } } if let Some(cur_line) = sf.get_line(cur_lo.line - 1) { @@ -316,18 +322,22 @@ impl CodeSuggestion { } } // Add a whole line highlight per line in the snippet. + let len = part.snippet.split('\n').next().unwrap_or(&part.snippet).len(); line_highlight.push(SubstitutionHighlight { - start: cur_lo.col.0, - end: cur_lo.col.0 - + part.snippet.split('\n').next().unwrap_or(&part.snippet).len(), + start: (cur_lo.col.0 as isize + acc) as usize, + end: (cur_lo.col.0 as isize + acc + len as isize) as usize, }); + buf.push_str(&part.snippet); + prev_hi = sm.lookup_char_pos(part.span.hi()); + if prev_hi.line == cur_lo.line { + acc += len as isize - (prev_hi.col.0 - cur_lo.col.0) as isize; + } + prev_line = sf.get_line(prev_hi.line - 1); for line in part.snippet.split('\n').skip(1) { + acc = 0; highlights.push(std::mem::take(&mut line_highlight)); line_highlight.push(SubstitutionHighlight { start: 0, end: line.len() }); } - buf.push_str(&part.snippet); - prev_hi = sm.lookup_char_pos(part.span.hi()); - prev_line = sf.get_line(prev_hi.line - 1); } highlights.push(std::mem::take(&mut line_highlight)); let only_capitalization = is_case_difference(sm, &buf, bounding_span); |
