Skip to content
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

Replace tabs earlier in diagnostics #79757

Merged
merged 2 commits into from
Jan 12, 2021

Conversation

jryans
Copy link
Contributor

@jryans jryans commented Dec 6, 2020

This replaces tabs earlier in the diagnostics emitting process, which allows various margin calculations to ignore the existence of tabs. It does add a string copy for the source lines that are emitted.

Fixes #78438

r? @estebank

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 6, 2020
@jryans
Copy link
Contributor Author

jryans commented Dec 6, 2020

It was not enough to just edit places where we check Unicode width, as many other margin calculations are also impacted. This approach seems like the simplest thing I could think of given the problem we're trying to solve.

I did also experiment with wrapper types to clearly delineate the different kinds of lengths / offsets, but it's much more verbose and a much larger change, which I am not sure is worth the trouble. I believe it would avoid the string copy though.

@jryans jryans force-pushed the long-line-tab-handling-early-expand branch from 04aa312 to 485efb1 Compare December 6, 2020 01:37
@jryans jryans force-pushed the long-line-tab-handling-early-expand branch from 485efb1 to 507cabd Compare December 6, 2020 02:32
@jryans
Copy link
Contributor Author

jryans commented Dec 6, 2020

Ah, hmm, I guess there are a few remaining failures because some tabs were making it through to StyledBuffer. (It's a bit hard to read the UI test failures locally for me, as there are quite a few that fail locally but work on CI...)

Anyway, I'm curious what you think about the approach generally. If it seems broadly okay, I'll adjust things further to fix up the remaining tests.

Comment on lines -28 to -32
let s = self.styles[line_pos].remove(*pos);
for _ in 0..4 {
line.insert(*pos, ' ');
self.styles[line_pos].insert(*pos, s);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm slightly concerned by this removal. Have you tried to see the output in your local CLI? I need to double check the code, but can you confirm that the underlines are all colored correctly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is safe, since the style handling here is about adjusting them for the adding tabs, but we now handle the tabs earlier on, so there's no need to adjust at this stage any more.

The output looks correct to me as well. Here are a few examples:

image

image

@estebank
Copy link
Contributor

estebank commented Dec 8, 2020

The chances look reasonable, I need to read it again to make sure that everything is correct, but provisionally r=me. Could you address @pickfire's comment about replace and post a screenshot of the new output?

@jryans jryans force-pushed the long-line-tab-handling-early-expand branch from 507cabd to ad0a30e Compare December 8, 2020 15:39
@jryans
Copy link
Contributor Author

jryans commented Dec 8, 2020

@estebank Thanks for the initial look! 😄 This should now be ready for a full review. Changes since last time:

  • Switched to replace
  • Added screenshots
  • Updated other paths that print source lines to replace as well
  • Added assertions to ensure no stray tabs slip through

Copy link
Contributor

@pickfire pickfire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

This replaces tabs earlier in the diagnostics emitting process, which allows
various margin calculations to ignore the existence of tabs. It does add a
string copy for the source lines that are emitted.
@jryans jryans force-pushed the long-line-tab-handling-early-expand branch from ad0a30e to 3537bd8 Compare December 9, 2020 10:12
@jryans
Copy link
Contributor Author

jryans commented Dec 9, 2020

I made a small cleanup change after @pickfire's latest review:

  • StyledBuffer.render no longer mutates, so I changed it to &self

@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 11, 2021
@jryans
Copy link
Contributor Author

jryans commented Jan 11, 2021

@estebank Just a friendly reminder that this is ready for another review. 😄 I’m hoping to work my way up to eventually helping with the review load as well.

Comment on lines +647 to +648
// Tabs are assumed to have been replaced by spaces in calling code.
assert!(!source_string.contains('\t'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit heavy handed but ok with me (I will assume we'll see reports on nightly if this causes issues before it hits stable).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay, mostly I just wanted it to be ultra clear to future code readers which paths should not have tabs, but it could be relaxed to a comment of course. I'll check json output now.

@estebank
Copy link
Contributor

@estebank Just a friendly reminder that this is ready for another review. 😄 I’m hoping to work my way up to eventually helping with the review load as well.

No worries! Apologies, I was offline for all of December, which is why my personal queue has grown dramatically 😅

The changes look all great. I'm approving, but could you also check that the --output=json works correctly (without triggering the asserts)? If you don't get to it, I'll try it out tomorrow on nightly.

Super happy to see this fixed!

@estebank
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Jan 12, 2021

📌 Commit 3537bd8 has been approved by estebank

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 12, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Jan 12, 2021
Rollup of 8 pull requests

Successful merges:

 - rust-lang#79757 (Replace tabs earlier in diagnostics)
 - rust-lang#80600 (Add `MaybeUninit` method `array_assume_init`)
 - rust-lang#80880 (Move some tests to more reasonable directories)
 - rust-lang#80897 (driver: Use `atty` instead of rolling our own)
 - rust-lang#80898 (Add another test case for rust-lang#79808)
 - rust-lang#80917 (core/slice: remove doc comment about scoped borrow)
 - rust-lang#80927 (Replace a simple `if let` with the `matches` macro)
 - rust-lang#80930 (fix typo in trait method mutability mismatch help)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@jryans
Copy link
Contributor Author

jryans commented Jan 12, 2021

could you also check that the --output=json works correctly (without triggering the asserts)? If you don't get to it, I'll try it out tomorrow on nightly.

@estebank I couldn't find any --output=json flag in rustc or cargo, but I am guessing perhaps you meant rustc's --error-format=json? If yes, then that seems to work correctly for the test case in this PR (without triggering the assertions):

$ ./build/x86_64-apple-darwin/stage1/bin/rustc src/test/ui/terminal-width/tabs-trimming.rs --error-format=json
{"message":"variable `v` is not bound in all patterns","code":{"code":"E0408","explanation":"An \"or\" pattern was used where the variable bindings are not consistently bound\nacross patterns.\n\nErroneous code example:\n\n```compile_fail,E0408\nmatch x {\n    Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is\n                                      //        not bound in pattern #2\n    _ => ()\n}\n```\n\nHere, `y` is bound to the contents of the `Some` and can be used within the\nblock corresponding to the match arm. However, in case `x` is `None`, we have\nnot specified what `y` is, and the block will use a nonexistent variable.\n\nTo fix this error, either split into multiple match arms:\n\n```\nlet x = Some(1);\nmatch x {\n    Some(y) => { /* use y */ }\n    None => { /* ... */ }\n}\n```\n\nor, bind the variable to a field of the same type in all sub-patterns of the\nor pattern:\n\n```\nlet x = (0, 2);\nmatch x {\n    (0, y) | (y, 0) => { /* use y */}\n    _ => {}\n}\n```\n\nIn this example, if `x` matches the pattern `(0, _)`, the second field is set\nto `y`. If it matches `(_, 0)`, the first field is set to `y`; so in all\ncases `y` is set to some value.\n"},"level":"error","spans":[{"file_name":"src/test/ui/terminal-width/tabs-trimming.rs","byte_start":222,"byte_end":223,"line_start":9,"line_end":9,"column_start":16,"column_end":17,"is_primary":true,"text":[{"text":"\t\t\t\t\t\t\tv @ 1 | 2 | 3 => panic!(\"You gave me too little money {}\", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT","highlight_start":16,"highlight_end":17}],"label":"pattern doesn't bind `v`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/test/ui/terminal-width/tabs-trimming.rs","byte_start":226,"byte_end":227,"line_start":9,"line_end":9,"column_start":20,"column_end":21,"is_primary":true,"text":[{"text":"\t\t\t\t\t\t\tv @ 1 | 2 | 3 => panic!(\"You gave me too little money {}\", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT","highlight_start":20,"highlight_end":21}],"label":"pattern doesn't bind `v`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/test/ui/terminal-width/tabs-trimming.rs","byte_start":214,"byte_end":215,"line_start":9,"line_end":9,"column_start":8,"column_end":9,"is_primary":false,"text":[{"text":"\t\t\t\t\t\t\tv @ 1 | 2 | 3 => panic!(\"You gave me too little money {}\", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT","highlight_start":8,"highlight_end":9}],"label":"variable not in all patterns","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0408]: variable `v` is not bound in all patterns\n --> src/test/ui/terminal-width/tabs-trimming.rs:9:16\n  |\n9 | ...   v @ 1 | 2 | 3 => panic!(\"You gave me too little money {}\", v), // Long text here: TTTTTTTT...\n  |       -       ^   ^ pattern doesn't bind `v`\n  |       |       |\n  |       |       pattern doesn't bind `v`\n  |       variable not in all patterns\n\n"}
{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error\n\n"}
{"message":"For more information about this error, try `rustc --explain E0408`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0408`.\n"}

@bors
Copy link
Contributor

bors commented Jan 12, 2021

⌛ Testing commit 3537bd8 with merge b6b4616...

@bors bors merged commit 86b900a into rust-lang:master Jan 12, 2021
@rustbot rustbot added this to the 1.51.0 milestone Jan 12, 2021
jryans added a commit to jryans/rust that referenced this pull request Feb 3, 2021
The tab replacement for diagnostics added in rust-lang#79757 included a few assertions to
ensure all tab characters are handled appropriately. We've started getting
reports of these assertions firing (rust-lang#81614). Since it's only a cosmetic issue,
this downgrades the assertions to debug only, so we at least continue compiling
even if the diagnostics might be a tad wonky.

Fixes rust-lang#81614
m-ou-se added a commit to m-ou-se/rust that referenced this pull request Feb 3, 2021
…tebank

Reduce tab formatting assertions to debug only

The tab replacement for diagnostics added in rust-lang#79757 included a few assertions to ensure all tab characters are handled appropriately. We've started getting reports of these assertions firing (rust-lang#81614). Since it's only a cosmetic issue, this downgrades the assertions to debug only, so we at least continue compiling even if the diagnostics might be a tad wonky.

Minimizes the impact of rust-lang#81614
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Long line printing doesn't support tabs
7 participants