-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Mispositioned error-indicator at compile-time #38384
Comments
Hello fellow tabs user! I have experienced this too, I was just too lazy to do a bug report. Thanks for filing it :) |
Before rendering compiler messages to-be-printed are analyzed and some spaces are replaced with tabs in order to respect identation in the code. All that is done heuristically on a best-effort basis. Now we even multiline spans in nightly, which makes this problem even more difficult to solve. That means simply replacing a few spaces with tabs is not sufficient anymore. My opinion is that it would be best to simply render all tabs from the source code as 4 spaces in stderr. Anything else will be even more buggy. @jonathandturner Thoughts? If you agree, I'll make a PR. |
Tabs should be handled by putting a tab in the matching output. Seems that is not the right answer for all situations? I'm confused as to why this isn't working, as the original example seems like it should work okay. |
Do you have a smaller repro we could use to fix the issue? |
(btw, sorry for the delay in response, I've been on an extended vacation) |
No. Take a look at this example:
We have these lines connecting "starting here" and "ending here". How many underscores should those lines have? Depends on how many spaces your terminal/text editor/IDE/browser uses to display tabs. Ultimately, it's impossible to render error messages together with tabs properly accross all environments. Another option would be to convert tabs into 4 spaces before rendering. Then error/warning markers will not be misaligned with code - that's the major advantage of converting tabs to spaces. |
There is no work-around for this that I can see, even setting tab-width to 4 doesn't work since the LHS number output is variable-width. |
As @stjepang said I think the best soltution is to render the tabs as spaces for the error output. It might be theorically possible to get the tab size from the terminal but that sounds like more effort this it is worth. I am rarely (never) copying the output of errors back into my source so it shouldn't be an issue. A bouns feature would be user-adjustable tab size but starting with 2 or 4 is probably sufficent. |
Also is there any way to get this prioritized? It seems like having unaligned error messages is unacceptable as the text relies on the range indicators to make any sense. |
Why not preserving the whitespace-chars of the specific line as given in the source, just replacing everything else from the occurrence of the first non-white-space on? |
It should be safe to "repeat" the given line, and replace the non-whitespace-content with the debug output. Imagine the following:
To handle that situation in line 4 right, the following steps should work:
|
@florianb I think the only way to resolve this is to replace each tab with a fixed amount of spaces. Your suggestion doesn't work because of cases like: fn main() {
""";
} Giving you errors like:
It needs to draw the entire line with |
@est31 - thanks i didn't think of that case. |
Studying clang/gccFrom a suggestion by @eddyb on IRC on what gcc/clang do, I've looked at their behaviour.
For gcc, I've omitted the last character to produce an invalid string literal. It gave the following error:
Both treated the Now let's add a space to test whether they implement a "tab stop" algorithm, or a "tab == 4 whitespace" one. Clang output when I add one space before the
One space more between the line start and Gcc output of the same (with the last " removed):
So clang basically implements the full "tab == go to the next tab stop" algorithm, while gcc replaces each tab by one whitespace, and continues to print whitespaces next to tabs. Used versions: Plan for rustcI suggest to take a similar path to the one clang is going, by keeping the column number as it is right now (the same that clang/gcc are using), and by either printing out each tab as 4 spaces or alternatively by implementing the full tab stop algorithm that apparently clang is doing. I'm generally neutral as to whether implement Further points
|
@est31 That sounds good. Yes, it's critical that the column number in the error messages count charaters. IIUC this issue is just that the printed messages don't lign up correctly because it prints some tabs in the source and expects to be able to line up some individual characters next to it. As far as tab-stops vs simple expansion for the error message I don't think it matters too much. |
Simple replacement will break formatting for (bad-style) code. Obviously no-one should be using tabs after normal characters but some people will be and they will complain. Better just fix the problem now before it gets filed as an issue. |
@Vurich: unfortunately the concept of elastic tabstops is emerging. |
@Vurich while you are correct, it isn't relly possible to do that without knowing what that author has configured their tab size to. I guess it would be nice to do the work in tabstops with some value which could be adjusted but it seems like this case will never just work. We could consider making it configurable or looking for an All that being said I am clearly biased because I don't do this myself. It would be interesting to see if and how clang and GCC deal with this. I would assume they don't but I haven't tested. |
That's fair, I'm convinced. Still, 4-space tabstops will never break anything that simple replacement won't break even worse and it's a pretty safe default to assume. |
I think providing configuration options or following an editorconfig or similar are overengineering, but even if we want to add something like that, providing a support for 4-space tabstops is an important first step. I'll check tomorrow whether I want to provide a PR to fix at least this issue with the plan I've proposed above. If anyone of you is very eager to do the implementation themselves, please speak up! |
With my PR #44386 I've chosen to go with gcc's strategy for now (tab mapped to one space always). Its the easiest to implement, and fixes the actual issue of mispositioning. Obviously its not beautiful, but if anyone wants to improve on that, please do so! |
Fixes rust-lang#38384 Most of the Rust community uses 4 spaces for indentation, but there are also tab users of Rust (including myself!). This patch fixes a bug in error printing which mispositions error indicators when near code with tabs. The code attempted to fix the issue by replacing spaces with tabs, but it sadly wasn't enough, as sometimes you may not print spaces but _ or ^ instead. This patch employs the reverse strategy: it replaces each tab with a space, so that the number of _ and ^ and spaces in error indicators below the code snippet line up perfectly. In a study [1] preceeding this patch, we could see that this strategy is also chosen by gcc version 6.3.0. Its not perfect, as the output is not beautiful, but its the easiest to implement. If anyone wants to improve on this, be my guest! This patch is meant as improvement of the status quo, not as perfect end status. It fixes the actual issue of mispositioning error indicators. [1]: rust-lang#38384 (comment)
Fix mispositioned error indicators Fixes #38384 Most of the Rust community uses 4 spaces for indentation, but there are also tab users of Rust (including myself!). This patch fixes a bug in error printing which mispositions error indicators when near code with tabs. The code attempted to fix the issue by replacing spaces with tabs, but it sadly wasn't enough, as sometimes you may not print spaces but _ or ^ instead. This patch employs the reverse strategy: it replaces each tab with a space, so that the number of _ and ^ and spaces in error indicators below the code snippet line up perfectly. In a study [1] preceeding this patch, we could see that this strategy is also chosen by gcc version 6.3.0. Its not perfect, as the output is not beautiful, but its the easiest to implement. If anyone wants to improve on this, be my guest! This patch is meant as improvement of the status quo, not as perfect end status. It fixes the actual issue of mispositioning error indicators. [1]: #38384 (comment)
I've filed #44618 as a follow-up to not forget about the clang option |
There's been a regression on this with help spans. See #47377 . The tests |
The positional indicator of the moved value appears with the wrong indentation as you can see in the screenshot:
Apparently i don't know why this happens, i am using tabs (with 4 spaces width) to format my source. In the reality these lines look as follows:
Versions
The text was updated successfully, but these errors were encountered: