Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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
# for free to join this conversation on GitHub. Already have an account? # 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