about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-06 21:05:53 +0000
committerbors <bors@rust-lang.org>2017-12-06 21:05:53 +0000
commit5a2465e2b44ecdd3b5d835c0abe29e9a4c9dcfe4 (patch)
tree76b353607669b391077b7230d0c0c13966bbbc29 /src
parentcf30759a8409bee031ac252ee207452ab4804467 (diff)
parent9d80e2200af22bb4532a7cc4738b22e408072ffd (diff)
downloadrust-5a2465e2b44ecdd3b5d835c0abe29e9a4c9dcfe4.tar.gz
rust-5a2465e2b44ecdd3b5d835c0abe29e9a4c9dcfe4.zip
Auto merge of #45953 - estebank:tab-4, r=nikomatsakis
Display `\t` in diagnostics code as four spaces

Follow up to #44386 using the unicode variable width machinery from #45711 to replace tabs in the source code when displaying a diagnostic error with four spaces (instead of only one), while properly accounting for this when calculating underlines.

Partly addresses #44618.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_errors/styled_buffer.rs17
-rw-r--r--src/libsyntax_pos/lib.rs15
-rw-r--r--src/test/ui/codemap_tests/tab.stderr8
-rw-r--r--src/test/ui/codemap_tests/tab_2.stderr4
-rw-r--r--src/test/ui/codemap_tests/tab_3.stderr10
5 files changed, 37 insertions, 17 deletions
diff --git a/src/librustc_errors/styled_buffer.rs b/src/librustc_errors/styled_buffer.rs
index ceb94f27dc3..2c33f805203 100644
--- a/src/librustc_errors/styled_buffer.rs
+++ b/src/librustc_errors/styled_buffer.rs
@@ -27,10 +27,21 @@ impl StyledBuffer {
     }
 
     fn replace_tabs(&mut self) {
-        for line in self.text.iter_mut() {
-            for c in line.iter_mut() {
+        for (line_pos, line) in self.text.iter_mut().enumerate() {
+            let mut tab_pos = vec![];
+            for (pos, c) in line.iter().enumerate() {
                 if *c == '\t' {
-                    *c = ' ';
+                    tab_pos.push(pos);
+                }
+            }
+            // start with the tabs at the end of the line to replace them with 4 space chars
+            for pos in tab_pos.iter().rev() {
+                assert_eq!(line.remove(*pos), '\t');
+                // fix the position of the style to match up after replacing the tabs
+                let s = self.styles[line_pos].remove(*pos);
+                for _ in 0..4 {
+                    line.insert(*pos, ' ');
+                    self.styles[line_pos].insert(*pos, s);
                 }
             }
         }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index bf059cac891..ec652b5607e 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -503,6 +503,8 @@ pub enum NonNarrowChar {
     ZeroWidth(BytePos),
     /// Represents a wide (fullwidth) character
     Wide(BytePos),
+    /// Represents a tab character, represented visually with a width of 4 characters
+    Tab(BytePos),
 }
 
 impl NonNarrowChar {
@@ -510,6 +512,7 @@ impl NonNarrowChar {
         match width {
             0 => NonNarrowChar::ZeroWidth(pos),
             2 => NonNarrowChar::Wide(pos),
+            4 => NonNarrowChar::Tab(pos),
             _ => panic!("width {} given for non-narrow character", width),
         }
     }
@@ -518,7 +521,8 @@ impl NonNarrowChar {
     pub fn pos(&self) -> BytePos {
         match *self {
             NonNarrowChar::ZeroWidth(p) |
-            NonNarrowChar::Wide(p) => p,
+            NonNarrowChar::Wide(p) |
+            NonNarrowChar::Tab(p) => p,
         }
     }
 
@@ -527,6 +531,7 @@ impl NonNarrowChar {
         match *self {
             NonNarrowChar::ZeroWidth(_) => 0,
             NonNarrowChar::Wide(_) => 2,
+            NonNarrowChar::Tab(_) => 4,
         }
     }
 }
@@ -538,6 +543,7 @@ impl Add<BytePos> for NonNarrowChar {
         match self {
             NonNarrowChar::ZeroWidth(pos) => NonNarrowChar::ZeroWidth(pos + rhs),
             NonNarrowChar::Wide(pos) => NonNarrowChar::Wide(pos + rhs),
+            NonNarrowChar::Tab(pos) => NonNarrowChar::Tab(pos + rhs),
         }
     }
 }
@@ -549,6 +555,7 @@ impl Sub<BytePos> for NonNarrowChar {
         match self {
             NonNarrowChar::ZeroWidth(pos) => NonNarrowChar::ZeroWidth(pos - rhs),
             NonNarrowChar::Wide(pos) => NonNarrowChar::Wide(pos - rhs),
+            NonNarrowChar::Tab(pos) => NonNarrowChar::Tab(pos - rhs),
         }
     }
 }
@@ -868,8 +875,10 @@ impl FileMap {
 
     pub fn record_width(&self, pos: BytePos, ch: char) {
         let width = match ch {
-            '\t' | '\n' =>
-                // Tabs will consume one column.
+            '\t' =>
+                // Tabs will consume 4 columns.
+                4,
+            '\n' =>
                 // Make newlines take one column so that displayed spans can point them.
                 1,
             ch =>
diff --git a/src/test/ui/codemap_tests/tab.stderr b/src/test/ui/codemap_tests/tab.stderr
index 41ab60f017f..e95078f2547 100644
--- a/src/test/ui/codemap_tests/tab.stderr
+++ b/src/test/ui/codemap_tests/tab.stderr
@@ -1,16 +1,16 @@
 error[E0425]: cannot find value `bar` in this scope
   --> $DIR/tab.rs:14:2
    |
-14 |  bar; //~ ERROR cannot find value `bar`
-   |  ^^^ not found in this scope
+14 |     bar; //~ ERROR cannot find value `bar`
+   |     ^^^ not found in this scope
 
 error[E0308]: mismatched types
   --> $DIR/tab.rs:18:2
    |
 17 | fn foo() {
    |          - help: try adding a return type: `-> &'static str `
-18 |  "bar   boo" //~ ERROR mismatched types
-   |  ^^^^^^^^^^^ expected (), found reference
+18 |     "bar            boo" //~ ERROR mismatched types
+   |     ^^^^^^^^^^^^^^^^^^^^ expected (), found reference
    |
    = note: expected type `()`
               found type `&'static str`
diff --git a/src/test/ui/codemap_tests/tab_2.stderr b/src/test/ui/codemap_tests/tab_2.stderr
index 7f6b55e7eb8..34c49d97562 100644
--- a/src/test/ui/codemap_tests/tab_2.stderr
+++ b/src/test/ui/codemap_tests/tab_2.stderr
@@ -1,8 +1,8 @@
 error: unterminated double quote string
   --> $DIR/tab_2.rs:14:7
    |
-14 |       """; //~ ERROR unterminated double quote
-   |  _______^
+14 |                   """; //~ ERROR unterminated double quote
+   |  ___________________^
 15 | | }
    | |__^
 
diff --git a/src/test/ui/codemap_tests/tab_3.stderr b/src/test/ui/codemap_tests/tab_3.stderr
index 278e590a36d..32202062663 100644
--- a/src/test/ui/codemap_tests/tab_3.stderr
+++ b/src/test/ui/codemap_tests/tab_3.stderr
@@ -1,11 +1,11 @@
 error[E0382]: use of moved value: `some_vec`
   --> $DIR/tab_3.rs:17:20
    |
-15 |  some_vec.into_iter();
-   |  -------- value moved here
-16 |  {
-17 |   println!("{:?}", some_vec); //~ ERROR use of moved
-   |                    ^^^^^^^^ value used here after move
+15 |     some_vec.into_iter();
+   |     -------- value moved here
+16 |     {
+17 |         println!("{:?}", some_vec); //~ ERROR use of moved
+   |                          ^^^^^^^^ value used here after move
    |
    = note: move occurs because `some_vec` has type `std::vec::Vec<&str>`, which does not implement the `Copy` trait