diff --git a/src/librustc_errors/styled_buffer.rs b/src/librustc_errors/styled_buffer.rs index ceb94f27dc3ce..2c33f80520360 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 bf059cac89152..ec652b5607ec4 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 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 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 41ab60f017f61..e95078f25474a 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 7f6b55e7eb8ea..34c49d9756222 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 278e590a36d13..322020626639b 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