diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index cc2a519087df..99342351d92c 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1060,11 +1060,11 @@ impl EmitterWriter { -> io::Result<()> { use std::borrow::Borrow; - let primary_span = suggestion.substitution_spans().next().unwrap(); + let primary_sub = &suggestion.substitution_parts[0]; if let Some(ref cm) = self.cm { let mut buffer = StyledBuffer::new(); - let lines = cm.span_to_lines(primary_span).unwrap(); + let lines = cm.span_to_lines(primary_sub.span).unwrap(); assert!(!lines.lines.is_empty()); @@ -1077,26 +1077,51 @@ impl EmitterWriter { Some(Style::HeaderMsg)); let suggestions = suggestion.splice_lines(cm.borrow()); - let line_start = cm.lookup_char_pos(primary_span.lo).line - 1; - let mut row_num = 1; + 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; + draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1); + let mut row_num = 2; for complete in suggestions.iter().take(MAX_SUGGESTIONS) { + let mut line_pos = 0; + // 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(); for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) { - // print the span column to avoid confusion + // Print the span column to avoid confusion buffer.puts(row_num, 0, - &((line_start + row_num).to_string()), + &((line_start + line_pos).to_string()), Style::LineNumber); // print the suggestion draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); buffer.append(row_num, line, Style::NoStyle); row_num += 1; + if show_underline { + draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); + + let sub_len = primary_sub.substitutions[0].trim_right().len(); + let underline_start = span_start_pos.col.0; + let underline_end = span_start_pos.col.0 + sub_len; + for p in underline_start..underline_end { + buffer.putc(row_num, + max_line_num_len + 3 + p, + '^', + Style::UnderlinePrimary); + } + row_num += 1; + } + line_pos += 1; } // if we elided some lines, add an ellipsis if let Some(_) = lines.next() { buffer.append(row_num, "...", Style::NoStyle); + } else if !show_underline && suggestions.len() <= MAX_SUGGESTIONS { + draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1); } } if suggestions.len() > MAX_SUGGESTIONS { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c248e20b608f..23d852323697 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2920,10 +2920,6 @@ impl<'a> Parser<'a> { err.cancel(); let codemap = self.sess.codemap(); let suggestion_span = lhs_span.to(self.prev_span); - let suggestion = match codemap.span_to_snippet(suggestion_span) { - Ok(lstring) => format!("({})", lstring), - _ => format!("( as )") - }; let warn_message = match codemap.span_to_snippet(self.prev_span) { Ok(lstring) => format!("`{}`", lstring), _ => "a type".to_string(), @@ -2934,6 +2930,10 @@ impl<'a> Parser<'a> { let mut err = self.sess.span_diagnostic.struct_span_err(sp, &msg); err.span_label(sp, "interpreted as generic argument"); err.span_label(self.span, "not interpreted as comparison"); + let suggestion = match codemap.span_to_snippet(suggestion_span) { + Ok(lstring) => format!("({})", lstring), + _ => format!("( as )") + }; err.span_suggestion(suggestion_span, "if you want to compare the casted value then write:", suggestion); diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr index 034bc0d12822..f9702d43ad51 100644 --- a/src/test/ui/issue-22644.stderr +++ b/src/test/ui/issue-22644.stderr @@ -7,7 +7,9 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | not interpreted as comparison | help: if you want to compare the casted value then write: + | 16 | println!("{}", (a as usize) < b); + | ^^^^^^^^^^^^ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:17:33 @@ -18,7 +20,9 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | not interpreted as comparison | help: if you want to compare the casted value then write: + | 17 | println!("{}", (a as usize) < 4); + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.stderr b/src/test/ui/resolve/enums-are-namespaced-xc.stderr index 87ca26695b06..525dd4fe8f1c 100644 --- a/src/test/ui/resolve/enums-are-namespaced-xc.stderr +++ b/src/test/ui/resolve/enums-are-namespaced-xc.stderr @@ -5,7 +5,9 @@ error[E0425]: cannot find value `A` in module `namespaced_enums` | ^ not found in `namespaced_enums` | help: possible candidate is found in another module, you can import it into scope + | 12 | use namespaced_enums::Foo::A; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0425]: cannot find function `B` in module `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:18:31 @@ -14,7 +16,9 @@ error[E0425]: cannot find function `B` in module `namespaced_enums` | ^ not found in `namespaced_enums` | help: possible candidate is found in another module, you can import it into scope + | 12 | use namespaced_enums::Foo::B; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:21:31 @@ -23,7 +27,9 @@ error[E0422]: cannot find struct, variant or union type `C` in module `namespace | ^ not found in `namespaced_enums` | help: possible candidate is found in another module, you can import it into scope + | 12 | use namespaced_enums::Foo::C; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/resolve/issue-16058.stderr b/src/test/ui/resolve/issue-16058.stderr index 184ab5575483..7abf6e3d5fde 100644 --- a/src/test/ui/resolve/issue-16058.stderr +++ b/src/test/ui/resolve/issue-16058.stderr @@ -5,9 +5,11 @@ error[E0574]: expected struct, variant or union type, found enum `Result` | ^^^^^^ not a struct, variant or union type | help: possible better candidates are found in other modules, you can import them into scope + | 12 | use std::fmt::Result; -13 | use std::io::Result; -14 | use std::thread::Result; +12 | use std::io::Result; +12 | use std::thread::Result; + | error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-17518.stderr b/src/test/ui/resolve/issue-17518.stderr index ced4919e47a1..d7017f301452 100644 --- a/src/test/ui/resolve/issue-17518.stderr +++ b/src/test/ui/resolve/issue-17518.stderr @@ -5,7 +5,9 @@ error[E0422]: cannot find struct, variant or union type `E` in this scope | ^ not found in this scope | help: possible candidate is found in another module, you can import it into scope + | 11 | use SomeEnum::E; + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index 1f4fe01dee06..ce5ed7b5e5db 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -5,9 +5,11 @@ error[E0405]: cannot find trait `Mul` in this scope | ^^^ not found in this scope | help: possible candidates are found in other modules, you can import them into scope + | 11 | use mul1::Mul; -12 | use mul2::Mul; -13 | use std::ops::Mul; +11 | use mul2::Mul; +11 | use std::ops::Mul; + | error[E0412]: cannot find type `Mul` in this scope --> $DIR/issue-21221-1.rs:72:16 @@ -16,10 +18,11 @@ error[E0412]: cannot find type `Mul` in this scope | ^^^ not found in this scope | help: possible candidates are found in other modules, you can import them into scope + | 11 | use mul1::Mul; -12 | use mul2::Mul; -13 | use mul3::Mul; -14 | use mul4::Mul; +11 | use mul2::Mul; +11 | use mul3::Mul; +11 | use mul4::Mul; and 2 other candidates error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope @@ -35,7 +38,9 @@ error[E0405]: cannot find trait `Div` in this scope | ^^^ not found in this scope | help: possible candidate is found in another module, you can import it into scope + | 11 | use std::ops::Div; + | ^^^^^^^^^^^^^^^^^^ error: cannot continue compilation due to previous error diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index 74490efed7a1..bca3667d60ba 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -5,7 +5,9 @@ error[E0405]: cannot find trait `T` in this scope | ^ not found in this scope | help: possible candidate is found in another module, you can import it into scope + | 11 | use foo::bar::T; + | ^^^^^^^^^^^^^^^^ error[E0601]: main function not found diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr index 54f3773a8d7a..f364fb590abc 100644 --- a/src/test/ui/resolve/issue-21221-3.stderr +++ b/src/test/ui/resolve/issue-21221-3.stderr @@ -5,7 +5,9 @@ error[E0405]: cannot find trait `OuterTrait` in this scope | ^^^^^^^^^^ not found in this scope | help: possible candidate is found in another module, you can import it into scope + | 16 | use issue_21221_3::outer::OuterTrait; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot continue compilation due to previous error diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr index 739a06ca8b36..a022ca0749d3 100644 --- a/src/test/ui/resolve/issue-21221-4.stderr +++ b/src/test/ui/resolve/issue-21221-4.stderr @@ -5,7 +5,9 @@ error[E0405]: cannot find trait `T` in this scope | ^ not found in this scope | help: possible candidate is found in another module, you can import it into scope + | 16 | use issue_21221_4::T; + | ^^^^^^^^^^^^^^^^^^^^^ error: cannot continue compilation due to previous error diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index d1df59408c76..56d3afd77e63 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -5,7 +5,9 @@ error[E0404]: expected trait, found type alias `Foo` | ^^^ type aliases cannot be used for traits | help: possible better candidate is found in another module, you can import it into scope + | 12 | use issue_3907::Foo; + | ^^^^^^^^^^^^^^^^^^^^ error: cannot continue compilation due to previous error diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index 6d75efffe626..c0b0fc63f22b 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -9,7 +9,9 @@ error[E0423]: expected value, found struct `Z` | constructor is not visible here due to private fields | help: possible better candidate is found in another module, you can import it into scope + | 15 | use m::n::Z; + | ^^^^^^^^^^^^ error[E0423]: expected value, found struct `S` --> $DIR/privacy-struct-ctor.rs:36:5 @@ -21,7 +23,9 @@ error[E0423]: expected value, found struct `S` | constructor is not visible here due to private fields | help: possible better candidate is found in another module, you can import it into scope + | 13 | use m::S; + | ^^^^^^^^^ error[E0423]: expected value, found struct `xcrate::S` --> $DIR/privacy-struct-ctor.rs:42:5 @@ -33,7 +37,9 @@ error[E0423]: expected value, found struct `xcrate::S` | constructor is not visible here due to private fields | help: possible better candidate is found in another module, you can import it into scope + | 13 | use m::S; + | ^^^^^^^^^ error[E0603]: tuple struct `Z` is private --> $DIR/privacy-struct-ctor.rs:25:9 diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index d44c29ad7393..b344f00cd88f 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -5,7 +5,9 @@ error[E0404]: expected trait, found type parameter `Add` | ^^^ not a trait | help: possible better candidate is found in another module, you can import it into scope + | 11 | use std::ops::Add; + | ^^^^^^^^^^^^^^^^^^ error[E0601]: main function not found diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index 3129dc1a6717..a0445eaee916 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -5,7 +5,9 @@ error[E0369]: binary operation `+` cannot be applied to type `&'static str` | ^^^^^^^^^^^^^^^^^^^ `+` can't be used to concatenate two `&str` strings | help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left. + | 12 | let x = "Hello ".to_owned() + "World!"; + | ^^^^^^^^^^^^^^^^^^^ error[E0369]: binary operation `+` cannot be applied to type `World` --> $DIR/issue-39018.rs:17:13