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

Migrate rustdoc from Tera to Askama #92526

Merged
merged 3 commits into from
Jan 13, 2022
Merged

Migrate rustdoc from Tera to Askama #92526

merged 3 commits into from
Jan 13, 2022

Conversation

djc
Copy link
Contributor

@djc djc commented Jan 3, 2022

See #84419.

Should probably get a benchmarking run to verify if it has the intended effect on rustdoc performance.

cc @jsha @jyn514.

@rust-highfive
Copy link
Collaborator

r? @GuillaumeGomez

(rust-highfive has picked a reviewer for you, use r? to override)

@rustbot rustbot added the T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. label Jan 3, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 3, 2022
@GuillaumeGomez
Copy link
Member

Let's check perf.

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 3, 2022
@bors
Copy link
Contributor

bors commented Jan 3, 2022

⌛ Trying commit 05465c2f5081b3d866854d74745029f0bace4b63 with merge e9be93a5f7d0a32ad8a9f6a1794ee49ef250d8fa...

Copy link
Contributor

@jsha jsha left a comment

Choose a reason for hiding this comment

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

Thanks for working on this! Overall looks great. A few questions below.

src/librustdoc/templates/page.html Show resolved Hide resolved
src/librustdoc/templates/page.html Outdated Show resolved Hide resolved
@bors
Copy link
Contributor

bors commented Jan 3, 2022

☀️ Try build successful - checks-actions
Build commit: e9be93a5f7d0a32ad8a9f6a1794ee49ef250d8fa (e9be93a5f7d0a32ad8a9f6a1794ee49ef250d8fa)

@rust-timer
Copy link
Collaborator

Queued e9be93a5f7d0a32ad8a9f6a1794ee49ef250d8fa with parent ddabe07, future comparison URL.

@@ -143,8 +139,7 @@ pub(super) fn print_item(
src_href: src_href.as_deref(),
};

let teractx = tera::Context::from_serialize(item_vars).unwrap();
let heading = templates.render("print_item.html", &teractx).unwrap();
let heading = item_vars.render().unwrap();
Copy link
Contributor Author

@djc djc Jan 3, 2022

Choose a reason for hiding this comment

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

A further performance improvement here would be to make sure that Buffer impls core::fmt::Write, in which case we could use render_into(buf) rather than render(), avoiding the allocation of a temporary String here. Buffer internally seems to just hold a String and it has write_str() and write_fmt() methods already, so perhaps it would make sense to implement that trait? I'm not sure how big/relevant the performance improvement would be.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (e9be93a5f7d0a32ad8a9f6a1794ee49ef250d8fa): comparison url.

Summary: This change led to very large relevant improvements 🎉 in compiler performance.

  • Very large improvement in instruction counts (up to -30.8% on full builds of externs)

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 3, 2022
@djc
Copy link
Contributor Author

djc commented Jan 3, 2022

Looks like this easily wins back performance from #89695 and thus fixes #89732:

Benchmark & Profile Scenario % Change Significance factor Before #89695 After #89695 This PR
externs full -30.82% 210.60x 4189786474.00 4344364681.00 2946465638.00
stm32f4 full -12.20%? 39.40x 56031165508.00 57091116514.00 45580042347.00
style-servo full -9.81% 83.44x 59526418329.00 60422392129.00 47964593547.00
html5ever full -3.94% 20.06x 5015123198.00 5043144386.00 4373075414.00

It looks like it's even substantially better than the situation before using Tera.

@GuillaumeGomez
Copy link
Member

GuillaumeGomez commented Jan 3, 2022

So performance is great, code changes look good. Can you confirm that the generated HTML files size doesn't change (before and after this PR) please?

@djc
Copy link
Contributor Author

djc commented Jan 3, 2022

Can you recommend an easy way/entry point on how/where to check that?

@GuillaumeGomez
Copy link
Member

Sure! So first, use x.py doc std --stage 1 to generate docs in build/[your archi]/doc. Then use du -s build/[your archi]/doc. Remove this folder once done and switch to your branch and repeat both commands.

@@ -7,20 +7,20 @@
<meta name="description" content="{{page.description}}"> {#- -#}
<meta name="keywords" content="{{page.keywords}}"> {#- -#}
<title>{{page.title}}</title> {#- -#}
Copy link
Member

Choose a reason for hiding this comment

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

Is there a way to get Askama to automatically strip the extra space rather than having to use {#- -#} all over the place? This is one of my annoyances with templates, and it seems like it should theoretically be solvable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is not currently. Askama is a general-purpose text templating mechanism, and the "extra space" is only useless in the particular context of writing out HTML. I don't know the exact details of how reducing whitespace in a string serialization of the HTML DOM will affect that DOM, but if there is a reliable algorithm to implement that, I'd suggest you open an issue against Askama to discuss how we might support that.

(For example, one way I might imagine doing it is by stripping any whitespace after a newline, but that doesn't remove all the whitespace the {#- -#} currently remove because it leaves the newlines themselves. However, if you strip the newlines themselves you would invalidate content like <img src="foo"\nalt="foo">. So solving this optimally seems like a decently hard problem.)

Copy link
Member

Choose a reason for hiding this comment

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

At least stripping the extra spaces after the newline seems like it'd be good enough to me. Sometimes the newlines can be helpful for debugging the HTML too.

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 don't think I will have time to write code for this, but I'm happy to discuss how it could be implemented and review the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One of the Askama team members submitted a PR for something like this today: https://github.com/djc/askama/pull/598.

@camelid
Copy link
Member

camelid commented Jan 4, 2022

What do the errors look like when a template parameter is used incorrectly? E.g., what's the error when you try to iterate over an integer in a template?

@djc
Copy link
Contributor Author

djc commented Jan 4, 2022

What do the errors look like when a template parameter is used incorrectly? E.g., what's the error when you try to iterate over an integer in a template?

The errors are somewhat painful: you get a normal compiler error but with the span pointing to the derive(Template). As far as I know there is no straightforward way to fix this because (a) procedural macros cannot check types themselves and (b) procedural macros cannot create new spans that point outside the Rust source code. While creating this PR I resorted to using cargo expand to expand the template, copying over the generated code to get a better error, then fixing it up in the template. Ideally you'd write smaller bits of template at a time so that you know roughly where the error would be coming from.

@djc
Copy link
Contributor Author

djc commented Jan 4, 2022

Sure! So first, use x.py doc std --stage 1 to generate docs in build/[your archi]/doc. Then use du -s build/[your archi]/doc. Remove this folder once done and switch to your branch and repeat both commands.

Building the std docs this way errors out for me:

 Documenting core v0.0.0 (/Users/djc/src/rust/library/core)
dyld[64157]: Library not loaded: @rpath/libtest-88c87912f839b84d.dylib
  Referenced from: /Users/djc/src/rust/build/aarch64-apple-darwin/stage1/bin/rustdoc
  Reason: tried: '/Users/djc/src/rust/build/aarch64-apple-darwin/stage1/lib/libtest-88c87912f839b84d.dylib' (no such file), '/Users/djc/src/rust/build/aarch64-apple-darwin/stage1/bin/../lib/libtest-88c87912f839b84d.dylib' (no such file), '/Users/djc/src/rust/build/aarch64-apple-darwin/stage1/bin/../lib/libtest-88c87912f839b84d.dylib' (no such file), '/Users/djc/src/rust/build/aarch64-apple-darwin/stage1-std/release/deps/libtest-88c87912f839b84d.dylib' (no such file), '/Users/djc/src/rust/build/aarch64-apple-darwin/stage0/lib/libtest-88c87912f839b84d.dylib' (no such file), '/Users/djc/lib/libtest-88c87912f839b84d.dylib' (no such file), '/usr/local/lib/libtest-88c87912f839b84d.dylib' (no such file), '/usr/lib/libtest-88c87912f839b84d.dylib' (no such file)

@GuillaumeGomez
Copy link
Member

Ah right, sometimes for whatever reason it just doesn't build. Use x.py clean beforehand and try again... If it still doesn't work, remove everything in the build folder and try again.

I was sure that this issue was fixed though... So weird.

@jyn514
Copy link
Member

jyn514 commented Jan 4, 2022

Documenting core v0.0.0 (/Users/djc/src/rust/library/core)
dyld[64157]: Library not loaded: @rpath/libtest-88c87912f839b84d.dylib
  Referenced from: /Users/djc/src/rust/build/aarch64-apple-darwin/stage1/bin/rustdoc
  Reason: tried: '/Users/djc/src/rust/build/aarch64-apple-darwin/stage1/lib/libtest-88c87912f839b84d.dylib' (no such file)

That looks like you haven't built the standard library yet, which is strange since I thought x.py should build it before building rustdoc ... does x.py build --stage 1 std && x.py doc --stage 1 std help?

@GuillaumeGomez
Copy link
Member

It's in the build requirements normally as you can see here.

@camelid
Copy link
Member

camelid commented Jan 4, 2022

What do the errors look like when a template parameter is used incorrectly? E.g., what's the error when you try to iterate over an integer in a template?

The errors are somewhat painful: you get a normal compiler error but with the span pointing to the derive(Template). As far as I know there is no straightforward way to fix this because (a) procedural macros cannot check types themselves and (b) procedural macros cannot create new spans that point outside the Rust source code. While creating this PR I resorted to using cargo expand to expand the template, copying over the generated code to get a better error, then fixing it up in the template. Ideally you'd write smaller bits of template at a time so that you know roughly where the error would be coming from.

Hmm... I wonder if there's a way you could attach the spans to non-Rust code by doing something like

const _: &str = include_str!("the_template.html");

Then, the template source code would be part of the SourceMap, but it would (should) be optimized out of the final binary. I'm not sure how you'd get access to those spans from Askama, but maybe it's worth looking into?

@camelid
Copy link
Member

camelid commented Jan 4, 2022

Why did you move the templates from src/librustdoc/html/templates to src/librustdoc/templates? The old location seems better to me.

@bors
Copy link
Contributor

bors commented Jan 12, 2022

⌛ Testing commit ef96d57 with merge e038d9166b04292cd4f8f0ed1091ae0163dfa25b...

@rust-log-analyzer
Copy link
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bors
Copy link
Contributor

bors commented Jan 12, 2022

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jan 12, 2022
@GuillaumeGomez
Copy link
Member

@bors retry

@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, 2022
@matthiaskrgr
Copy link
Member

@bors p=11 prioritizing over #92826

@bors
Copy link
Contributor

bors commented Jan 13, 2022

⌛ Testing commit ef96d57 with merge e916815...

@bors
Copy link
Contributor

bors commented Jan 13, 2022

☀️ Test successful - checks-actions
Approved by: jsha
Pushing e916815 to master...

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (e916815): comparison url.

Summary: This change led to very large relevant improvements 🎉 in compiler performance.

  • Very large improvement in instruction counts (up to -30.7% on full builds of externs)

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 14, 2022
Fix a missing dot in the main item heading

This pull-request fix a missing `·` in the item header ~~and also make use of `&nbsp;` to explicit that the spaces are mandatory~~.

| Before | After |
| --- | --- |
| ![image](https://user-images.githubusercontent.com/3616612/149393966-7cca6dc5-9a62-47fa-8c9c-18f936d43aa9.png) | ![image](https://user-images.githubusercontent.com/3616612/149393869-5ffd6e44-d91c-4ece-b69e-d103304f6626.png) |

PS: This was introduce yesterday by rust-lang#92526 (the migration from Tera to Askama) and is not currently observable in the nightly doc.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 14, 2022
Fix a missing dot in the main item heading

This pull-request fix a missing `·` in the item header ~~and also make use of `&nbsp;` to explicit that the spaces are mandatory~~.

| Before | After |
| --- | --- |
| ![image](https://user-images.githubusercontent.com/3616612/149393966-7cca6dc5-9a62-47fa-8c9c-18f936d43aa9.png) | ![image](https://user-images.githubusercontent.com/3616612/149393869-5ffd6e44-d91c-4ece-b69e-d103304f6626.png) |

PS: This was introduce yesterday by rust-lang#92526 (the migration from Tera to Askama) and is not currently observable in the nightly doc.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 14, 2022
Fix a missing dot in the main item heading

This pull-request fix a missing `·` in the item header ~~and also make use of `&nbsp;` to explicit that the spaces are mandatory~~.

| Before | After |
| --- | --- |
| ![image](https://user-images.githubusercontent.com/3616612/149393966-7cca6dc5-9a62-47fa-8c9c-18f936d43aa9.png) | ![image](https://user-images.githubusercontent.com/3616612/149393869-5ffd6e44-d91c-4ece-b69e-d103304f6626.png) |

PS: This was introduce yesterday by rust-lang#92526 (the migration from Tera to Askama) and is not currently observable in the nightly doc.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 19, 2022
…=notriddle

Move back templates into html folder

Follow-up of rust-lang#92526.

r? `@notriddle`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.