-
-
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
Conversation
|
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. |
|
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 |
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
1755d4d to
19b04f2
Compare
|
ok, looks good now thanks for this @bors r+ |
|
@bors r- wait, actually not can you please squash commits into one before merge? |
|
Commit 19b04f2 has been unapproved. |
19b04f2 to
243874a
Compare
|
Done! cc: @Kivooeo |
This comment has been minimized.
This comment has been minimized.
This commit adds a heuristics-based syntax highlighter for the `rustc --explain` command. It uses `rsutc_lexer`'s lexer to parse input in tokens, and matches on them to determine their color.
243874a to
67c45b7
Compare
|
@bors r+ |
…uwer Rollup of 15 pull requests Successful merges: - #148623 (Ignore `#[doc(hidden)]` items when computing trimmed paths for printing) - #150550 (Miscellaneous cleanups to borrowck related code) - #150879 (Remove the diagnostic lints) - #150895 (rustc_errors: Add (heuristic) Syntax Highlighting for `rustc --explain`) - #150987 (remote-test-server: Fix header in batch mode) - #151004 (std: implement `sleep_until` on Apple platforms) - #151045 (Simplify some literal-value negations with `u128::wrapping_neg`) - #151119 (Support pointers in type reflection) - #151171 (Do not recover from `Trait()` if generic list is unterminated) - #151231 (HIR typeck cleanup: clarify and re-style `check_expr_unop`) - #151249 (Parse ident with allowing recovery when trying to diagnose) - #151295 (THIR patterns: Use `ty::Value` in more places throughout `const_to_pat`) - #151326 (Remove `DiagMessage::Translated` in favour of `DiagMessage::Str`) - #151361 (add test for issue 61463) - #151371 (Add `S-blocked` to `labels_blocking_approval`) r? @ghost
Rollup merge of #150895 - rustc_colored_explain, r=Kivooeo rustc_errors: Add (heuristic) Syntax Highlighting for `rustc --explain` 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 1. Change `term::entrypoint` to `term::entrypoint_with_formatter`, which takes an optional third argument, which is a function pointer to a formatter. ([compiler/rustc_errors/src/markdown/mod.rs](https://github.com/rust-lang/rust/compare/main...JayanAXHF:rust:rustc_colored_explain?expand=1#diff-a6e139cadbc2e6922d816eb08f9e2c7b48304d09e6588227e2b70215c4f0725c)) 2. Change `MdStream::write_anstream_buf` to 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](https://github.com/rust-lang/rust/compare/main...JayanAXHF:rust:rustc_colored_explain?expand=1#diff-a6e139cadbc2e6922d816eb08f9e2c7b48304d09e6588227e2b70215c4f0725c)) 3. Change [`compiler/rustc_driver_impl/src/lib.rs`](https://github.com/rust-lang/rust/compare/main...JayanAXHF:rust:rustc_colored_explain?expand=1#diff-39877a2556ea309c89384956740d5892a59cef024aa9473cce16bbdd99287937) to call `MdStream::write_anstream_buf_with_formatter` instead of `MdStream::write_anstream_buf`. 4. Add a `compiler/rustc_driver_impl/src/highlighter.rs` file, which contains the actual syntax highlighter. # Implementation Details 1. The highlighter starts from the `highlight` function defined in `compiler/rustc_driver_impl/src/highlighter.rs`. It creates a new instance of the `Highlighter` struct, and calls its `highlight_rustc_lexer` function to start highlighting. 2. The `highlight_rustc_lexer` function uses `rustc_lexer` to lex the code into `Token`s. `rustc_lexer` was chosen since it preserves the newlines after scanning. 3. Based on the kind of token (`TokenKind`), we color the corresponding lexeme. ## Highlighter Implementation ### Identifiers 1. All identifiers that match a (non-exhaustive and minimal) list of keywords are coloured magenta. 2. An identifier that begins with a capital letter is assumed as a type. There is no distinction between a `Trait` and a type, since that would involve name resolution, and the parts of `rustc` that perform name resolution on code do not preserve the original formatting. (An attempt to use `rustc_parse`'s lexer and `TokenStream` was made, which was then printed with the pretty printer, but failed to preserve the formatting and was generally more complex to work with) 3. An identifier that is immediately followed by a parenthesis is recognized as a function identifier, and coloured blue. ## Literals 5. A `String` literal (or its corresponding `Raw`, `C` and `Byte` versions) is colored green. 6. All other literals are colored bright red (orange-esque) ## Everything Else Everything else is colored bright white and dimmed, to create a grayish colour. --- # Demo <img width="1864" height="2136" alt="image" src="https://github.com/user-attachments/assets/b17d3a71-e641-4457-be85-5e5b1cea2954" /> <caption> Command: <code>rustc --explain E0520</code> </caption> --- This description was not generated by an LLM (:p) cc: @bjorn3
…uwer Rollup of 15 pull requests Successful merges: - rust-lang/rust#148623 (Ignore `#[doc(hidden)]` items when computing trimmed paths for printing) - rust-lang/rust#150550 (Miscellaneous cleanups to borrowck related code) - rust-lang/rust#150879 (Remove the diagnostic lints) - rust-lang/rust#150895 (rustc_errors: Add (heuristic) Syntax Highlighting for `rustc --explain`) - rust-lang/rust#150987 (remote-test-server: Fix header in batch mode) - rust-lang/rust#151004 (std: implement `sleep_until` on Apple platforms) - rust-lang/rust#151045 (Simplify some literal-value negations with `u128::wrapping_neg`) - rust-lang/rust#151119 (Support pointers in type reflection) - rust-lang/rust#151171 (Do not recover from `Trait()` if generic list is unterminated) - rust-lang/rust#151231 (HIR typeck cleanup: clarify and re-style `check_expr_unop`) - rust-lang/rust#151249 (Parse ident with allowing recovery when trying to diagnose) - rust-lang/rust#151295 (THIR patterns: Use `ty::Value` in more places throughout `const_to_pat`) - rust-lang/rust#151326 (Remove `DiagMessage::Translated` in favour of `DiagMessage::Str`) - rust-lang/rust#151361 (add test for issue 61463) - rust-lang/rust#151371 (Add `S-blocked` to `labels_blocking_approval`) r? @ghost
…uwer Rollup of 15 pull requests Successful merges: - rust-lang/rust#148623 (Ignore `#[doc(hidden)]` items when computing trimmed paths for printing) - rust-lang/rust#150550 (Miscellaneous cleanups to borrowck related code) - rust-lang/rust#150879 (Remove the diagnostic lints) - rust-lang/rust#150895 (rustc_errors: Add (heuristic) Syntax Highlighting for `rustc --explain`) - rust-lang/rust#150987 (remote-test-server: Fix header in batch mode) - rust-lang/rust#151004 (std: implement `sleep_until` on Apple platforms) - rust-lang/rust#151045 (Simplify some literal-value negations with `u128::wrapping_neg`) - rust-lang/rust#151119 (Support pointers in type reflection) - rust-lang/rust#151171 (Do not recover from `Trait()` if generic list is unterminated) - rust-lang/rust#151231 (HIR typeck cleanup: clarify and re-style `check_expr_unop`) - rust-lang/rust#151249 (Parse ident with allowing recovery when trying to diagnose) - rust-lang/rust#151295 (THIR patterns: Use `ty::Value` in more places throughout `const_to_pat`) - rust-lang/rust#151326 (Remove `DiagMessage::Translated` in favour of `DiagMessage::Str`) - rust-lang/rust#151361 (add test for issue 61463) - rust-lang/rust#151371 (Add `S-blocked` to `labels_blocking_approval`) r? @ghost
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