-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
rustc_errors: Add (heuristic) Syntax Highlighting for rustc --explain
#150895
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
base: main
Are you sure you want to change the base?
Conversation
Changed `highlight_rustc_lexer` to have only one place where the original lexeme is extracted. This reduces dereferences and slices. Very minor perf change.
|
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
|
r? @fee1-dead rustbot has assigned @fee1-dead. Use |
|
PS (Link to Zulip Topic) : #t-compiler/diagnostics > Colored output for `rustc --explain` |
|
Is this change requires MCP? |
Could you clarify what you mean by MCP? I'm very new to rustc (this is my first contribution) |
|
A process where you propose a change and other members brainstorm it whether it worth adding or not |
Oh thanks. I don't think that this qualifies as a major change. It just adds some very simple code that basically colours tokens by matching on its kind and lexeme. IMO it falls in the light-weight proposal category, as it doesn't break anything (if it errors, the plain block is printed) |
|
I don't think this needs an MCP, it's a reasonably local change that could be backed out at any time. |
|
r? me |
|
Fyi this will need a test somehow, a UI test is probably fine |
The test could probably me giving it a string of code and comparing its colored output to what was expected. |
This comment has been minimized.
This comment has been minimized.
The existing tests need to be updated |
|
IIRC that test can be updated with RUSTC_BLESS=1 |
Could you elaborate please (I'm sorry I'm new to the codebase) |
|
Sorry, you don't need to set that env - just run
Not actually sure why that test failed, the code formatter isn't hooked there. |
The problem was something related to the fast that we use a `Style::new` default style when no style is matched
|
I have fixed the failing test. |
Where would I create the test? |
|
Can we consider colouring all primitives types as well? The same way it was made for keywords |
|
Can Same for |
Sure! |
This would require having to change stuff in a few places (in the same file i believe)
This can done, since iirc |
Feel free to do this changes |
Removed unnecessary wrapper around `write_anstream_buf_with_formatter` and renamed it to `write_anstream_buf`.
Done in #b84220 and #34f6890! cc: @Kivooeo |
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.
All changes looks good to me!
There's just a small typo. Also, I need some more time to think about whether we need to create a test, and if so, how
Co-authored-by: Kivooeo <[email protected]>
Wonderful! I'll push the highlighting for the primitive types tomorrow.
Fixed
Please, take your time :D |
This comment has been minimized.
This comment has been minimized.
Yes any kind of behavior change generally needs a test. Why the green check if you're not yet sure :) @JayanAXHF the test can be the same as |
This approval is for implementation |
What will this look like in the .stdout file? |
I believe it should just show the escape codes, similar to the output.stdout file that's in this PR now (though code highlighting isn't hooked there of course) |
These are two commits squashed together: feat: add support for primitive types refactor: refactor out the list of keywords into a global const
I've just tried this locally. Instead of showing ANSI codes in the .stdout file, it created a basic.svg file containing just a solid black rectangle, which doesn't seem correct Here is what I did so you can try to reproduce it or point out what I might have done wrong (Without specifying --error-format, it gave an error. It seems the --color flag might be for diagnostics) |
Done in 7d96470 |
Would it be fine if the test just focused on the highlighter? |
|
@Kivooeo (cc: @tgross35) I have figured out (i think) why if io::stdout().is_terminal() {
show_md_content_with_pager(&text, color);
} else {
safe_print!("{text}");
}prevents printing the output with color if |
|
Following my previous message, I have added the tests for the highlighter. However, I did have to change |
This comment has been minimized.
This comment has been minimized.
dddc3ea to
f53159e
Compare
| if color == ColorConfig::Always { | ||
| show_md_content_with_pager(&text, color); | ||
| } |
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.
My original thought was to create not a UI test, but something that just tests the highlight function, maybe? I don't really like how this ANSI test looks; this change feels unrelated to this PR, and creating this SVG file is also something that I'd like to try to avoid
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.
I agree with the test looking weird. Should I convert this to a highlighter test? IMO the change, however unrelated, makes the function behave as it should.
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.
Maybe we could do this for different PR if you really thinks so
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.
But I don't really think that this change will address any real problem or even be any kind of improvement (maybe I don't see something about this change, so you could elaborate on this a little more)
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.
The fact that --color always didn't always output in color made its name and description a misnomer. Usually, when you set a program to output color always, it does so, regardless of the output being a terminal or not. This is just my opinion, I'd love to hear what you think about this.
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.
I think it's like #[inline(always)] which is also not always doing inline
Yeah, I think it's better to separate this problems, in this PR we are working on making rustc --explain colourful, and I'd maybe suggest to open a zulip discussion on that matter
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.
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.
I think it's like
#[inline(always)]which is also not always doing inlineYeah, I think it's better to separate this problems, in this PR we are working on making
rustc --explaincolourful, and I'd maybe suggest to open a zulip discussion on that matter
So should I refactor the test to be of the highlighter instead?
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.
So should I refactor the test to be of the highlighter instead?
Yeah would be nice, maybe even revert last commit
I see there is some tests in compiler/rustc_errors/src/markdown/tests/, maybe it would be possible to add such test case somewhere here? Could to take a look on possibility to add a test here? The simplest test would also be fine
This PR adds a feature that enables
rustc --explain <error>to have syntax highlighted code blocks. Due to performance, size and complexity constraints, the highlighter is very heuristc, relying on conventions for capitalizations and such to infer what an identifier represents. The details for the implementation are specified below.Changes
term::entrypointtoterm::entrypoint_with_formatter, which takes an optional third argument, which is a function pointer to a formatter. (compiler/rustc_errors/src/markdown/mod.rs)MdStream::write_anstream_bufto be a wrapper around a new function,MdStream::write_anstream_buf_with_formatter, which takes a function pointer to a formatter. (compiler/rustc_errors/src/markdown/mod.rs)compiler/rustc_driver_impl/src/lib.rsto callMdStream::write_anstream_buf_with_formatterinstead ofMdStream::write_anstream_buf.compiler/rustc_driver_impl/src/highlighter.rsfile, which contains the actual syntax highlighter.Implementation Details
highlightfunction defined incompiler/rustc_driver_impl/src/highlighter.rs. It creates a new instance of theHighlighterstruct, and calls itshighlight_rustc_lexerfunction to start highlighting.highlight_rustc_lexerfunction usesrustc_lexerto lex the code intoTokens.rustc_lexerwas chosen since it preserves the newlines after scanning.TokenKind), we color the corresponding lexeme.Highlighter Implementation
Identifiers
Traitand a type, since that would involve name resolution, and the parts ofrustcthat perform name resolution on code do not preserve the original formatting. (An attempt to userustc_parse's lexer andTokenStreamwas made, which was then printed with the pretty printer, but failed to preserve the formatting and was generally more complex to work with)Literals
Stringliteral (or its correspondingRaw,CandByteversions) is colored green.Everything Else
Everything else is colored bright white and dimmed, to create a grayish colour.
Demo
rustc --explain E0520This description was not generated by an LLM (:p)
cc: @bjorn3