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

Servo's async Tokenizer: New! Improved! Now with multithreading! #17565

Merged
merged 2 commits into from Jul 28, 2017

Conversation

Projects
None yet
7 participants
@cynicaldevil
Copy link
Contributor

commented Jun 29, 2017

The Tokenizer, defined in the file async_html.rs will run on the main thread, while h5e's Tokenizer(along with its Sink) lives on the parser thread. Both h5e's Tokenizer and Sink communicate with the main thread Tokenizer via their own mpsc channels. The Sink keeps sending parser operations to the main thread, to be executed. For some operations, it waits for a message from the main thread before returning.


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #__ (github issue number if applicable).
  • There are tests for these changes OR
  • These changes do not require tests because _____

This change is Reviewable

@highfive

This comment has been minimized.

Copy link

commented Jun 29, 2017

Heads up! This PR modifies the following files:

  • @fitzgen: components/script/dom/servoparser/async_html.rs
  • @KiChjang: components/script/dom/servoparser/async_html.rs
@highfive

This comment has been minimized.

Copy link

commented Jun 29, 2017

warning Warning warning

  • These commits modify script code, but no tests are modified. Please consider adding a test!
@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jun 29, 2017

cc @nox

}

#[derive(HeapSizeOf)]
enum ToSinkMsg {

This comment has been minimized.

Copy link
@cynicaldevil

cynicaldevil Jun 29, 2017

Author Contributor

The messages sent from the main thread Tokenizer to the Sink are the results of the synchronous operations we perform. Only two sync operations exist.

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Add docs instead of GH comments. :)

Are these answers or questions?

HtmlTokenizer(FromHtmlTokenizerMsg)
}

let mut send_tendrils = Vec::new();

This comment has been minimized.

Copy link
@cynicaldevil

cynicaldevil Jun 29, 2017

Author Contributor

Instead of making the BufferQueue implement Send, I now extract the StrTendrils from the BufferQueue and convert them to SendTendrils, which are then stored in a mutex. After we get a result from the feed function, we update input based on the contents of the mutex. The mutex is updated after HtmlTokenizer's feed method returns.

@nox

This comment has been minimized.

Copy link
Member

commented Jul 1, 2017

51.24s$ ./mach test-compiletest
   Compiling compiletest_rs v0.2.6
   Compiling script v0.0.1 (file:///home/travis/build/servo/servo/components/script)
   Compiling compiletest_helper v0.0.1 (file:///home/travis/build/servo/servo/tests/compiletest/helper)
error[E0271]: type mismatch resolving `<html5ever::<unnamed>::fmt::UTF8 as html5ever::<unnamed>::fmt::SliceFormat>::Slice == html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
   --> /home/travis/build/servo/servo/components/script/dom/servoparser/async_html.rs:240:34
    |
240 |                         map(|st| StrTendril::from(st.clone())).collect::<VecDeque<StrTendril>>();
    |                                  ^^^^^^^^^^^^^^^^ expected str, found struct `html5ever::<unnamed>::SendTendril`
    |
    = note: expected type `str`
               found type `html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
    = note: required by `core::convert::From::from`
error[E0271]: type mismatch resolving `<html5ever::<unnamed>::fmt::UTF8 as html5ever::<unnamed>::fmt::SliceFormat>::Slice == html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
   --> /home/travis/build/servo/servo/components/script/dom/servoparser/async_html.rs:418:30
    |
418 |                     map(|st| StrTendril::from(st.clone())).collect::<VecDeque<StrTendril>>();
    |                              ^^^^^^^^^^^^^^^^ expected str, found struct `html5ever::<unnamed>::SendTendril`
    |
    = note: expected type `str`
               found type `html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
    = note: required by `core::convert::From::from`
error: aborting due to previous error(s)
error: Could not compile `script`.
To learn more, run the command again with --verbose.
The command "./mach test-compiletest" exited with 101.
50.57s$ ./mach test-unit
   Compiling size_of_test v0.0.1 (file:///home/travis/build/servo/servo/components/size_of_test)
   Compiling servo_remutex_tests v0.0.1 (file:///home/travis/build/servo/servo/tests/unit/servo_remutex)
   Compiling servo_config_tests v0.0.1 (file:///home/travis/build/servo/servo/tests/unit/servo_config)
   Compiling net_traits_tests v0.0.1 (file:///home/travis/build/servo/servo/tests/unit/net_traits)
   Compiling selectors v0.19.0 (file:///home/travis/build/servo/servo/components/selectors)
   Compiling profile_tests v0.0.1 (file:///home/travis/build/servo/servo/tests/unit/profile)
   Compiling script v0.0.1 (file:///home/travis/build/servo/servo/components/script)
   Compiling net_tests v0.0.1 (file:///home/travis/build/servo/servo/tests/unit/net)
   Compiling gfx_tests v0.0.1 (file:///home/travis/build/servo/servo/tests/unit/gfx)
warning: unused import: `std::borrow::Cow`
    --> /home/travis/build/servo/servo/components/selectors/parser.rs:1575:9
     |
1575 |     use std::borrow::Cow;
     |         ^^^^^^^^^^^^^^^^
     |
     = note: #[warn(unused_imports)] on by default
   Compiling layout_tests v0.0.1 (file:///home/travis/build/servo/servo/tests/unit/layout)
error[E0271]: type mismatch resolving `<html5ever::<unnamed>::fmt::UTF8 as html5ever::<unnamed>::fmt::SliceFormat>::Slice == html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
   --> /home/travis/build/servo/servo/components/script/dom/servoparser/async_html.rs:240:34
    |
240 |                         map(|st| StrTendril::from(st.clone())).collect::<VecDeque<StrTendril>>();
    |                                  ^^^^^^^^^^^^^^^^ expected str, found struct `html5ever::<unnamed>::SendTendril`
    |
    = note: expected type `str`
               found type `html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
    = note: required by `core::convert::From::from`
error[E0271]: type mismatch resolving `<html5ever::<unnamed>::fmt::UTF8 as html5ever::<unnamed>::fmt::SliceFormat>::Slice == html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
   --> /home/travis/build/servo/servo/components/script/dom/servoparser/async_html.rs:418:30
    |
418 |                     map(|st| StrTendril::from(st.clone())).collect::<VecDeque<StrTendril>>();
    |                              ^^^^^^^^^^^^^^^^ expected str, found struct `html5ever::<unnamed>::SendTendril`
    |
    = note: expected type `str`
               found type `html5ever::<unnamed>::SendTendril<html5ever::<unnamed>::fmt::UTF8>`
    = note: required by `core::convert::From::from`
error: aborting due to previous error(s)
error: Could not compile `script`.
To learn more, run the command again with --verbose.
The command "./mach test-unit" exited with 101.
@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 1, 2017

Yes, it requires the new tendril version, which implements clone for Sendtendril. It works, I have compiled this locally using that.

@@ -4,12 +4,13 @@

#![allow(unrooted_must_root)]

use core::iter::FromIterator;
use core::str::FromStr;

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Aren't these already imported? At the very least, you shouldn't depend on them from core.

}
}
#[derive(HeapSizeOf, JSTraceable)]
struct Attribute {

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Why is this now needed?

This comment has been minimized.

Copy link
@cynicaldevil

cynicaldevil Jul 5, 2017

Author Contributor

The attributes defined in h5e can't be sent between threads, so I convert them to this type before sending them.

enum ParseOperation {
GetTemplateContents(ParseNodeId, ParseNodeId),
CreateElement(ParseNodeId, QualName, Vec<Attribute>),
CreateComment(StrTendril, ParseNodeId),
CreateElement(ParseNodeId, QualName, Vec<Attribute>, u64),

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Please make these have named fields, as I mentioned in the first PR. What even is that u64?

Pop(ParseNodeId),
SetQuirksMode(
#[ignore_heap_size_of = "Defined in style"]
ServoQuirksMode

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Derive HeapSizeOf on ServoQuirksMode in style.

}

#[derive(JSTraceable, HeapSizeOf)]
#[derive(HeapSizeOf)]
enum FromHtmlTokenizerMsg {

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Don't use an enum if there is only a single variant.

}

#[derive(HeapSizeOf)]
enum ToSinkMsg {

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Add docs instead of GH comments. :)

Are these answers or questions?

let send_tendrils = Arc::new(Mutex::new(send_tendrils));
// Send message to parser thread, asking it to started reading from the shared input.
// Parser operation messages will be sent to main thread as they are evaluated.
self.html_tokenizer_sender.send(ToHtmlTokenizerMsg::Feed(send_tendrils.clone())).unwrap();

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Why do we need to put the tendrils in a Arc<Mutex<T>> if we just send them afterwards?

This comment has been minimized.

Copy link
@cynicaldevil

cynicaldevil Jul 5, 2017

Author Contributor

I need to access send_tendrils again a few lines below....but this seems confusing to others. I think I'll remove the mutex and just pass it in the message itself.

This comment has been minimized.

Copy link
@cynicaldevil

cynicaldevil Jul 6, 2017

Author Contributor

Hmm...yeah... passing them via messages is not possible, needs HeapSizeOf impl for Tendril. Mutexes will have to do for now.

This comment has been minimized.

Copy link
@nox

nox Jul 18, 2017

Member

HeapSizeOf can be ignored, I think it's less important than avoiding mutices were we can.

match receiver.recv().expect("Unexpected sink channel panic in Html parser thread") {
ToHtmlTokenizerMsg::Feed(data) => {
let mut data = data.lock().unwrap();
let input = (*data).iter().

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Why the explicit deref here?

ToHtmlTokenizerMsg::Feed(data) => {
let mut data = data.lock().unwrap();
let input = (*data).iter().
map(|st| StrTendril::from(st.clone())).collect::<VecDeque<StrTendril>>();

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

Why the VecDeque here?

is_integration_point: bool,
}

impl Default for ParseNodeData {

This comment has been minimized.

Copy link
@nox

nox Jul 3, 2017

Member

This can be derived.

@nox

This comment has been minimized.

Copy link
Member

commented Jul 3, 2017

Yes, it requires the new tendril version, which implements clone for Sendtendril. It works, I have compiled this locally using that.

Use tendril 0.3.1.

@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 5, 2017

Currently, tendril's types are imported via h5e, for example, StrTendril is imported as use html5ever::tendril::StrTendril, so the tendril version in h5e needs to be updated first, followed by a h5e version update in Servo.

@cynicaldevil cynicaldevil force-pushed the cynicaldevil:new-parser-thread branch from e42747d to ef283e5 Jul 6, 2017

@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 6, 2017

@nox I've updated the PR with the changes. I also added some comments to better explain the workings.

Now, if we ask bors to try this PR, it will test it using the synchronous tokenizer. Should I add an additional commit which enables the async tokenizer in preferences, just for testing purposes?

@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 6, 2017

☔️ The latest upstream changes (presumably #17624) made this pull request unmergeable. Please resolve the merge conflicts.

@cynicaldevil cynicaldevil force-pushed the cynicaldevil:new-parser-thread branch from ef283e5 to bb05fd0 Jul 9, 2017

@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 9, 2017

I rebased the PR, but don't know why the needs-rebase label wasn't removed.

@KiChjang KiChjang removed the S-needs-rebase label Jul 9, 2017

@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 11, 2017

☔️ The latest upstream changes (presumably #17655) made this pull request unmergeable. Please resolve the merge conflicts.

@cynicaldevil cynicaldevil force-pushed the cynicaldevil:new-parser-thread branch from bb05fd0 to 5fae497 Jul 11, 2017

@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 11, 2017

@nox ready for try, then?

@KiChjang

This comment has been minimized.

Copy link
Member

commented Jul 11, 2017

@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 11, 2017

⌛️ Trying commit 5fae497 with merge ff48c7f...

bors-servo added a commit that referenced this pull request Jul 11, 2017

Auto merge of #17565 - cynicaldevil:new-parser-thread, r=<try>
Servo's async Tokenizer: New! Improved! Now with multithreading!

<!-- Please describe your changes on the following line: -->
**Note: Not to be merged until tendril v0.3.1 lands in Servo.**

The Tokenizer, defined in the file `async_html.rs` will run on the main thread, while h5e's `Tokenizer`(along with its Sink) lives on the parser thread. Both h5e's `Tokenizer` and `Sink` communicate with the main thread Tokenizer via their own mpsc channels. The Sink keeps sending parser operations to the main thread, to be executed. For some operations, it waits for a message from the main thread before returning.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17565)
<!-- Reviewable:end -->
@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 11, 2017

💔 Test failed - mac-rel-wpt4

@cynicaldevil cynicaldevil force-pushed the cynicaldevil:new-parser-thread branch from 5fae497 to aebd6d4 Jul 12, 2017

@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 12, 2017

@nox Removed a sender-receiver pair and merged it with another one. Now HtmlTokenizer and Sink both send messages to the same receiver. This solves the concurrency issue which was causing the tests to fail, and also makes it a little easier to understand the whole thing.

@bors-servo try

@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 28, 2017

@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2017

⌛️ Trying commit b33aef2 with merge b98aefc...

bors-servo added a commit that referenced this pull request Jul 28, 2017

Auto merge of #17565 - cynicaldevil:new-parser-thread, r=<try>
Servo's async Tokenizer: New! Improved! Now with multithreading!

<!-- Please describe your changes on the following line: -->

The Tokenizer, defined in the file `async_html.rs` will run on the main thread, while h5e's `Tokenizer`(along with its Sink) lives on the parser thread. Both h5e's `Tokenizer` and `Sink` communicate with the main thread Tokenizer via their own mpsc channels. The Sink keeps sending parser operations to the main thread, to be executed. For some operations, it waits for a message from the main thread before returning.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17565)
<!-- Reviewable:end -->
@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2017

💔 Test failed - mac-rel-wpt4

@highfive

This comment has been minimized.

Copy link

commented Jul 28, 2017

  ▶ Unexpected subtest result in /html/dom/dynamic-markup-insertion/document-write/iframe_005.html:
  └ PASS [expected FAIL] document.write external script into iframe write back into parent

  ▶ Unexpected subtest result in /html/dom/dynamic-markup-insertion/opening-the-input-stream/010.html:
  └ PASS [expected FAIL] Salvagability of document.opened document

@cynicaldevil cynicaldevil force-pushed the cynicaldevil:new-parser-thread branch from b33aef2 to 0750fdc Jul 28, 2017

@cynicaldevil

This comment has been minimized.

Copy link
Contributor Author

commented Jul 28, 2017

Forgot to add changes before committing, trying again:
@bors-servo try

@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2017

⌛️ Trying commit 0750fdc with merge 98653c9...

bors-servo added a commit that referenced this pull request Jul 28, 2017

Auto merge of #17565 - cynicaldevil:new-parser-thread, r=<try>
Servo's async Tokenizer: New! Improved! Now with multithreading!

<!-- Please describe your changes on the following line: -->

The Tokenizer, defined in the file `async_html.rs` will run on the main thread, while h5e's `Tokenizer`(along with its Sink) lives on the parser thread. Both h5e's `Tokenizer` and `Sink` communicate with the main thread Tokenizer via their own mpsc channels. The Sink keeps sending parser operations to the main thread, to be executed. For some operations, it waits for a message from the main thread before returning.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17565)
<!-- Reviewable:end -->
@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2017

@jdm

This comment has been minimized.

Copy link
Member

commented Jul 28, 2017

@bors-servo: r=nox,jdm

@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2017

📌 Commit 0750fdc has been approved by nox,jdm

@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2017

⌛️ Testing commit 0750fdc with merge e8272dc...

bors-servo added a commit that referenced this pull request Jul 28, 2017

Auto merge of #17565 - cynicaldevil:new-parser-thread, r=nox,jdm
Servo's async Tokenizer: New! Improved! Now with multithreading!

<!-- Please describe your changes on the following line: -->

The Tokenizer, defined in the file `async_html.rs` will run on the main thread, while h5e's `Tokenizer`(along with its Sink) lives on the parser thread. Both h5e's `Tokenizer` and `Sink` communicate with the main thread Tokenizer via their own mpsc channels. The Sink keeps sending parser operations to the main thread, to be executed. For some operations, it waits for a message from the main thread before returning.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17565)
<!-- Reviewable:end -->
@bors-servo

This comment has been minimized.

Copy link
Contributor

commented Jul 28, 2017

@bors-servo bors-servo merged commit 0750fdc into servo:master Jul 28, 2017

3 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details

moz-servo-sync added a commit to moz-servo-sync/servo that referenced this pull request Jul 28, 2017

bors-servo added a commit that referenced this pull request Jul 28, 2017

Auto merge of #17910 - moz-servo-sync:gecko-backout, r=moz-servo-sync
Backed out changeset a417b9d7712d for vendoring bustage. r=backout on a CLOSED TREE

Backed out changeset a417b9d7712d for vendoring bustage. r=backout on a CLOSED TREE

Backs out #17565

bors-servo added a commit that referenced this pull request Jul 28, 2017

Auto merge of #17910 - moz-servo-sync:gecko-backout, r=moz-servo-sync
Multiple gecko backouts

Backed out changeset a417b9d7712d for vendoring bustage. r=backout on a CLOSED TREE

Backs out #17565

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17910)
<!-- Reviewable:end -->

---

Backed out changeset c424ad1c5f94 for build failures a=backout CLOSED TREE

Backs out #17892
@jdm

This comment has been minimized.

Copy link
Member

commented Jul 29, 2017

This was reverted by Gecko and needs to be merged again. However, to avoid the problem that triggered the revert, we probably need to conditionally add HeapSizeOf in selectors if a "servo" feature is enabled for the crate.

@cynicaldevil cynicaldevil referenced this pull request Jul 29, 2017

Merged

Run the async HTML Tokenizer on a new thread #17914

2 of 2 tasks complete

bors-servo added a commit that referenced this pull request Jul 29, 2017

Auto merge of #17914 - cynicaldevil:new-parser-thread, r=emilio
Run the async HTML Tokenizer on a new thread

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

Follow up for #17565

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17914)
<!-- Reviewable:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.