1
Fork 0

Account for negative offsets in suggestions

When suggesting code that has a shorter span than the current code,
account for this by keeping the offset as a signed value.
This commit is contained in:
Esteban Küber 2018-05-23 18:31:54 -07:00
parent 2daa013290
commit 50eefc0d77
2 changed files with 20 additions and 15 deletions

View file

@ -1242,29 +1242,32 @@ impl EmitterWriter {
line_pos += 1;
row_num += 1;
}
let mut extra = 0;
// This offset and the ones below need to be signed to account for replacement code
// that is shorter than the original code.
let mut offset: isize = 0;
// Only show an underline in the suggestions if the suggestion is not the
// entirety of the code being shown and the displayed code is not multiline.
if show_underline {
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
for part in parts {
let span_start_pos = cm.lookup_char_pos(part.span.lo());
let span_end_pos = cm.lookup_char_pos(part.span.hi());
// length of the code to be substituted
let snippet_len = span_end_pos.col_display - span_start_pos.col_display;
let span_start_pos = cm.lookup_char_pos(part.span.lo()).col_display;
let span_end_pos = cm.lookup_char_pos(part.span.hi()).col_display;
// Do not underline the leading or trailing spaces.
let start = part.snippet.len() - part.snippet.trim_left().len();
// account for substitutions containing unicode characters
// Do not underline the leading...
let start = part.snippet.len()
.saturating_sub(part.snippet.trim_left().len());
// ...or trailing spaces. Account for substitutions containing unicode
// characters.
let sub_len = part.snippet.trim().chars().fold(0, |acc, ch| {
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
});
let underline_start = span_start_pos.col_display + start + extra;
let underline_end = span_start_pos.col_display + start + sub_len + extra;
let underline_start = (span_start_pos + start) as isize + offset;
let underline_end = (span_start_pos + start + sub_len) as isize + offset;
for p in underline_start..underline_end {
buffer.putc(row_num,
max_line_num_len + 3 + p,
max_line_num_len + 3 + p as usize,
'^',
Style::UnderlinePrimary);
}
@ -1272,7 +1275,7 @@ impl EmitterWriter {
if underline_start == underline_end {
for p in underline_start-1..underline_start+1 {
buffer.putc(row_num,
max_line_num_len + 3 + p,
max_line_num_len + 3 + p as usize,
'-',
Style::UnderlineSecondary);
}
@ -1280,12 +1283,14 @@ impl EmitterWriter {
// length of the code after substitution
let full_sub_len = part.snippet.chars().fold(0, |acc, ch| {
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) as isize
});
// length of the code to be substituted
let snippet_len = (span_end_pos - span_start_pos) as isize;
// For multiple substitutions, use the position *after* the previous
// substitutions have happened.
extra += full_sub_len - snippet_len;
offset += full_sub_len - snippet_len;
}
row_num += 1;
}

View file

@ -9,7 +9,7 @@ LL | fn foo<U: Debug>(&self, _: &U) { }
help: try removing the generic parameter and using `impl Trait` instead
|
LL | fn foo(&self, _: &impl Debug) { }
|
| -- ^^^^^^^^^^
error[E0643]: method `bar` has incompatible signature for trait
--> $DIR/impl-generic-mismatch.rs:27:23