Only underline suggestion if it is not the only code being shown

This commit is contained in:
Esteban Küber 2017-07-05 16:39:06 -07:00
parent eb478e2381
commit 697c85a4f1
16 changed files with 98 additions and 43 deletions

View file

@ -1078,17 +1078,14 @@ impl EmitterWriter {
let suggestions = suggestion.splice_lines(cm.borrow()); let suggestions = suggestion.splice_lines(cm.borrow());
let span_start_pos = cm.lookup_char_pos(primary_sub.span.lo); let span_start_pos = cm.lookup_char_pos(primary_sub.span.lo);
let span_end_pos = cm.lookup_char_pos(primary_sub.span.hi);
let line_start = span_start_pos.line; let line_start = span_start_pos.line;
draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1); draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
let mut row_num = 2; let mut row_num = 2;
for complete in suggestions.iter().take(MAX_SUGGESTIONS) { for (&(ref complete, show_underline), ref sub) in suggestions
.iter().zip(primary_sub.substitutions.iter()).take(MAX_SUGGESTIONS)
{
let mut line_pos = 0; let mut line_pos = 0;
// Only show underline if there's a single suggestion and it is a single line // Only show underline if there's a single suggestion and it is a single line
let show_underline = complete.lines().count() == 1
&& span_start_pos.line == span_end_pos.line
&& primary_sub.substitutions.len() == 1;
let mut lines = complete.lines(); let mut lines = complete.lines();
for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) { for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) {
// Print the span column to avoid confusion // Print the span column to avoid confusion
@ -1099,11 +1096,13 @@ impl EmitterWriter {
// print the suggestion // print the suggestion
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
buffer.append(row_num, line, Style::NoStyle); buffer.append(row_num, line, Style::NoStyle);
line_pos += 1;
row_num += 1; row_num += 1;
// 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 { if show_underline {
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
let sub_len = sub.trim_right().len();
let sub_len = primary_sub.substitutions[0].trim_right().len();
let underline_start = span_start_pos.col.0; let underline_start = span_start_pos.col.0;
let underline_end = span_start_pos.col.0 + sub_len; let underline_end = span_start_pos.col.0 + sub_len;
for p in underline_start..underline_end { for p in underline_start..underline_end {
@ -1114,19 +1113,19 @@ impl EmitterWriter {
} }
row_num += 1; row_num += 1;
} }
line_pos += 1;
} }
// if we elided some lines, add an ellipsis // if we elided some lines, add an ellipsis
if let Some(_) = lines.next() { if let Some(_) = lines.next() {
buffer.append(row_num, "...", Style::NoStyle); buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber);
} else if !show_underline && suggestions.len() <= MAX_SUGGESTIONS { } else if !show_underline {
draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1); draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
row_num += 1;
} }
} }
if suggestions.len() > MAX_SUGGESTIONS { if suggestions.len() > MAX_SUGGESTIONS {
let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS); let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS);
buffer.append(row_num, &msg, Style::NoStyle); buffer.puts(row_num, 0, &msg, Style::NoStyle);
} }
emit_to_destination(&buffer.render(), level, &mut self.dst)?; emit_to_destination(&buffer.render(), level, &mut self.dst)?;
} }

View file

@ -114,8 +114,8 @@ impl CodeSuggestion {
self.substitution_parts.iter().map(|sub| sub.span) self.substitution_parts.iter().map(|sub| sub.span)
} }
/// Returns the assembled code suggestions. /// Returns the assembled code suggestions and wether they should be shown with an underline.
pub fn splice_lines(&self, cm: &CodeMapper) -> Vec<String> { pub fn splice_lines(&self, cm: &CodeMapper) -> Vec<(String, bool)> {
use syntax_pos::{CharPos, Loc, Pos}; use syntax_pos::{CharPos, Loc, Pos};
fn push_trailing(buf: &mut String, fn push_trailing(buf: &mut String,
@ -138,7 +138,7 @@ impl CodeSuggestion {
} }
if self.substitution_parts.is_empty() { if self.substitution_parts.is_empty() {
return vec![String::new()]; return vec![(String::new(), false)];
} }
let mut primary_spans: Vec<_> = self.substitution_parts let mut primary_spans: Vec<_> = self.substitution_parts
@ -175,14 +175,25 @@ impl CodeSuggestion {
prev_hi.col = CharPos::from_usize(0); prev_hi.col = CharPos::from_usize(0);
let mut prev_line = fm.get_line(lines.lines[0].line_index); let mut prev_line = fm.get_line(lines.lines[0].line_index);
let mut bufs = vec![String::new(); self.substitutions()]; let mut bufs = vec![(String::new(), false); self.substitutions()];
for (sp, substitutes) in primary_spans { for (sp, substitutes) in primary_spans {
let cur_lo = cm.lookup_char_pos(sp.lo); let cur_lo = cm.lookup_char_pos(sp.lo);
for (buf, substitute) in bufs.iter_mut().zip(substitutes) { for (&mut (ref mut buf, ref mut underline), substitute) in bufs.iter_mut()
.zip(substitutes) {
if prev_hi.line == cur_lo.line { if prev_hi.line == cur_lo.line {
push_trailing(buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo)); push_trailing(buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo));
// 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 prev_line.as_ref().unwrap().trim().len() > 0
&& !substitute.ends_with('\n')
&& substitute.lines().count() == 1
{
*underline = true;
}
} else { } else {
*underline = false;
push_trailing(buf, prev_line.as_ref(), &prev_hi, None); push_trailing(buf, prev_line.as_ref(), &prev_hi, None);
// push lines between the previous and current span (if any) // push lines between the previous and current span (if any)
for idx in prev_hi.line..(cur_lo.line - 1) { for idx in prev_hi.line..(cur_lo.line - 1) {
@ -200,7 +211,7 @@ impl CodeSuggestion {
prev_hi = cm.lookup_char_pos(sp.hi); prev_hi = cm.lookup_char_pos(sp.hi);
prev_line = fm.get_line(prev_hi.line - 1); prev_line = fm.get_line(prev_hi.line - 1);
} }
for buf in &mut bufs { for &mut (ref mut buf, _) in &mut bufs {
// if the replacement already ends with a newline, don't print the next line // if the replacement already ends with a newline, don't print the next line
if !buf.ends_with('\n') { if !buf.ends_with('\n') {
push_trailing(buf, prev_line.as_ref(), &prev_hi, None); push_trailing(buf, prev_line.as_ref(), &prev_hi, None);

View file

@ -359,7 +359,7 @@ impl DiagnosticCode {
impl JsonEmitter { impl JsonEmitter {
fn render(&self, suggestion: &CodeSuggestion) -> Vec<String> { fn render(&self, suggestion: &CodeSuggestion) -> Vec<String> {
suggestion.splice_lines(&*self.cm) suggestion.splice_lines(&*self.cm).iter().map(|line| line.0.to_owned()).collect()
} }
} }

View file

@ -7,9 +7,13 @@ error[E0308]: mismatched types
= note: expected type `()` = note: expected type `()`
found type `usize` found type `usize`
help: did you mean to add a semicolon here? help: did you mean to add a semicolon here?
| foo(); |
19 | foo();
| ^
help: possibly return type missing here? help: possibly return type missing here?
| fn bar() -> usize { |
18 | fn bar() -> usize {
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View file

@ -14,5 +14,18 @@ fn main() {
println!("{}", a as usize > b); println!("{}", a as usize > b);
println!("{}", a as usize < b); println!("{}", a as usize < b);
println!("{}", a as usize < 4); println!("{}", a
as
usize
<
4);
println!("{}", a
as
usize
<
5);
} }

View file

@ -12,17 +12,37 @@ help: if you want to compare the casted value then write:
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:17:33 --> $DIR/issue-22644.rs:21:20
| |
17 | println!("{}", a as usize < 4); 20 | <
| - ^ interpreted as generic argument | - not interpreted as comparison
| | 21 | 4);
| not interpreted as comparison | ^ interpreted as generic argument
| |
help: if you want to compare the casted value then write: help: if you want to compare the casted value then write:
| |
17 | println!("{}", (a as usize) < 4); 17 | println!("{}", (a
| ^^^^^^^^^^^^ 18 | as
19 | usize)
|
error: aborting due to 2 previous errors error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:30:20
|
29 | <
| - not interpreted as comparison
30 | 5);
| ^ interpreted as generic argument
|
help: if you want to compare the casted value then write:
|
22 | println!("{}", (a
23 |
24 |
25 | as
26 |
27 |
...
error: aborting due to 3 previous errors

View file

@ -7,7 +7,7 @@ error[E0425]: cannot find value `A` in module `namespaced_enums`
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
12 | use namespaced_enums::Foo::A; 12 | use namespaced_enums::Foo::A;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
error[E0425]: cannot find function `B` in module `namespaced_enums` error[E0425]: cannot find function `B` in module `namespaced_enums`
--> $DIR/enums-are-namespaced-xc.rs:18:31 --> $DIR/enums-are-namespaced-xc.rs:18:31
@ -18,7 +18,7 @@ error[E0425]: cannot find function `B` in module `namespaced_enums`
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
12 | use namespaced_enums::Foo::B; 12 | use namespaced_enums::Foo::B;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums` error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums`
--> $DIR/enums-are-namespaced-xc.rs:21:31 --> $DIR/enums-are-namespaced-xc.rs:21:31
@ -29,7 +29,7 @@ error[E0422]: cannot find struct, variant or union type `C` in module `namespace
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
12 | use namespaced_enums::Foo::C; 12 | use namespaced_enums::Foo::C;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -7,7 +7,9 @@ error[E0574]: expected struct, variant or union type, found enum `Result`
help: possible better candidates are found in other modules, you can import them into scope help: possible better candidates are found in other modules, you can import them into scope
| |
12 | use std::fmt::Result; 12 | use std::fmt::Result;
|
12 | use std::io::Result; 12 | use std::io::Result;
|
12 | use std::thread::Result; 12 | use std::thread::Result;
| |

View file

@ -7,7 +7,7 @@ error[E0422]: cannot find struct, variant or union type `E` in this scope
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
11 | use SomeEnum::E; 11 | use SomeEnum::E;
| ^^^^^^^^^^^^^^^^ |
error: aborting due to previous error error: aborting due to previous error

View file

@ -7,7 +7,9 @@ error[E0405]: cannot find trait `Mul` in this scope
help: possible candidates are found in other modules, you can import them into scope help: possible candidates are found in other modules, you can import them into scope
| |
11 | use mul1::Mul; 11 | use mul1::Mul;
|
11 | use mul2::Mul; 11 | use mul2::Mul;
|
11 | use std::ops::Mul; 11 | use std::ops::Mul;
| |
@ -20,9 +22,13 @@ error[E0412]: cannot find type `Mul` in this scope
help: possible candidates are found in other modules, you can import them into scope help: possible candidates are found in other modules, you can import them into scope
| |
11 | use mul1::Mul; 11 | use mul1::Mul;
|
11 | use mul2::Mul; 11 | use mul2::Mul;
|
11 | use mul3::Mul; 11 | use mul3::Mul;
|
11 | use mul4::Mul; 11 | use mul4::Mul;
|
and 2 other candidates and 2 other candidates
error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope
@ -40,7 +46,7 @@ error[E0405]: cannot find trait `Div` in this scope
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
11 | use std::ops::Div; 11 | use std::ops::Div;
| ^^^^^^^^^^^^^^^^^^ |
error: cannot continue compilation due to previous error error: cannot continue compilation due to previous error

View file

@ -7,7 +7,7 @@ error[E0405]: cannot find trait `T` in this scope
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
11 | use foo::bar::T; 11 | use foo::bar::T;
| ^^^^^^^^^^^^^^^^ |
error[E0601]: main function not found error[E0601]: main function not found

View file

@ -7,7 +7,7 @@ error[E0405]: cannot find trait `OuterTrait` in this scope
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
16 | use issue_21221_3::outer::OuterTrait; 16 | use issue_21221_3::outer::OuterTrait;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
error: cannot continue compilation due to previous error error: cannot continue compilation due to previous error

View file

@ -7,7 +7,7 @@ error[E0405]: cannot find trait `T` in this scope
help: possible candidate is found in another module, you can import it into scope help: possible candidate is found in another module, you can import it into scope
| |
16 | use issue_21221_4::T; 16 | use issue_21221_4::T;
| ^^^^^^^^^^^^^^^^^^^^^ |
error: cannot continue compilation due to previous error error: cannot continue compilation due to previous error

View file

@ -7,7 +7,7 @@ error[E0404]: expected trait, found type alias `Foo`
help: possible better candidate is found in another module, you can import it into scope help: possible better candidate is found in another module, you can import it into scope
| |
12 | use issue_3907::Foo; 12 | use issue_3907::Foo;
| ^^^^^^^^^^^^^^^^^^^^ |
error: cannot continue compilation due to previous error error: cannot continue compilation due to previous error

View file

@ -11,7 +11,7 @@ error[E0423]: expected value, found struct `Z`
help: possible better candidate is found in another module, you can import it into scope help: possible better candidate is found in another module, you can import it into scope
| |
15 | use m::n::Z; 15 | use m::n::Z;
| ^^^^^^^^^^^^ |
error[E0423]: expected value, found struct `S` error[E0423]: expected value, found struct `S`
--> $DIR/privacy-struct-ctor.rs:36:5 --> $DIR/privacy-struct-ctor.rs:36:5
@ -25,7 +25,7 @@ error[E0423]: expected value, found struct `S`
help: possible better candidate is found in another module, you can import it into scope help: possible better candidate is found in another module, you can import it into scope
| |
13 | use m::S; 13 | use m::S;
| ^^^^^^^^^ |
error[E0423]: expected value, found struct `xcrate::S` error[E0423]: expected value, found struct `xcrate::S`
--> $DIR/privacy-struct-ctor.rs:42:5 --> $DIR/privacy-struct-ctor.rs:42:5
@ -39,7 +39,7 @@ error[E0423]: expected value, found struct `xcrate::S`
help: possible better candidate is found in another module, you can import it into scope help: possible better candidate is found in another module, you can import it into scope
| |
13 | use m::S; 13 | use m::S;
| ^^^^^^^^^ |
error[E0603]: tuple struct `Z` is private error[E0603]: tuple struct `Z` is private
--> $DIR/privacy-struct-ctor.rs:25:9 --> $DIR/privacy-struct-ctor.rs:25:9

View file

@ -7,7 +7,7 @@ error[E0404]: expected trait, found type parameter `Add`
help: possible better candidate is found in another module, you can import it into scope help: possible better candidate is found in another module, you can import it into scope
| |
11 | use std::ops::Add; 11 | use std::ops::Add;
| ^^^^^^^^^^^^^^^^^^ |
error[E0601]: main function not found error[E0601]: main function not found