-
Notifications
You must be signed in to change notification settings - Fork 902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix tabs having a fixed width internally #5039
base: master
Are you sure you want to change the base?
Conversation
Ref rust-lang#4968. Tabs were always counted to have a width of config.tab_spaces. Since they actually can have less than that depending on the line"s previous contents, rustfmt would sometimes complain about the line length even if the line did actually fit.
Looks like this still fails if there is more than one tab character in a line. |
@MitMaro - thanks for sharing! sounds straightforward enough, but do you have a snippet you"d be willing to share? that makes adding a corresponding test case a bit easier |
Here"s a test case (based on the one above) that still causes a panic: // rustfmt-error_on_unformatted: true
// rustfmt-error_on_line_overflow: true
// Part of #4968. This line has a width of 100, so it should be fine, but rustfmt panicked.
fn panic_with_tabs() {
let a = "tab here: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonu est \
est, consetetur sadipscing";
} Here"s the stack:
|
Another test case, and one I reduced from one of my projects that still causes a crash in rustfmt is leading tabs with // rustfmt-error_on_unformatted: true
// rustfmt-error_on_line_overflow: true
// rustfmt-hard_tabs: true
fn panic_with_tabs() {
let a = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
}
|
Right. I didn"t fix the entire bug, only those (few) cases where the line would actually fit into the width limit. See my comment here: #4968 (comment) |
@@ -559,7 +559,7 @@ impl<'a> FormatLines<'a> { | |||
fn char(&mut self, c: char, kind: FullCodeCharKind) { | |||
self.newline_count = 0; | |||
self.line_len += if c == '\t' { | |||
self.config.tab_spaces() | |||
self.config.tab_spaces() - self.line_len % self.config.tab_spaces() | |||
} else { | |||
1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 1
can also cause issues with non-ascii idents. Could be c.len_utf8()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another possible fix for tabs is to use self.line_buffer.push_str(&" ".repeat(self.config.tab_spaces()))
. Not sure which is correct.
* Internally, rustfmt preserves tabs and counts them as multiple characters (based on configuration). * The annoted_snippet dependency counts tabs as 1 character. * If rustfmt produces an error on a line containing tabs, annotated_snippet may think that the error is out of range and panic. * Have rustfmt internally replace tabs with the corresponding number of spaces, so that columns can be counted unambiguously. * This change is based on PR rust-lang#5039 by karyon, but with the code review suggestions by camsteffen.
* Internally, rustfmt preserves tabs and counts them as multiple characters (based on configuration). * The annotated_snippet dependency always counts tabs as 1 character. * If rustfmt tries to display an error on a line containing tabs, the indicies are mismatched. * In the extreme case, annotated_snippet may try to access out-of-range indices, and panic. * This change is based on the code review by camsteffen on PR rust-lang#5039 by karyon: have rustfmt internally replace tabs with the corresponding number of spaces, so that columns/indices in the buffer passed to annotated_snippet are counted (unambiguously and) the same.
* Internally, rustfmt preserves tabs and counts them as multiple characters (based on configuration). * The annotated_snippet dependency always counts tabs as 1 character. * If rustfmt tries to display an error on a line containing tabs, the indicies are mismatched. * In the extreme case, annotated_snippet may try to access out-of-range indices, and panic. * This change is based on the code review by camsteffen on PR rust-lang#5039 by karyon: have rustfmt internally replace tabs with the corresponding number of spaces, so that columns/indices in the buffer passed to annotated_snippet are counted (unambiguously and) the same.
* This change is based on the code review by camsteffen on PR rust-lang#5039 by karyon: have rustfmt internally replace tabs with the corresponding number of spaces, so that columns/indices in the buffer passed to annotated_snippet are counted unambiguously.
@karyon @camsteffen gentle ping |
@drahnr neither of us can do anything to advance this PR AFAICT. The maintainers have to action on it. |
* This change is based on the code review by camsteffen on PR rust-lang#5039 by karyon: have rustfmt internally replace tabs with the corresponding number of spaces, so that columns/indices in the buffer passed to annotated_snippet are counted unambiguously.
Ref #4968. Tabs were always counted to have a width of config.tab_spaces.
Since they actually can have less than that depending on the line"s
previous contents, rustfmt would sometimes complain about the line
length even if the line did actually fit.