Skip to content

Commit 50eefc0

Browse files
committed
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.
1 parent 2daa013 commit 50eefc0

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

src/librustc_errors/emitter.rs

+20-15
Original file line numberDiff line numberDiff line change
@@ -1242,50 +1242,55 @@ impl EmitterWriter {
12421242
line_pos += 1;
12431243
row_num += 1;
12441244
}
1245-
let mut extra = 0;
1245+
1246+
// This offset and the ones below need to be signed to account for replacement code
1247+
// that is shorter than the original code.
1248+
let mut offset: isize = 0;
12461249
// Only show an underline in the suggestions if the suggestion is not the
12471250
// entirety of the code being shown and the displayed code is not multiline.
12481251
if show_underline {
12491252
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
12501253
for part in parts {
1251-
let span_start_pos = cm.lookup_char_pos(part.span.lo());
1252-
let span_end_pos = cm.lookup_char_pos(part.span.hi());
1253-
// length of the code to be substituted
1254-
let snippet_len = span_end_pos.col_display - span_start_pos.col_display;
1255-
1256-
// Do not underline the leading or trailing spaces.
1257-
let start = part.snippet.len() - part.snippet.trim_left().len();
1258-
// account for substitutions containing unicode characters
1254+
let span_start_pos = cm.lookup_char_pos(part.span.lo()).col_display;
1255+
let span_end_pos = cm.lookup_char_pos(part.span.hi()).col_display;
1256+
1257+
// Do not underline the leading...
1258+
let start = part.snippet.len()
1259+
.saturating_sub(part.snippet.trim_left().len());
1260+
// ...or trailing spaces. Account for substitutions containing unicode
1261+
// characters.
12591262
let sub_len = part.snippet.trim().chars().fold(0, |acc, ch| {
12601263
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
12611264
});
12621265

1263-
let underline_start = span_start_pos.col_display + start + extra;
1264-
let underline_end = span_start_pos.col_display + start + sub_len + extra;
1266+
let underline_start = (span_start_pos + start) as isize + offset;
1267+
let underline_end = (span_start_pos + start + sub_len) as isize + offset;
12651268
for p in underline_start..underline_end {
12661269
buffer.putc(row_num,
1267-
max_line_num_len + 3 + p,
1270+
max_line_num_len + 3 + p as usize,
12681271
'^',
12691272
Style::UnderlinePrimary);
12701273
}
12711274
// underline removals too
12721275
if underline_start == underline_end {
12731276
for p in underline_start-1..underline_start+1 {
12741277
buffer.putc(row_num,
1275-
max_line_num_len + 3 + p,
1278+
max_line_num_len + 3 + p as usize,
12761279
'-',
12771280
Style::UnderlineSecondary);
12781281
}
12791282
}
12801283

12811284
// length of the code after substitution
12821285
let full_sub_len = part.snippet.chars().fold(0, |acc, ch| {
1283-
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
1286+
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) as isize
12841287
});
12851288

1289+
// length of the code to be substituted
1290+
let snippet_len = (span_end_pos - span_start_pos) as isize;
12861291
// For multiple substitutions, use the position *after* the previous
12871292
// substitutions have happened.
1288-
extra += full_sub_len - snippet_len;
1293+
offset += full_sub_len - snippet_len;
12891294
}
12901295
row_num += 1;
12911296
}

src/test/ui/impl-trait/impl-generic-mismatch.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | fn foo<U: Debug>(&self, _: &U) { }
99
help: try removing the generic parameter and using `impl Trait` instead
1010
|
1111
LL | fn foo(&self, _: &impl Debug) { }
12-
|
12+
| -- ^^^^^^^^^^
1313

1414
error[E0643]: method `bar` has incompatible signature for trait
1515
--> $DIR/impl-generic-mismatch.rs:27:23

0 commit comments

Comments
 (0)