about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2017-06-27 23:16:04 -0700
committerEsteban Küber <esteban@kuber.com.ar>2017-07-06 14:36:48 -0700
commiteb478e23813b89944edfa602b6927e17c4c62f86 (patch)
tree265b712b83ec72723c776fe3d04f9a32188e9214
parent7c849146353322ad72bba6c64580b53164aa9304 (diff)
downloadrust-eb478e23813b89944edfa602b6927e17c4c62f86.tar.gz
rust-eb478e23813b89944edfa602b6927e17c4c62f86.zip
Add extra whitespace for suggestions
-rw-r--r--src/librustc_errors/emitter.rs37
-rw-r--r--src/libsyntax/parse/parser.rs8
-rw-r--r--src/test/ui/issue-22644.stderr4
-rw-r--r--src/test/ui/resolve/enums-are-namespaced-xc.stderr6
-rw-r--r--src/test/ui/resolve/issue-16058.stderr6
-rw-r--r--src/test/ui/resolve/issue-17518.stderr2
-rw-r--r--src/test/ui/resolve/issue-21221-1.stderr15
-rw-r--r--src/test/ui/resolve/issue-21221-2.stderr2
-rw-r--r--src/test/ui/resolve/issue-21221-3.stderr2
-rw-r--r--src/test/ui/resolve/issue-21221-4.stderr2
-rw-r--r--src/test/ui/resolve/issue-3907.stderr2
-rw-r--r--src/test/ui/resolve/privacy-struct-ctor.stderr6
-rw-r--r--src/test/ui/span/issue-35987.stderr2
-rw-r--r--src/test/ui/span/issue-39018.stderr2
14 files changed, 79 insertions, 17 deletions
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index cc2a519087d..99342351d92 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 c248e20b608..23d85232369 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!("(<expression> as <type>)")
-                        };
                         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!("(<expression> as <type>)")
+                        };
                         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 034bc0d1282..f9702d43ad5 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 87ca26695b0..525dd4fe8f1 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 184ab557548..7abf6e3d5fd 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 ced4919e47a..d7017f30145 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 1f4fe01dee0..ce5ed7b5e5d 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 74490efed7a..bca3667d60b 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 54f3773a8d7..f364fb590ab 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 739a06ca8b3..a022ca0749d 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 d1df59408c7..56d3afd77e6 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 6d75efffe62..c0b0fc63f22 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 d44c29ad739..b344f00cd88 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 3129dc1a671..a0445eaee91 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