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

async and other Rust 2018+ keywords not recognized as so in Rustdoc highlighting #80004

Closed
ThePuzzlemaker opened this issue Dec 13, 2020 · 15 comments · Fixed by #80226
Closed
Assignees
Labels
A-async-await Area: Async & Await A-rustdoc-ui Area: rustdoc UI (generated HTML) AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@ThePuzzlemaker
Copy link
Contributor

ThePuzzlemaker commented Dec 13, 2020

I tried this code:

/// ```rust ignore
/// fn foo(bar: &dyn Baz);
/// async fn quux() {
///     qaz.frobnify().await;
/// }
/// fn bar() {
///     let mut a = 0;
///     abstract blah; /// is a reserved keyword
/// }
/// ```
fn foo() {}

I expected to see this happen: async and other Rust 2018+ keywords are highlighted as my project is set to edition = "2018" in its Cargo.toml

Instead, this happened: They were not highlighted, but regular keywords (including reserved ones) were.
image

I believe that the reason why this is happening is this snippet in librustdoc:

TokenKind::Ident => match text {
"ref" | "mut" => Class::RefKeyWord,
"self" | "Self" => Class::Self_,
"false" | "true" => Class::Bool,
"Option" | "Result" => Class::PreludeTy,
"Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
// Keywords are also included in the identifier set.
_ if Ident::from_str(text).is_reserved() => Class::KeyWord,
_ if self.in_macro_nonterminal => {
self.in_macro_nonterminal = false;
Class::MacroNonTerminal
}
_ => Class::Ident,
},

In this case, Ident::from_str will only create a dummy span (which isn't set to 2018 edition), so is_reserved does not include 2018+ keywords.

I would be willing to try to work on a PR to fix this issue if it is deemed worthy.

Meta

Tested

rustc --version --verbose:
stable:

rustc 1.48.0 (7eac88abb 2020-11-16)
binary: rustc
commit-hash: 7eac88abb2e57e752f3302f02be5f3ce3d7adfb4
commit-date: 2020-11-16
host: x86_64-unknown-linux-gnu
release: 1.48.0
LLVM version: 11.0

nightly:

rustc 1.50.0-nightly (7efc097c4 2020-12-12)
binary: rustc
commit-hash: 7efc097c4fe6e97f54a44cee91c56189e9ddb41c
commit-date: 2020-12-12
host: x86_64-unknown-linux-gnu
release: 1.50.0-nightly

Backtrace is not applicable.

@ThePuzzlemaker ThePuzzlemaker added the C-bug Category: This is a bug. label Dec 13, 2020
@ThePuzzlemaker
Copy link
Contributor Author

@rustbot label +T-rustdoc +A-rustdoc-ui +A-async-await
Hope these labels are accurate and helpful.

@rustbot rustbot added A-async-await Area: Async & Await A-rustdoc-ui Area: rustdoc UI (generated HTML) T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Dec 13, 2020
@tmandry tmandry added the AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. label Dec 17, 2020
@tmandry
Copy link
Member

tmandry commented Dec 17, 2020

@ThePuzzlemaker I think you have the right idea, though someone from the Rustdoc team might also be able to help with the details (cc @jyn514).

A PR would be welcome! Feel free to claim the issue with @rustbot claim. If you have questions, I'm also available to help here or on Zulip or DIscord, but my availability may be spotty over the next week.

@ThePuzzlemaker
Copy link
Contributor Author

@rustbot claim

@jyn514
Copy link
Member

jyn514 commented Dec 17, 2020

Yup, that looks right, good catch! The only tricky thing will be passing in a span in to Classifier::new, but I think all the callsites have access to at least a Session, and you can get an edition from there.

@ThePuzzlemaker
Copy link
Contributor Author

@rustbot release-assignment
I'm going to release assignment as I'm still not quite sure how this could be achieved even after looking through a bit of code.

@jyn514
Copy link
Member

jyn514 commented Dec 18, 2020

@ThePuzzlemaker where did you get stuck? I might be able to help.

@ThePuzzlemaker
Copy link
Contributor Author

@jyn514 I couldn't find a way to get access to a Session or how I even get a Span from the lexer. I guess I'll reclaim though.
@rustbot claim

@jyn514
Copy link
Member

jyn514 commented Dec 20, 2020

@ThePuzzlemaker you need to follow the call chain up until you get to somewhere that has a Session. If nothing else, run_renderer has one, but I bet you can get it a lot more easily if you find a function with a context of some kind; then just pass the session as an argument until it gets to where it needs to be. (Alternatively, you could just pass the edition instead.)

@ThePuzzlemaker
Copy link
Contributor Author

I guess if I just add it to the Session::new function then I can just follow the errors up.

@jyn514
Copy link
Member

jyn514 commented Dec 20, 2020

Wait, I'm confused - Session::new isn't part of rustdoc, and the code constructing a session will not be in rustdoc code. I recommend using rust-analyzer and go-to-definition to find all the callers of a function.

@jyn514 jyn514 closed this as completed Dec 20, 2020
@jyn514 jyn514 reopened this Dec 20, 2020
@ThePuzzlemaker
Copy link
Contributor Author

I mean Classifier::new or whatever

@ThePuzzlemaker
Copy link
Contributor Author

It looks like you can change the edition of a code block so I'll just do something like this:

  • Highlight 2018 keywords if edition is explicitly set to 2018, don't if it's explicitly set to not 2018
  • Highlight 2018 keywords if edition is set to 2018 for a crate and it's not explicitly set in the code block

@ThePuzzlemaker
Copy link
Contributor Author

ThePuzzlemaker commented Dec 20, 2020

Hm, looks like I'm stuck again. I was able to pass an Edition to the Classifier but I don't know how to check Ident.is_reserved with an arbitrary edition (as to change the edition you'd have to make a Span, but I don't know how to get one for this case, and using a dummy span probably wouldn't work as you'd need a SyntaxContext to make a dummy span with a specific edition and I don't know how to get that either).

@ThePuzzlemaker
Copy link
Contributor Author

ThePuzzlemaker commented Dec 20, 2020

I guess I could make a function Ident.is_reserved_for_edition and then have Ident.is_reserved just call that with the edition of the span in the ident (as since edition 2021 is around the corner, might as well make it a bit forwards-compatible 🙂)

@ThePuzzlemaker
Copy link
Contributor Author

:) my changes worked, now to test and make sure they didn't bork anything else
edition = "2015":
image
edition = "2018":
image

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Dec 23, 2020
…yn514,petrochenkov

Highlight edition-specific keywords correctly in code blocks, accounting for code block edition modifiers

Previously, edition-specific keywords (such as `async` and `await`) were not highlighted in code blocks, regardless of what edition was set. With this PR, this issue is fixed.

Now, the following behavior happens:
- When a code block is explicitly set to edition X, keywords from edition X are highlighted
- When a code block is explicitly set to a version that does not contain those keywords from edition X (e.g. edition Y), keywords from edition X are **not** highlighted
- When a code block has no explicit edition, keywords from the edition passed via `--edition` to rustdoc are highlighted

For example, a project set with `edition = "2015"` in its `Cargo.toml` would not highlight `async`/`await` unless the code block was set to `edition2018`. Additionally, a project set with `edition = "2018"` in its `Cargo.toml` *would* highlight `async`/`await` unless the code block was set to a version that did not contain those keywords (e.g. `edition2015`).

This PR fixes rust-lang#80004.

r? `@jyn514`
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Dec 24, 2020
…yn514,petrochenkov

Highlight edition-specific keywords correctly in code blocks, accounting for code block edition modifiers

Previously, edition-specific keywords (such as `async` and `await`) were not highlighted in code blocks, regardless of what edition was set. With this PR, this issue is fixed.

Now, the following behavior happens:
- When a code block is explicitly set to edition X, keywords from edition X are highlighted
- When a code block is explicitly set to a version that does not contain those keywords from edition X (e.g. edition Y), keywords from edition X are **not** highlighted
- When a code block has no explicit edition, keywords from the edition passed via `--edition` to rustdoc are highlighted

For example, a project set with `edition = "2015"` in its `Cargo.toml` would not highlight `async`/`await` unless the code block was set to `edition2018`. Additionally, a project set with `edition = "2018"` in its `Cargo.toml` *would* highlight `async`/`await` unless the code block was set to a version that did not contain those keywords (e.g. `edition2015`).

This PR fixes rust-lang#80004.

r? ```@jyn514```
@bors bors closed this as completed in ab10778 Dec 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await A-rustdoc-ui Area: rustdoc UI (generated HTML) AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
4 participants