Skip to content

Commit 103abdb

Browse files
authored
Rollup merge of rust-lang#50987 - estebank:underline-multiple-suggestions, r=petrochencov
Underline multiple suggested replacements in the same line <img width="685" alt="screen shot 2018-05-22 at 21 06 48" src="https://user-images.githubusercontent.com/1606434/40403051-174f3180-5e04-11e8-86b6-261630c5ff80.png"> Follow up to rust-lang#50943. Fix rust-lang#50977.
2 parents 444a9c3 + f36c643 commit 103abdb

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

src/librustc_errors/emitter.rs

+52-18
Original file line numberDiff line numberDiff line change
@@ -1215,19 +1215,20 @@ impl EmitterWriter {
12151215

12161216
let mut row_num = 2;
12171217
for &(ref complete, ref parts) in suggestions.iter().take(MAX_SUGGESTIONS) {
1218-
let show_underline = parts.len() == 1
1219-
&& complete.lines().count() == 1
1220-
&& parts[0].snippet.trim() != complete.trim();
1218+
// Only show underline if the suggestion spans a single line and doesn't cover the
1219+
// entirety of the code output. If you have multiple replacements in the same line
1220+
// of code, show the underline.
1221+
let show_underline = !(parts.len() == 1
1222+
&& parts[0].snippet.trim() == complete.trim())
1223+
&& complete.lines().count() == 1;
12211224

12221225
let lines = cm.span_to_lines(parts[0].span).unwrap();
12231226

12241227
assert!(!lines.lines.is_empty());
12251228

1226-
let span_start_pos = cm.lookup_char_pos(parts[0].span.lo());
1227-
let line_start = span_start_pos.line;
1229+
let line_start = cm.lookup_char_pos(parts[0].span.lo()).line;
12281230
draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
12291231
let mut line_pos = 0;
1230-
// Only show underline if there's a single suggestion and it is a single line
12311232
let mut lines = complete.lines();
12321233
for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) {
12331234
// Print the span column to avoid confusion
@@ -1241,22 +1242,55 @@ impl EmitterWriter {
12411242
line_pos += 1;
12421243
row_num += 1;
12431244
}
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;
12441249
// Only show an underline in the suggestions if the suggestion is not the
12451250
// entirety of the code being shown and the displayed code is not multiline.
12461251
if show_underline {
12471252
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
1248-
let start = parts[0].snippet.len() - parts[0].snippet.trim_left().len();
1249-
// account for substitutions containing unicode characters
1250-
let sub_len = parts[0].snippet.trim().chars().fold(0, |acc, ch| {
1251-
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
1252-
});
1253-
let underline_start = span_start_pos.col_display + start;
1254-
let underline_end = span_start_pos.col_display + start + sub_len;
1255-
for p in underline_start..underline_end {
1256-
buffer.putc(row_num,
1257-
max_line_num_len + 3 + p,
1258-
'^',
1259-
Style::UnderlinePrimary);
1253+
for part in parts {
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.
1262+
let sub_len = part.snippet.trim().chars().fold(0, |acc, ch| {
1263+
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
1264+
});
1265+
1266+
let underline_start = (span_start_pos + start) as isize + offset;
1267+
let underline_end = (span_start_pos + start + sub_len) as isize + offset;
1268+
for p in underline_start..underline_end {
1269+
buffer.putc(row_num,
1270+
max_line_num_len + 3 + p as usize,
1271+
'^',
1272+
Style::UnderlinePrimary);
1273+
}
1274+
// underline removals too
1275+
if underline_start == underline_end {
1276+
for p in underline_start-1..underline_start+1 {
1277+
buffer.putc(row_num,
1278+
max_line_num_len + 3 + p as usize,
1279+
'-',
1280+
Style::UnderlineSecondary);
1281+
}
1282+
}
1283+
1284+
// length of the code after substitution
1285+
let full_sub_len = part.snippet.chars().fold(0, |acc, ch| {
1286+
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) as isize
1287+
});
1288+
1289+
// length of the code to be substituted
1290+
let snippet_len = (span_end_pos - span_start_pos) as isize;
1291+
// For multiple substitutions, use the position *after* the previous
1292+
// substitutions have happened.
1293+
offset += full_sub_len - snippet_len;
12601294
}
12611295
row_num += 1;
12621296
}

src/librustc_typeck/check/compare_method.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
777777
let new_generics_span = tcx
778778
.sess
779779
.codemap()
780-
.generate_fn_name_span(impl_m.span)?
780+
.generate_fn_name_span(impl_span)?
781781
.shrink_to_hi();
782782
// in case there are generics, just replace them
783783
let generics_span = impl_m

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

+3-7
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
@@ -21,12 +21,8 @@ LL | fn bar(&self, _: &impl Debug) { }
2121
| ^^^^^^^^^^ expected generic parameter, found `impl Trait`
2222
help: try changing the `impl Trait` argument to a generic parameter
2323
|
24-
LL | fn bar<U: Debug><U: Debug>(&self, _: &U);
25-
LL | }
26-
LL |
27-
LL | impl Bar for () {
28-
LL | fn bar(&self, _: &U) { }
29-
|
24+
LL | fn bar<U: Debug>(&self, _: &U) { }
25+
| ^^^^^^^^^^ ^
3026

3127
error[E0643]: method `hash` has incompatible signature for trait
3228
--> $DIR/impl-generic-mismatch.rs:38:33

0 commit comments

Comments
 (0)