about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs12
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/html/render/mod.rs33
-rw-r--r--src/librustdoc/html/render/search_index.rs107
-rw-r--r--src/librustdoc/html/render/search_index/encode.rs243
-rw-r--r--src/librustdoc/html/render/write_shared.rs31
-rw-r--r--src/librustdoc/html/static/.eslintrc.js2
-rw-r--r--src/librustdoc/html/static/js/main.js32
-rw-r--r--src/librustdoc/html/static/js/search.js509
-rw-r--r--src/librustdoc/html/static/js/storage.js4
-rw-r--r--src/tools/rustdoc-js/.eslintrc.js2
-rw-r--r--src/tools/rustdoc-js/tester.js99
-rw-r--r--tests/rustdoc-gui/anchors.goml2
-rw-r--r--tests/rustdoc-gui/code-color.goml2
-rw-r--r--tests/rustdoc-gui/codeblock-tooltip.goml2
-rw-r--r--tests/rustdoc-gui/cursor.goml2
-rw-r--r--tests/rustdoc-gui/docblock-code-block-line-number.goml2
-rw-r--r--tests/rustdoc-gui/docblock-table.goml2
-rw-r--r--tests/rustdoc-gui/escape-key.goml2
-rw-r--r--tests/rustdoc-gui/globals.goml2
-rw-r--r--tests/rustdoc-gui/go-to-collapsed-elem.goml4
-rw-r--r--tests/rustdoc-gui/headers-color.goml2
-rw-r--r--tests/rustdoc-gui/headings-anchor.goml8
-rw-r--r--tests/rustdoc-gui/headings.goml10
-rw-r--r--tests/rustdoc-gui/help-page.goml8
-rw-r--r--tests/rustdoc-gui/highlight-colors.goml4
-rw-r--r--tests/rustdoc-gui/item-decl-colors.goml4
-rw-r--r--tests/rustdoc-gui/item-decl-comment-highlighting.goml4
-rw-r--r--tests/rustdoc-gui/item-info-alignment.goml4
-rw-r--r--tests/rustdoc-gui/item-info.goml4
-rw-r--r--tests/rustdoc-gui/jump-to-def-background.goml17
-rw-r--r--tests/rustdoc-gui/label-next-to-symbol.goml12
-rw-r--r--tests/rustdoc-gui/links-color.goml4
-rw-r--r--tests/rustdoc-gui/notable-trait.goml20
-rw-r--r--tests/rustdoc-gui/pocket-menu.goml2
-rw-r--r--tests/rustdoc-gui/run-on-hover.goml2
-rw-r--r--tests/rustdoc-gui/rust-logo.goml2
-rw-r--r--tests/rustdoc-gui/scrape-examples-color.goml6
-rw-r--r--tests/rustdoc-gui/scrape-examples-toggle.goml2
-rw-r--r--tests/rustdoc-gui/search-corrections.goml10
-rw-r--r--tests/rustdoc-gui/search-error.goml2
-rw-r--r--tests/rustdoc-gui/search-filter.goml2
-rw-r--r--tests/rustdoc-gui/search-form-elements.goml4
-rw-r--r--tests/rustdoc-gui/search-keyboard.goml2
-rw-r--r--tests/rustdoc-gui/search-no-result.goml2
-rw-r--r--tests/rustdoc-gui/search-reexport.goml4
-rw-r--r--tests/rustdoc-gui/search-result-color.goml246
-rw-r--r--tests/rustdoc-gui/search-result-display.goml4
-rw-r--r--tests/rustdoc-gui/search-result-impl-disambiguation.goml4
-rw-r--r--tests/rustdoc-gui/search-result-keyword.goml2
-rw-r--r--tests/rustdoc-gui/search-tab-change-title-fn-sig.goml10
-rw-r--r--tests/rustdoc-gui/search-tab.goml12
-rw-r--r--tests/rustdoc-gui/setting-auto-hide-content-large-items.goml2
-rw-r--r--tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml2
-rw-r--r--tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml2
-rw-r--r--tests/rustdoc-gui/setting-go-to-only-result.goml4
-rw-r--r--tests/rustdoc-gui/settings.goml2
-rw-r--r--tests/rustdoc-gui/sidebar-links-color.goml4
-rw-r--r--tests/rustdoc-gui/sidebar-mobile.goml2
-rw-r--r--tests/rustdoc-gui/sidebar-source-code-display.goml4
-rw-r--r--tests/rustdoc-gui/sidebar-source-code.goml2
-rw-r--r--tests/rustdoc-gui/sidebar.goml2
-rw-r--r--tests/rustdoc-gui/source-code-page.goml6
-rw-r--r--tests/rustdoc-gui/stab-badge.goml2
-rw-r--r--tests/rustdoc-gui/target.goml2
-rw-r--r--tests/rustdoc-gui/toggle-docs.goml2
-rw-r--r--tests/rustdoc-gui/type-declation-overflow.goml8
-rw-r--r--tests/rustdoc-gui/unsafe-fn.goml17
-rw-r--r--tests/rustdoc-gui/warning-block.goml2
-rw-r--r--tests/rustdoc-gui/where-whitespace.goml10
-rw-r--r--tests/rustdoc/search-index-summaries.rs2
-rw-r--r--tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr19
-rw-r--r--tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr19
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr23
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr23
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr115
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr115
80 files changed, 1104 insertions, 808 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a10eccb1ce5..80e6dce2d92 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4783,6 +4783,8 @@ version = "0.0.0"
 dependencies = [
  "arrayvec",
  "askama",
+ "base64",
+ "byteorder",
  "expect-test",
  "indexmap",
  "itertools 0.12.1",
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index e0bbd582d88..99dbb342268 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -3,7 +3,7 @@
 //! be a coroutine body that takes all of its upvars by-move, and which we stash
 //! into the `CoroutineInfo` for all coroutines returned by coroutine-closures.
 
-use rustc_data_structures::fx::FxIndexSet;
+use rustc_data_structures::unord::UnordSet;
 use rustc_hir as hir;
 use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::mir::{self, dump_mir, MirPass};
@@ -33,7 +33,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
             return;
         }
 
-        let mut by_ref_fields = FxIndexSet::default();
+        let mut by_ref_fields = UnordSet::default();
         let by_move_upvars = Ty::new_tup_from_iter(
             tcx,
             tcx.closure_captures(coroutine_def_id).iter().enumerate().map(|(idx, capture)| {
@@ -73,7 +73,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
 
 struct MakeByMoveBody<'tcx> {
     tcx: TyCtxt<'tcx>,
-    by_ref_fields: FxIndexSet<FieldIdx>,
+    by_ref_fields: UnordSet<FieldIdx>,
     by_move_coroutine_ty: Ty<'tcx>,
 }
 
@@ -89,11 +89,11 @@ impl<'tcx> MutVisitor<'tcx> for MakeByMoveBody<'tcx> {
         location: mir::Location,
     ) {
         if place.local == ty::CAPTURE_STRUCT_LOCAL
-            && !place.projection.is_empty()
-            && let mir::ProjectionElem::Field(idx, ty) = place.projection[0]
+            && let Some((&mir::ProjectionElem::Field(idx, ty), projection)) =
+                place.projection.split_first()
             && self.by_ref_fields.contains(&idx)
         {
-            let (begin, end) = place.projection[1..].split_first().unwrap();
+            let (begin, end) = projection.split_first().unwrap();
             // FIXME(async_closures): I'm actually a bit surprised to see that we always
             // initially deref the by-ref upvars. If this is not actually true, then we
             // will at least get an ICE that explains why this isn't true :^)
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index e5aa81d83d5..6918574814f 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -60,7 +60,7 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
            /scripts/validate-error-codes.sh && \
            reuse --include-submodules lint && \
            # Runs checks to ensure that there are no ES5 issues in our JS code.
-           es-check es6 ../src/librustdoc/html/static/js/*.js && \
+           es-check es8 ../src/librustdoc/html/static/js/*.js && \
            eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js && \
            eslint -c ../src/tools/rustdoc-js/.eslintrc.js ../src/tools/rustdoc-js/tester.js && \
            eslint -c ../src/tools/rustdoc-gui/.eslintrc.js ../src/tools/rustdoc-gui/tester.js
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index a2b63962ba1..07feb823492 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.16.11
\ No newline at end of file
+0.17.0
\ No newline at end of file
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index d43c0cfa961..9a23811ed3f 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -9,6 +9,8 @@ path = "lib.rs"
 [dependencies]
 arrayvec = { version = "0.7", default-features = false }
 askama = { version = "0.12", default-features = false, features = ["config"] }
+base64 = "0.21.7"
+byteorder = "1.5"
 itertools = "0.12"
 indexmap = "2"
 minifier = "0.3.0"
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 1ddcb3d8728..4e46f847fd7 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -184,40 +184,15 @@ pub(crate) enum RenderTypeId {
 
 impl RenderTypeId {
     pub fn write_to_string(&self, string: &mut String) {
-        // (sign, value)
-        let (sign, id): (bool, u32) = match &self {
+        let id: i32 = match &self {
             // 0 is a sentinel, everything else is one-indexed
             // concrete type
-            RenderTypeId::Index(idx) if *idx >= 0 => (false, (idx + 1isize).try_into().unwrap()),
+            RenderTypeId::Index(idx) if *idx >= 0 => (idx + 1isize).try_into().unwrap(),
             // generic type parameter
-            RenderTypeId::Index(idx) => (true, (-*idx).try_into().unwrap()),
+            RenderTypeId::Index(idx) => (*idx).try_into().unwrap(),
             _ => panic!("must convert render types to indexes before serializing"),
         };
-        // zig-zag encoding
-        let value: u32 = (id << 1) | (if sign { 1 } else { 0 });
-        // Self-terminating hex use capital letters for everything but the
-        // least significant digit, which is lowercase. For example, decimal 17
-        // would be `` Aa `` if zig-zag encoding weren't used.
-        //
-        // Zig-zag encoding, however, stores the sign bit as the last bit.
-        // This means, in the last hexit, 1 is actually `c`, -1 is `b`
-        // (`a` is the imaginary -0), and, because all the bits are shifted
-        // by one, `` A` `` is actually 8 and `` Aa `` is -8.
-        //
-        // https://rust-lang.github.io/rustc-dev-guide/rustdoc-internals/search.html
-        // describes the encoding in more detail.
-        let mut shift: u32 = 28;
-        let mut mask: u32 = 0xF0_00_00_00;
-        while shift < 32 {
-            let hexit = (value & mask) >> shift;
-            if hexit != 0 || shift == 0 {
-                let hex =
-                    char::try_from(if shift == 0 { '`' } else { '@' } as u32 + hexit).unwrap();
-                string.push(hex);
-            }
-            shift = shift.wrapping_sub(4);
-            mask = mask >> 4;
-        }
+        search_index::encode::write_vlqhex_to_string(id, string);
     }
 }
 
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index be2786c99ec..51f90e45500 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -1,3 +1,5 @@
+pub(crate) mod encode;
+
 use std::collections::hash_map::Entry;
 use std::collections::{BTreeMap, VecDeque};
 
@@ -17,12 +19,46 @@ use crate::html::format::join_with_double_colon;
 use crate::html::markdown::short_markdown_summary;
 use crate::html::render::{self, IndexItem, IndexItemFunctionType, RenderType, RenderTypeId};
 
+use encode::{bitmap_to_string, write_vlqhex_to_string};
+
+/// The serialized search description sharded version
+///
+/// The `index` is a JSON-encoded list of names and other information.
+///
+/// The desc has newlined descriptions, split up by size into 128KiB shards.
+/// For example, `(4, "foo\nbar\nbaz\nquux")`.
+///
+/// There is no single, optimal size for these shards, because it depends on
+/// configuration values that we can't predict or control, such as the version
+/// of HTTP used (HTTP/1.1 would work better with larger files, while HTTP/2
+/// and 3 are more agnostic), transport compression (gzip, zstd, etc), whether
+/// the search query is going to produce a large number of results or a small
+/// number, the bandwidth delay product of the network...
+///
+/// Gzipping some standard library descriptions to guess what transport
+/// compression will do, the compressed file sizes can be as small as 4.9KiB
+/// or as large as 18KiB (ignoring the final 1.9KiB shard of leftovers).
+/// A "reasonable" range for files is for them to be bigger than 1KiB,
+/// since that's about the amount of data that can be transferred in a
+/// single TCP packet, and 64KiB, the maximum amount of data that
+/// TCP can transfer in a single round trip without extensions.
+///
+/// [1]: https://en.wikipedia.org/wiki/Maximum_transmission_unit#MTUs_for_common_media
+/// [2]: https://en.wikipedia.org/wiki/Sliding_window_protocol#Basic_concept
+/// [3]: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/description-tcp-features
+pub(crate) struct SerializedSearchIndex {
+    pub(crate) index: String,
+    pub(crate) desc: Vec<(usize, String)>,
+}
+
+const DESC_INDEX_SHARD_LEN: usize = 128 * 1024;
+
 /// Builds the search index from the collected metadata
 pub(crate) fn build_index<'tcx>(
     krate: &clean::Crate,
     cache: &mut Cache,
     tcx: TyCtxt<'tcx>,
-) -> String {
+) -> SerializedSearchIndex {
     let mut itemid_to_pathid = FxHashMap::default();
     let mut primitives = FxHashMap::default();
     let mut associated_types = FxHashMap::default();
@@ -319,7 +355,6 @@ pub(crate) fn build_index<'tcx>(
         .collect::<Vec<_>>();
 
     struct CrateData<'a> {
-        doc: String,
         items: Vec<&'a IndexItem>,
         paths: Vec<(ItemType, Vec<Symbol>)>,
         // The String is alias name and the vec is the list of the elements with this alias.
@@ -328,6 +363,11 @@ pub(crate) fn build_index<'tcx>(
         aliases: &'a BTreeMap<String, Vec<usize>>,
         // Used when a type has more than one impl with an associated item with the same name.
         associated_item_disambiguators: &'a Vec<(usize, String)>,
+        // A list of shard lengths encoded as vlqhex. See the comment in write_vlqhex_to_string
+        // for information on the format.
+        desc_index: String,
+        // A list of items with no description. This is eventually turned into a bitmap.
+        empty_desc: Vec<u32>,
     }
 
     struct Paths {
@@ -409,7 +449,6 @@ pub(crate) fn build_index<'tcx>(
             let mut names = Vec::with_capacity(self.items.len());
             let mut types = String::with_capacity(self.items.len());
             let mut full_paths = Vec::with_capacity(self.items.len());
-            let mut descriptions = Vec::with_capacity(self.items.len());
             let mut parents = Vec::with_capacity(self.items.len());
             let mut functions = String::with_capacity(self.items.len());
             let mut deprecated = Vec::with_capacity(self.items.len());
@@ -432,7 +471,6 @@ pub(crate) fn build_index<'tcx>(
                 parents.push(item.parent_idx.map(|x| x + 1).unwrap_or(0));
 
                 names.push(item.name.as_str());
-                descriptions.push(&item.desc);
 
                 if !item.path.is_empty() {
                     full_paths.push((index, &item.path));
@@ -444,7 +482,8 @@ pub(crate) fn build_index<'tcx>(
                 }
 
                 if item.deprecation.is_some() {
-                    deprecated.push(index);
+                    // bitmasks always use 1-indexing for items, with 0 as the crate itself
+                    deprecated.push(u32::try_from(index + 1).unwrap());
                 }
             }
 
@@ -455,17 +494,16 @@ pub(crate) fn build_index<'tcx>(
             let has_aliases = !self.aliases.is_empty();
             let mut crate_data =
                 serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?;
-            crate_data.serialize_field("doc", &self.doc)?;
             crate_data.serialize_field("t", &types)?;
             crate_data.serialize_field("n", &names)?;
-            // Serialize as an array of item indices and full paths
             crate_data.serialize_field("q", &full_paths)?;
-            crate_data.serialize_field("d", &descriptions)?;
             crate_data.serialize_field("i", &parents)?;
             crate_data.serialize_field("f", &functions)?;
-            crate_data.serialize_field("c", &deprecated)?;
+            crate_data.serialize_field("D", &self.desc_index)?;
             crate_data.serialize_field("p", &paths)?;
             crate_data.serialize_field("b", &self.associated_item_disambiguators)?;
+            crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?;
+            crate_data.serialize_field("e", &bitmap_to_string(&self.empty_desc))?;
             if has_aliases {
                 crate_data.serialize_field("a", &self.aliases)?;
             }
@@ -473,16 +511,58 @@ pub(crate) fn build_index<'tcx>(
         }
     }
 
-    // Collect the index into a string
-    format!(
+    let (empty_desc, desc) = {
+        let mut empty_desc = Vec::new();
+        let mut result = Vec::new();
+        let mut set = String::new();
+        let mut len: usize = 0;
+        let mut item_index: u32 = 0;
+        for desc in std::iter::once(&crate_doc).chain(crate_items.iter().map(|item| &item.desc)) {
+            if desc == "" {
+                empty_desc.push(item_index);
+                item_index += 1;
+                continue;
+            }
+            if set.len() >= DESC_INDEX_SHARD_LEN {
+                result.push((len, std::mem::replace(&mut set, String::new())));
+                len = 0;
+            } else if len != 0 {
+                set.push('\n');
+            }
+            set.push_str(&desc);
+            len += 1;
+            item_index += 1;
+        }
+        result.push((len, std::mem::replace(&mut set, String::new())));
+        (empty_desc, result)
+    };
+
+    let desc_index = {
+        let mut desc_index = String::with_capacity(desc.len() * 4);
+        for &(len, _) in desc.iter() {
+            write_vlqhex_to_string(len.try_into().unwrap(), &mut desc_index);
+        }
+        desc_index
+    };
+
+    assert_eq!(
+        crate_items.len() + 1,
+        desc.iter().map(|(len, _)| *len).sum::<usize>() + empty_desc.len()
+    );
+
+    // The index, which is actually used to search, is JSON
+    // It uses `JSON.parse(..)` to actually load, since JSON
+    // parses faster than the full JavaScript syntax.
+    let index = format!(
         r#"["{}",{}]"#,
         krate.name(tcx),
         serde_json::to_string(&CrateData {
-            doc: crate_doc,
             items: crate_items,
             paths: crate_paths,
             aliases: &aliases,
             associated_item_disambiguators: &associated_item_disambiguators,
+            desc_index,
+            empty_desc,
         })
         .expect("failed serde conversion")
         // All these `replace` calls are because we have to go through JS string for JSON content.
@@ -490,7 +570,8 @@ pub(crate) fn build_index<'tcx>(
         .replace('\'', r"\'")
         // We need to escape double quotes for the JSON.
         .replace("\\\"", "\\\\\"")
-    )
+    );
+    SerializedSearchIndex { index, desc }
 }
 
 pub(crate) fn get_function_type_for_search<'tcx>(
diff --git a/src/librustdoc/html/render/search_index/encode.rs b/src/librustdoc/html/render/search_index/encode.rs
new file mode 100644
index 00000000000..54407c614c4
--- /dev/null
+++ b/src/librustdoc/html/render/search_index/encode.rs
@@ -0,0 +1,243 @@
+use base64::prelude::*;
+
+pub(crate) fn write_vlqhex_to_string(n: i32, string: &mut String) {
+    let (sign, magnitude): (bool, u32) =
+        if n >= 0 { (false, n.try_into().unwrap()) } else { (true, (-n).try_into().unwrap()) };
+    // zig-zag encoding
+    let value: u32 = (magnitude << 1) | (if sign { 1 } else { 0 });
+    // Self-terminating hex use capital letters for everything but the
+    // least significant digit, which is lowercase. For example, decimal 17
+    // would be `` Aa `` if zig-zag encoding weren't used.
+    //
+    // Zig-zag encoding, however, stores the sign bit as the last bit.
+    // This means, in the last hexit, 1 is actually `c`, -1 is `b`
+    // (`a` is the imaginary -0), and, because all the bits are shifted
+    // by one, `` A` `` is actually 8 and `` Aa `` is -8.
+    //
+    // https://rust-lang.github.io/rustc-dev-guide/rustdoc-internals/search.html
+    // describes the encoding in more detail.
+    let mut shift: u32 = 28;
+    let mut mask: u32 = 0xF0_00_00_00;
+    // first skip leading zeroes
+    while shift < 32 {
+        let hexit = (value & mask) >> shift;
+        if hexit != 0 || shift == 0 {
+            break;
+        }
+        shift = shift.wrapping_sub(4);
+        mask = mask >> 4;
+    }
+    // now write the rest
+    while shift < 32 {
+        let hexit = (value & mask) >> shift;
+        let hex = char::try_from(if shift == 0 { '`' } else { '@' } as u32 + hexit).unwrap();
+        string.push(hex);
+        shift = shift.wrapping_sub(4);
+        mask = mask >> 4;
+    }
+}
+
+// Used during bitmap encoding
+enum Container {
+    /// number of ones, bits
+    Bits(Box<[u64; 1024]>),
+    /// list of entries
+    Array(Vec<u16>),
+    /// list of (start, len-1)
+    Run(Vec<(u16, u16)>),
+}
+impl Container {
+    fn popcount(&self) -> u32 {
+        match self {
+            Container::Bits(bits) => bits.iter().copied().map(|x| x.count_ones()).sum(),
+            Container::Array(array) => {
+                array.len().try_into().expect("array can't be bigger than 2**32")
+            }
+            Container::Run(runs) => {
+                runs.iter().copied().map(|(_, lenm1)| u32::from(lenm1) + 1).sum()
+            }
+        }
+    }
+    fn push(&mut self, value: u16) {
+        match self {
+            Container::Bits(bits) => bits[value as usize >> 6] |= 1 << (value & 0x3F),
+            Container::Array(array) => {
+                array.push(value);
+                if array.len() >= 4096 {
+                    let array = std::mem::replace(array, Vec::new());
+                    *self = Container::Bits(Box::new([0; 1024]));
+                    for value in array {
+                        self.push(value);
+                    }
+                }
+            }
+            Container::Run(runs) => {
+                if let Some(r) = runs.last_mut()
+                    && r.0 + r.1 + 1 == value
+                {
+                    r.1 += 1;
+                } else {
+                    runs.push((value, 0));
+                }
+            }
+        }
+    }
+    fn try_make_run(&mut self) -> bool {
+        match self {
+            Container::Bits(bits) => {
+                let mut r: u64 = 0;
+                for (i, chunk) in bits.iter().copied().enumerate() {
+                    let next_chunk =
+                        i.checked_add(1).and_then(|i| bits.get(i)).copied().unwrap_or(0);
+                    r += !chunk & u64::from((chunk << 1).count_ones());
+                    r += !next_chunk & u64::from((chunk >> 63).count_ones());
+                }
+                if (2 + 4 * r) >= 8192 {
+                    return false;
+                }
+                let bits = std::mem::replace(bits, Box::new([0; 1024]));
+                *self = Container::Run(Vec::new());
+                for (i, bits) in bits.iter().copied().enumerate() {
+                    if bits == 0 {
+                        continue;
+                    }
+                    for j in 0..64 {
+                        let value = (u16::try_from(i).unwrap() << 6) | j;
+                        if bits & (1 << j) != 0 {
+                            self.push(value);
+                        }
+                    }
+                }
+                true
+            }
+            Container::Array(array) if array.len() <= 5 => false,
+            Container::Array(array) => {
+                let mut r = 0;
+                let mut prev = None;
+                for value in array.iter().copied() {
+                    if value.checked_sub(1) != prev {
+                        r += 1;
+                    }
+                    prev = Some(value);
+                }
+                if 2 + 4 * r >= 2 * array.len() + 2 {
+                    return false;
+                }
+                let array = std::mem::replace(array, Vec::new());
+                *self = Container::Run(Vec::new());
+                for value in array {
+                    self.push(value);
+                }
+                true
+            }
+            Container::Run(_) => true,
+        }
+    }
+}
+
+// checked against roaring-rs in
+// https://gitlab.com/notriddle/roaring-test
+pub(crate) fn write_bitmap_to_bytes(
+    domain: &[u32],
+    mut out: impl std::io::Write,
+) -> std::io::Result<()> {
+    // https://arxiv.org/pdf/1603.06549.pdf
+    let mut keys = Vec::<u16>::new();
+    let mut containers = Vec::<Container>::new();
+    let mut key: u16;
+    let mut domain_iter = domain.into_iter().copied().peekable();
+    let mut has_run = false;
+    while let Some(entry) = domain_iter.next() {
+        key = (entry >> 16).try_into().expect("shifted off the top 16 bits, so it should fit");
+        let value: u16 = (entry & 0x00_00_FF_FF).try_into().expect("AND 16 bits, so it should fit");
+        let mut container = Container::Array(vec![value]);
+        while let Some(entry) = domain_iter.peek().copied() {
+            let entry_key: u16 =
+                (entry >> 16).try_into().expect("shifted off the top 16 bits, so it should fit");
+            if entry_key != key {
+                break;
+            }
+            domain_iter.next().expect("peeking just succeeded");
+            container
+                .push((entry & 0x00_00_FF_FF).try_into().expect("AND 16 bits, so it should fit"));
+        }
+        keys.push(key);
+        has_run = container.try_make_run() || has_run;
+        containers.push(container);
+    }
+    // https://github.com/RoaringBitmap/RoaringFormatSpec
+    use byteorder::{WriteBytesExt, LE};
+    const SERIAL_COOKIE_NO_RUNCONTAINER: u32 = 12346;
+    const SERIAL_COOKIE: u32 = 12347;
+    const NO_OFFSET_THRESHOLD: u32 = 4;
+    let size: u32 = containers.len().try_into().unwrap();
+    let start_offset = if has_run {
+        out.write_u32::<LE>(SERIAL_COOKIE | ((size - 1) << 16))?;
+        for set in containers.chunks(8) {
+            let mut b = 0;
+            for (i, container) in set.iter().enumerate() {
+                if matches!(container, &Container::Run(..)) {
+                    b |= 1 << i;
+                }
+            }
+            out.write_u8(b)?;
+        }
+        if size < NO_OFFSET_THRESHOLD {
+            4 + 4 * size + ((size + 7) / 8)
+        } else {
+            4 + 8 * size + ((size + 7) / 8)
+        }
+    } else {
+        out.write_u32::<LE>(SERIAL_COOKIE_NO_RUNCONTAINER)?;
+        out.write_u32::<LE>(containers.len().try_into().unwrap())?;
+        4 + 4 + 4 * size + 4 * size
+    };
+    for (&key, container) in keys.iter().zip(&containers) {
+        // descriptive header
+        let key: u32 = key.into();
+        let count: u32 = container.popcount() - 1;
+        out.write_u32::<LE>((count << 16) | key)?;
+    }
+    if !has_run || size >= NO_OFFSET_THRESHOLD {
+        // offset header
+        let mut starting_offset = start_offset;
+        for container in &containers {
+            out.write_u32::<LE>(starting_offset)?;
+            starting_offset += match container {
+                Container::Bits(_) => 8192u32,
+                Container::Array(array) => u32::try_from(array.len()).unwrap() * 2,
+                Container::Run(runs) => 2 + u32::try_from(runs.len()).unwrap() * 4,
+            };
+        }
+    }
+    for container in &containers {
+        match container {
+            Container::Bits(bits) => {
+                for chunk in bits.iter() {
+                    out.write_u64::<LE>(*chunk)?;
+                }
+            }
+            Container::Array(array) => {
+                for value in array.iter() {
+                    out.write_u16::<LE>(*value)?;
+                }
+            }
+            Container::Run(runs) => {
+                out.write_u16::<LE>((runs.len()).try_into().unwrap())?;
+                for (start, lenm1) in runs.iter().copied() {
+                    out.write_u16::<LE>(start)?;
+                    out.write_u16::<LE>(lenm1)?;
+                }
+            }
+        }
+    }
+    Ok(())
+}
+
+pub(crate) fn bitmap_to_string(domain: &[u32]) -> String {
+    let mut buf = Vec::new();
+    let mut strbuf = String::new();
+    write_bitmap_to_bytes(&domain, &mut buf).unwrap();
+    BASE64_STANDARD.encode_string(&buf, &mut strbuf);
+    strbuf
+}
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index fbd45b2b48e..c806bf1cc66 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -24,6 +24,7 @@ use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
 use crate::formats::Impl;
 use crate::html::format::Buffer;
+use crate::html::render::search_index::SerializedSearchIndex;
 use crate::html::render::{AssocItemLink, ImplRenderingParameters};
 use crate::html::{layout, static_files};
 use crate::visit::DocVisitor;
@@ -46,7 +47,7 @@ use crate::{try_err, try_none};
 pub(super) fn write_shared(
     cx: &mut Context<'_>,
     krate: &Crate,
-    search_index: String,
+    search_index: SerializedSearchIndex,
     options: &RenderOptions,
 ) -> Result<(), Error> {
     // Write out the shared files. Note that these are shared among all rustdoc
@@ -312,7 +313,7 @@ pub(super) fn write_shared(
     let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix));
     let (mut all_indexes, mut krates) =
         try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst);
-    all_indexes.push(search_index);
+    all_indexes.push(search_index.index);
     krates.push(krate.name(cx.tcx()).to_string());
     krates.sort();
 
@@ -335,6 +336,32 @@ else if (window.initSearch) window.initSearch(searchIndex);
         Ok(v.into_bytes())
     })?;
 
+    let search_desc_dir = cx.dst.join(format!("search.desc/{krate}", krate = krate.name(cx.tcx())));
+    if Path::new(&search_desc_dir).exists() {
+        try_err!(std::fs::remove_dir_all(&search_desc_dir), &search_desc_dir);
+    }
+    try_err!(std::fs::create_dir_all(&search_desc_dir), &search_desc_dir);
+    let kratename = krate.name(cx.tcx()).to_string();
+    for (i, (_, data)) in search_index.desc.into_iter().enumerate() {
+        let output_filename = static_files::suffix_path(
+            &format!("{kratename}-desc-{i}-.js"),
+            &cx.shared.resource_suffix,
+        );
+        let path = search_desc_dir.join(output_filename);
+        try_err!(
+            std::fs::write(
+                &path,
+                &format!(
+                    r##"searchState.loadedDescShard({kratename}, {i}, {data})"##,
+                    kratename = serde_json::to_string(&kratename).unwrap(),
+                    data = serde_json::to_string(&data).unwrap(),
+                )
+                .into_bytes()
+            ),
+            &path
+        );
+    }
+
     write_invocation_specific("crates.js", &|| {
         let krates = krates.iter().map(|k| format!("\"{k}\"")).join(",");
         Ok(format!("window.ALL_CRATES = [{krates}];").into_bytes())
diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js
index 1a34530c2d1..a1e9cc6dfa1 100644
--- a/src/librustdoc/html/static/.eslintrc.js
+++ b/src/librustdoc/html/static/.eslintrc.js
@@ -5,7 +5,7 @@ module.exports = {
     },
     "extends": "eslint:recommended",
     "parserOptions": {
-        "ecmaVersion": 2015,
+        "ecmaVersion": 8,
         "sourceType": "module"
     },
     "rules": {
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index b9a769a7c6d..940b62be0c9 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -329,6 +329,30 @@ function preLoadCss(cssUrl) {
             search.innerHTML = "<h3 class=\"search-loading\">" + searchState.loadingText + "</h3>";
             searchState.showResults(search);
         },
+        descShards: new Map(),
+        loadDesc: async function({descShard, descIndex}) {
+            if (descShard.promise === null) {
+                descShard.promise = new Promise((resolve, reject) => {
+                    // The `resolve` callback is stored in the `descShard`
+                    // object, which is itself stored in `this.descShards` map.
+                    // It is called in `loadedDescShard` by the
+                    // search.desc script.
+                    descShard.resolve = resolve;
+                    const ds = descShard;
+                    const fname = `${ds.crate}-desc-${ds.shard}-`;
+                    const url = resourcePath(
+                        `search.desc/${descShard.crate}/${fname}`,
+                        ".js",
+                    );
+                    loadScript(url, reject);
+                });
+            }
+            const list = await descShard.promise;
+            return list[descIndex];
+        },
+        loadedDescShard: function(crate, shard, data) {
+            this.descShards.get(crate)[shard].resolve(data.split("\n"));
+        },
     };
 
     const toggleAllDocsId = "toggle-all-docs";
@@ -381,7 +405,7 @@ function preLoadCss(cssUrl) {
                                     window.location.replace("#" + item.id);
                                 }, 0);
                             }
-                        }
+                        },
                     );
                 }
             }
@@ -585,7 +609,7 @@ function preLoadCss(cssUrl) {
         const script = document
             .querySelector("script[data-ignore-extern-crates]");
         const ignoreExternCrates = new Set(
-            (script ? script.getAttribute("data-ignore-extern-crates") : "").split(",")
+            (script ? script.getAttribute("data-ignore-extern-crates") : "").split(","),
         );
         for (const lib of libs) {
             if (lib === window.currentCrate || ignoreExternCrates.has(lib)) {
@@ -1098,7 +1122,7 @@ function preLoadCss(cssUrl) {
         } else {
             wrapper.style.setProperty(
                 "--popover-arrow-offset",
-                (wrapperPos.right - pos.right + 4) + "px"
+                (wrapperPos.right - pos.right + 4) + "px",
             );
         }
         wrapper.style.visibility = "";
@@ -1680,7 +1704,7 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
                 pendingSidebarResizingFrame = false;
                 document.documentElement.style.setProperty(
                     "--resizing-sidebar-width",
-                    desiredSidebarSize + "px"
+                    desiredSidebarSize + "px",
                 );
             }, 100);
         }
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 875ebe2fc90..3daf1ad22de 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -206,14 +206,14 @@ const editDistanceState = {
                     // insertion
                     this.current[j - 1] + 1,
                     // substitution
-                    this.prev[j - 1] + substitutionCost
+                    this.prev[j - 1] + substitutionCost,
                 );
 
                 if ((i > 1) && (j > 1) && (a[aIdx] === b[bIdx - 1]) && (a[aIdx - 1] === b[bIdx])) {
                     // transposition
                     this.current[j] = Math.min(
                         this.current[j],
-                        this.prevPrev[j - 2] + 1
+                        this.prevPrev[j - 2] + 1,
                     );
                 }
             }
@@ -243,6 +243,14 @@ function initSearch(rawSearchIndex) {
      */
     let searchIndex;
     /**
+     * @type {Map<String, RoaringBitmap>}
+     */
+    let searchIndexDeprecated;
+    /**
+     * @type {Map<String, RoaringBitmap>}
+     */
+    let searchIndexEmptyDesc;
+    /**
      *  @type {Uint32Array}
      */
     let functionTypeFingerprint;
@@ -426,7 +434,7 @@ function initSearch(rawSearchIndex) {
         return c === "," || c === "=";
     }
 
-/**
+    /**
      * Returns `true` if the given `c` character is a path separator. For example
      * `:` in `a::b` or a whitespace in `a b`.
      *
@@ -856,8 +864,8 @@ function initSearch(rawSearchIndex) {
                         parserState,
                         parserState.userQuery.slice(start, end),
                         generics,
-                        isInGenerics
-                    )
+                        isInGenerics,
+                    ),
                 );
             }
         }
@@ -1295,7 +1303,7 @@ function initSearch(rawSearchIndex) {
      *
      * @return {ResultsTable}
      */
-    function execQuery(parsedQuery, filterCrates, currentCrate) {
+    async function execQuery(parsedQuery, filterCrates, currentCrate) {
         const results_others = new Map(), results_in_args = new Map(),
             results_returned = new Map();
 
@@ -1342,9 +1350,9 @@ function initSearch(rawSearchIndex) {
          * @param {Results} results
          * @param {boolean} isType
          * @param {string} preferredCrate
-         * @returns {[ResultObject]}
+         * @returns {Promise<[ResultObject]>}
          */
-        function sortResults(results, isType, preferredCrate) {
+        async function sortResults(results, isType, preferredCrate) {
             const userQuery = parsedQuery.userQuery;
             const result_list = [];
             for (const result of results.values()) {
@@ -1394,8 +1402,8 @@ function initSearch(rawSearchIndex) {
                 }
 
                 // sort deprecated items later
-                a = aaa.item.deprecated;
-                b = bbb.item.deprecated;
+                a = searchIndexDeprecated.get(aaa.item.crate).contains(aaa.item.bitIndex);
+                b = searchIndexDeprecated.get(bbb.item.crate).contains(bbb.item.bitIndex);
                 if (a !== b) {
                     return a - b;
                 }
@@ -1422,8 +1430,8 @@ function initSearch(rawSearchIndex) {
                 }
 
                 // sort by description (no description goes later)
-                a = (aaa.item.desc === "");
-                b = (bbb.item.desc === "");
+                a = searchIndexEmptyDesc.get(aaa.item.crate).contains(aaa.item.bitIndex);
+                b = searchIndexEmptyDesc.get(bbb.item.crate).contains(bbb.item.bitIndex);
                 if (a !== b) {
                     return a - b;
                 }
@@ -1446,7 +1454,16 @@ function initSearch(rawSearchIndex) {
                 return 0;
             });
 
-            return transformResults(result_list);
+            const transformed = transformResults(result_list);
+            const descs = await Promise.all(transformed.map(result => {
+                return searchIndexEmptyDesc.get(result.crate).contains(result.bitIndex) ?
+                    "" :
+                    searchState.loadDesc(result);
+            }));
+            for (const [i, result] of transformed.entries()) {
+                result.desc = descs[i];
+            }
+            return transformed;
         }
 
         /**
@@ -1477,7 +1494,7 @@ function initSearch(rawSearchIndex) {
             whereClause,
             mgensIn,
             solutionCb,
-            unboxingDepth
+            unboxingDepth,
         ) {
             if (unboxingDepth >= UNBOXING_LIMIT) {
                 return false;
@@ -1524,7 +1541,7 @@ function initSearch(rawSearchIndex) {
                         queryElem,
                         whereClause,
                         mgens,
-                        unboxingDepth + 1
+                        unboxingDepth + 1,
                     )) {
                         continue;
                     }
@@ -1541,7 +1558,7 @@ function initSearch(rawSearchIndex) {
                             whereClause,
                             mgensScratch,
                             solutionCb,
-                            unboxingDepth + 1
+                            unboxingDepth + 1,
                         )) {
                             return true;
                         }
@@ -1551,7 +1568,7 @@ function initSearch(rawSearchIndex) {
                         whereClause,
                         mgens ? new Map(mgens) : null,
                         solutionCb,
-                        unboxingDepth + 1
+                        unboxingDepth + 1,
                     )) {
                         return true;
                     }
@@ -1625,7 +1642,7 @@ function initSearch(rawSearchIndex) {
                             queryElem,
                             whereClause,
                             mgensScratch,
-                            unboxingDepth
+                            unboxingDepth,
                         );
                         if (!solution) {
                             return false;
@@ -1638,7 +1655,7 @@ function initSearch(rawSearchIndex) {
                                 whereClause,
                                 simplifiedMgens,
                                 solutionCb,
-                                unboxingDepth
+                                unboxingDepth,
                             );
                             if (passesUnification) {
                                 return true;
@@ -1646,7 +1663,7 @@ function initSearch(rawSearchIndex) {
                         }
                         return false;
                     },
-                    unboxingDepth
+                    unboxingDepth,
                 );
                 if (passesUnification) {
                     return true;
@@ -1663,7 +1680,7 @@ function initSearch(rawSearchIndex) {
                     queryElem,
                     whereClause,
                     mgens,
-                    unboxingDepth + 1
+                    unboxingDepth + 1,
                 )) {
                     continue;
                 }
@@ -1689,7 +1706,7 @@ function initSearch(rawSearchIndex) {
                     whereClause,
                     mgensScratch,
                     solutionCb,
-                    unboxingDepth + 1
+                    unboxingDepth + 1,
                 );
                 if (passesUnification) {
                     return true;
@@ -1820,7 +1837,7 @@ function initSearch(rawSearchIndex) {
             queryElem,
             whereClause,
             mgensIn,
-            unboxingDepth
+            unboxingDepth,
         ) {
             if (fnType.bindings.size < queryElem.bindings.size) {
                 return false;
@@ -1849,7 +1866,7 @@ function initSearch(rawSearchIndex) {
                                 // possible solutions
                                 return false;
                             },
-                            unboxingDepth
+                            unboxingDepth,
                         );
                         return newSolutions;
                     });
@@ -1887,7 +1904,7 @@ function initSearch(rawSearchIndex) {
             queryElem,
             whereClause,
             mgens,
-            unboxingDepth
+            unboxingDepth,
         ) {
             if (unboxingDepth >= UNBOXING_LIMIT) {
                 return false;
@@ -1914,7 +1931,7 @@ function initSearch(rawSearchIndex) {
                     queryElem,
                     whereClause,
                     mgensTmp,
-                    unboxingDepth
+                    unboxingDepth,
                 );
             } else if (fnType.generics.length > 0 || fnType.bindings.size > 0) {
                 const simplifiedGenerics = [
@@ -1926,7 +1943,7 @@ function initSearch(rawSearchIndex) {
                     queryElem,
                     whereClause,
                     mgens,
-                    unboxingDepth
+                    unboxingDepth,
                 );
             }
             return false;
@@ -1975,7 +1992,7 @@ function initSearch(rawSearchIndex) {
                         elem,
                         whereClause,
                         mgens,
-                        unboxingDepth + 1
+                        unboxingDepth + 1,
                     );
                 }
                 if (row.id > 0 && elem.id > 0 && elem.pathWithoutLast.length === 0 &&
@@ -1989,7 +2006,7 @@ function initSearch(rawSearchIndex) {
                         elem,
                         whereClause,
                         mgens,
-                        unboxingDepth
+                        unboxingDepth,
                     );
                 }
             }
@@ -2007,7 +2024,7 @@ function initSearch(rawSearchIndex) {
                 return 0;
             }
             const maxPathEditDistance = Math.floor(
-                contains.reduce((acc, next) => acc + next.length, 0) / 3
+                contains.reduce((acc, next) => acc + next.length, 0) / 3,
             );
             let ret_dist = maxPathEditDistance + 1;
             const path = ty.path.split("::");
@@ -2066,12 +2083,13 @@ function initSearch(rawSearchIndex) {
                 crate: item.crate,
                 name: item.name,
                 path: item.path,
-                desc: item.desc,
+                descShard: item.descShard,
+                descIndex: item.descIndex,
                 ty: item.ty,
                 parent: item.parent,
                 type: item.type,
                 is_alias: true,
-                deprecated: item.deprecated,
+                bitIndex: item.bitIndex,
                 implDisambiguator: item.implDisambiguator,
             };
         }
@@ -2192,7 +2210,7 @@ function initSearch(rawSearchIndex) {
             results_others,
             results_in_args,
             results_returned,
-            maxEditDistance
+            maxEditDistance,
         ) {
             if (!row || (filterCrates !== null && row.crate !== filterCrates)) {
                 return;
@@ -2204,7 +2222,7 @@ function initSearch(rawSearchIndex) {
             // atoms in the function not present in the query
             const tfpDist = compareTypeFingerprints(
                 fullId,
-                parsedQuery.typeFingerprint
+                parsedQuery.typeFingerprint,
             );
             if (tfpDist !== null) {
                 const in_args = row.type && row.type.inputs
@@ -2276,7 +2294,7 @@ function initSearch(rawSearchIndex) {
 
             const tfpDist = compareTypeFingerprints(
                 row.id,
-                parsedQuery.typeFingerprint
+                parsedQuery.typeFingerprint,
             );
             if (tfpDist === null) {
                 return;
@@ -2298,10 +2316,10 @@ function initSearch(rawSearchIndex) {
                         row.type.where_clause,
                         mgens,
                         null,
-                        0 // unboxing depth
+                        0, // unboxing depth
                     );
                 },
-                0 // unboxing depth
+                0, // unboxing depth
             )) {
                 return;
             }
@@ -2419,7 +2437,7 @@ function initSearch(rawSearchIndex) {
                         }
 
                         return [typeNameIdMap.get(name).id, constraints];
-                    })
+                    }),
                 );
             }
 
@@ -2446,7 +2464,7 @@ function initSearch(rawSearchIndex) {
                             results_others,
                             results_in_args,
                             results_returned,
-                            maxEditDistance
+                            maxEditDistance,
                         );
                     }
                 }
@@ -2477,10 +2495,15 @@ function initSearch(rawSearchIndex) {
             innerRunQuery();
         }
 
-        const ret = createQueryResults(
+        const [sorted_in_args, sorted_returned, sorted_others] = await Promise.all([
             sortResults(results_in_args, true, currentCrate),
             sortResults(results_returned, true, currentCrate),
             sortResults(results_others, false, currentCrate),
+        ]);
+        const ret = createQueryResults(
+            sorted_in_args,
+            sorted_returned,
+            sorted_others,
             parsedQuery);
         handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates, currentCrate);
         if (parsedQuery.error !== null && ret.others.length !== 0) {
@@ -2581,14 +2604,14 @@ function initSearch(rawSearchIndex) {
      * @param {ParsedQuery} query
      * @param {boolean}     display - True if this is the active tab
      */
-    function addTab(array, query, display) {
+    async function addTab(array, query, display) {
         const extraClass = display ? " active" : "";
 
         const output = document.createElement("div");
         if (array.length > 0) {
             output.className = "search-results " + extraClass;
 
-            array.forEach(item => {
+            for (const item of array) {
                 const name = item.name;
                 const type = itemTypes[item.ty];
                 const longType = longItemTypes[item.ty];
@@ -2624,7 +2647,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
 
                 link.appendChild(description);
                 output.appendChild(link);
-            });
+            }
         } else if (query.error === null) {
             output.className = "search-failed" + extraClass;
             output.innerHTML = "No results :(<br/>" +
@@ -2666,7 +2689,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
      * @param {boolean} go_to_first
      * @param {string} filterCrates
      */
-    function showResults(results, go_to_first, filterCrates) {
+    async function showResults(results, go_to_first, filterCrates) {
         const search = searchState.outputElement();
         if (go_to_first || (results.others.length === 1
             && getSettingValue("go-to-only-result") === "true")
@@ -2699,9 +2722,11 @@ ${item.displayPath}<span class="${type}">${name}</span>\
 
         currentResults = results.query.userQuery;
 
-        const ret_others = addTab(results.others, results.query, true);
-        const ret_in_args = addTab(results.in_args, results.query, false);
-        const ret_returned = addTab(results.returned, results.query, false);
+        const [ret_others, ret_in_args, ret_returned] = await Promise.all([
+            addTab(results.others, results.query, true),
+            addTab(results.in_args, results.query, false),
+            addTab(results.returned, results.query, false),
+        ]);
 
         // Navigate to the relevant tab if the current tab is empty, like in case users search
         // for "-> String". If they had selected another tab previously, they have to click on
@@ -2822,7 +2847,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
      * and display the results.
      * @param {boolean} [forced]
      */
-    function search(forced) {
+    async function search(forced) {
         const query = parseQuery(searchState.input.value.trim());
         let filterCrates = getFilterCrates();
 
@@ -2850,8 +2875,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         // recent search query is added to the browser history.
         updateSearchHistory(buildUrl(query.original, filterCrates));
 
-        showResults(
-            execQuery(query, filterCrates, window.currentCrate),
+        await showResults(
+            await execQuery(query, filterCrates, window.currentCrate),
             params.go_to_first,
             filterCrates);
     }
@@ -2920,7 +2945,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             pathIndex = type[PATH_INDEX_DATA];
             generics = buildItemSearchTypeAll(
                 type[GENERICS_DATA],
-                lowercasePaths
+                lowercasePaths,
             );
             if (type.length > BINDINGS_DATA && type[BINDINGS_DATA].length > 0) {
                 bindings = new Map(type[BINDINGS_DATA].map(binding => {
@@ -3030,101 +3055,49 @@ ${item.displayPath}<span class="${type}">${name}</span>\
      * The raw function search type format is generated using serde in
      * librustdoc/html/render/mod.rs: IndexItemFunctionType::write_to_string
      *
-     * @param {{
-     *  string: string,
-     *  offset: number,
-     *  backrefQueue: FunctionSearchType[]
-     * }} itemFunctionDecoder
      * @param {Array<{name: string, ty: number}>} lowercasePaths
-     * @param {Map<string, integer>}
      *
      * @return {null|FunctionSearchType}
      */
-    function buildFunctionSearchType(itemFunctionDecoder, lowercasePaths) {
-        const c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset);
-        itemFunctionDecoder.offset += 1;
-        const [zero, ua, la, ob, cb] = ["0", "@", "`", "{", "}"].map(c => c.charCodeAt(0));
-        // `` ` `` is used as a sentinel because it's fewer bytes than `null`, and decodes to zero
-        // `0` is a backref
-        if (c === la) {
-            return null;
-        }
-        // sixteen characters after "0" are backref
-        if (c >= zero && c < ua) {
-            return itemFunctionDecoder.backrefQueue[c - zero];
-        }
-        if (c !== ob) {
-            throw ["Unexpected ", c, " in function: expected ", "{", "; this is a bug"];
-        }
-        // call after consuming `{`
-        function decodeList() {
-            let c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset);
-            const ret = [];
-            while (c !== cb) {
-                ret.push(decode());
-                c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset);
-            }
-            itemFunctionDecoder.offset += 1; // eat cb
-            return ret;
-        }
-        // consumes and returns a list or integer
-        function decode() {
-            let n = 0;
-            let c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset);
-            if (c === ob) {
-                itemFunctionDecoder.offset += 1;
-                return decodeList();
-            }
-            while (c < la) {
-                n = (n << 4) | (c & 0xF);
-                itemFunctionDecoder.offset += 1;
-                c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset);
-            }
-            // last character >= la
-            n = (n << 4) | (c & 0xF);
-            const [sign, value] = [n & 1, n >> 1];
-            itemFunctionDecoder.offset += 1;
-            return sign ? -value : value;
-        }
-        const functionSearchType = decodeList();
-        const INPUTS_DATA = 0;
-        const OUTPUT_DATA = 1;
-        let inputs, output;
-        if (typeof functionSearchType[INPUTS_DATA] === "number") {
-            inputs = [buildItemSearchType(functionSearchType[INPUTS_DATA], lowercasePaths)];
-        } else {
-            inputs = buildItemSearchTypeAll(
-                functionSearchType[INPUTS_DATA],
-                lowercasePaths
-            );
-        }
-        if (functionSearchType.length > 1) {
-            if (typeof functionSearchType[OUTPUT_DATA] === "number") {
-                output = [buildItemSearchType(functionSearchType[OUTPUT_DATA], lowercasePaths)];
+    function buildFunctionSearchTypeCallback(lowercasePaths) {
+        return functionSearchType => {
+            if (functionSearchType === 0) {
+                return null;
+            }
+            const INPUTS_DATA = 0;
+            const OUTPUT_DATA = 1;
+            let inputs, output;
+            if (typeof functionSearchType[INPUTS_DATA] === "number") {
+                inputs = [buildItemSearchType(functionSearchType[INPUTS_DATA], lowercasePaths)];
             } else {
-                output = buildItemSearchTypeAll(
-                    functionSearchType[OUTPUT_DATA],
-                    lowercasePaths
+                inputs = buildItemSearchTypeAll(
+                    functionSearchType[INPUTS_DATA],
+                    lowercasePaths,
                 );
             }
-        } else {
-            output = [];
-        }
-        const where_clause = [];
-        const l = functionSearchType.length;
-        for (let i = 2; i < l; ++i) {
-            where_clause.push(typeof functionSearchType[i] === "number"
-                ? [buildItemSearchType(functionSearchType[i], lowercasePaths)]
-                : buildItemSearchTypeAll(functionSearchType[i], lowercasePaths));
-        }
-        const ret = {
-            inputs, output, where_clause,
+            if (functionSearchType.length > 1) {
+                if (typeof functionSearchType[OUTPUT_DATA] === "number") {
+                    output = [buildItemSearchType(functionSearchType[OUTPUT_DATA], lowercasePaths)];
+                } else {
+                    output = buildItemSearchTypeAll(
+                        functionSearchType[OUTPUT_DATA],
+                        lowercasePaths,
+                    );
+                }
+            } else {
+                output = [];
+            }
+            const where_clause = [];
+            const l = functionSearchType.length;
+            for (let i = 2; i < l; ++i) {
+                where_clause.push(typeof functionSearchType[i] === "number"
+                    ? [buildItemSearchType(functionSearchType[i], lowercasePaths)]
+                    : buildItemSearchTypeAll(functionSearchType[i], lowercasePaths));
+            }
+            return {
+                inputs, output, where_clause,
+            };
         };
-        itemFunctionDecoder.backrefQueue.unshift(ret);
-        if (itemFunctionDecoder.backrefQueue.length > 16) {
-            itemFunctionDecoder.backrefQueue.pop();
-        }
-        return ret;
     }
 
     /**
@@ -3245,6 +3218,185 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         return functionTypeFingerprint[(fullId * 4) + 3];
     }
 
+    class VlqHexDecoder {
+        constructor(string, cons) {
+            this.string = string;
+            this.cons = cons;
+            this.offset = 0;
+            this.backrefQueue = [];
+        }
+        // call after consuming `{`
+        decodeList() {
+            const cb = "}".charCodeAt(0);
+            let c = this.string.charCodeAt(this.offset);
+            const ret = [];
+            while (c !== cb) {
+                ret.push(this.decode());
+                c = this.string.charCodeAt(this.offset);
+            }
+            this.offset += 1; // eat cb
+            return ret;
+        }
+        // consumes and returns a list or integer
+        decode() {
+            const [ob, la] = ["{", "`"].map(c => c.charCodeAt(0));
+            let n = 0;
+            let c = this.string.charCodeAt(this.offset);
+            if (c === ob) {
+                this.offset += 1;
+                return this.decodeList();
+            }
+            while (c < la) {
+                n = (n << 4) | (c & 0xF);
+                this.offset += 1;
+                c = this.string.charCodeAt(this.offset);
+            }
+            // last character >= la
+            n = (n << 4) | (c & 0xF);
+            const [sign, value] = [n & 1, n >> 1];
+            this.offset += 1;
+            return sign ? -value : value;
+        }
+        next() {
+            const c = this.string.charCodeAt(this.offset);
+            const [zero, ua, la] = ["0", "@", "`"].map(c => c.charCodeAt(0));
+            // sixteen characters after "0" are backref
+            if (c >= zero && c < ua) {
+                this.offset += 1;
+                return this.backrefQueue[c - zero];
+            }
+            // special exception: 0 doesn't use backref encoding
+            // it's already one character, and it's always nullish
+            if (c === la) {
+                this.offset += 1;
+                return this.cons(0);
+            }
+            const result = this.cons(this.decode());
+            this.backrefQueue.unshift(result);
+            if (this.backrefQueue.length > 16) {
+                this.backrefQueue.pop();
+            }
+            return result;
+        }
+    }
+    class RoaringBitmap {
+        constructor(str) {
+            const strdecoded = atob(str);
+            const u8array = new Uint8Array(strdecoded.length);
+            for (let j = 0; j < strdecoded.length; ++j) {
+                u8array[j] = strdecoded.charCodeAt(j);
+            }
+            const has_runs = u8array[0] === 0x3b;
+            const size = has_runs ?
+                ((u8array[2] | (u8array[3] << 8)) + 1) :
+                ((u8array[4] | (u8array[5] << 8) | (u8array[6] << 16) | (u8array[7] << 24)));
+            let i = has_runs ? 4 : 8;
+            let is_run;
+            if (has_runs) {
+                const is_run_len = Math.floor((size + 7) / 8);
+                is_run = u8array.slice(i, i + is_run_len);
+                i += is_run_len;
+            } else {
+                is_run = new Uint8Array();
+            }
+            this.keys = [];
+            this.cardinalities = [];
+            for (let j = 0; j < size; ++j) {
+                this.keys.push(u8array[i] | (u8array[i + 1] << 8));
+                i += 2;
+                this.cardinalities.push((u8array[i] | (u8array[i + 1] << 8)) + 1);
+                i += 2;
+            }
+            this.containers = [];
+            let offsets = null;
+            if (!has_runs || this.keys.length >= 4) {
+                offsets = [];
+                for (let j = 0; j < size; ++j) {
+                    offsets.push(u8array[i] | (u8array[i + 1] << 8) | (u8array[i + 2] << 16) |
+                        (u8array[i + 3] << 24));
+                    i += 4;
+                }
+            }
+            for (let j = 0; j < size; ++j) {
+                if (offsets && offsets[j] !== i) {
+                    console.log(this.containers);
+                    throw new Error(`corrupt bitmap ${j}: ${i} / ${offsets[j]}`);
+                }
+                if (is_run[j >> 3] & (1 << (j & 0x7))) {
+                    const runcount = (u8array[i] | (u8array[i + 1] << 8));
+                    i += 2;
+                    this.containers.push(new RoaringBitmapRun(
+                        runcount,
+                        u8array.slice(i, i + (runcount * 4)),
+                    ));
+                    i += runcount * 4;
+                } else if (this.cardinalities[j] >= 4096) {
+                    this.containers.push(new RoaringBitmapBits(u8array.slice(i, i + 8192)));
+                    i += 8192;
+                } else {
+                    const end = this.cardinalities[j] * 2;
+                    this.containers.push(new RoaringBitmapArray(
+                        this.cardinalities[j],
+                        u8array.slice(i, i + end),
+                    ));
+                    i += end;
+                }
+            }
+        }
+        contains(keyvalue) {
+            const key = keyvalue >> 16;
+            const value = keyvalue & 0xFFFF;
+            for (let i = 0; i < this.keys.length; ++i) {
+                if (this.keys[i] === key) {
+                    return this.containers[i].contains(value);
+                }
+            }
+            return false;
+        }
+    }
+
+    class RoaringBitmapRun {
+        constructor(runcount, array) {
+            this.runcount = runcount;
+            this.array = array;
+        }
+        contains(value) {
+            const l = this.runcount * 4;
+            for (let i = 0; i < l; i += 4) {
+                const start = this.array[i] | (this.array[i + 1] << 8);
+                const lenm1 = this.array[i + 2] | (this.array[i + 3] << 8);
+                if (value >= start && value <= (start + lenm1)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+    class RoaringBitmapArray {
+        constructor(cardinality, array) {
+            this.cardinality = cardinality;
+            this.array = array;
+        }
+        contains(value) {
+            const l = this.cardinality * 2;
+            for (let i = 0; i < l; i += 2) {
+                const start = this.array[i] | (this.array[i + 1] << 8);
+                if (value === start) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+    class RoaringBitmapBits {
+        constructor(array) {
+            this.array = array;
+        }
+        contains(value) {
+            return !!(this.array[value >> 3] & (1 << (value & 7)));
+        }
+    }
+
     /**
      * Convert raw search index into in-memory search index.
      *
@@ -3252,6 +3404,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
      */
     function buildIndex(rawSearchIndex) {
         searchIndex = [];
+        searchIndexDeprecated = new Map();
+        searchIndexEmptyDesc = new Map();
         const charA = "A".charCodeAt(0);
         let currentIndex = 0;
         let id = 0;
@@ -3271,26 +3425,48 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         id = 0;
 
         for (const [crate, crateCorpus] of rawSearchIndex) {
+            // a string representing the lengths of each description shard
+            // a string representing the list of function types
+            const itemDescShardDecoder = new VlqHexDecoder(crateCorpus.D, noop => noop);
+            let descShard = {
+                crate,
+                shard: 0,
+                start: 0,
+                len: itemDescShardDecoder.next(),
+                promise: null,
+                resolve: null,
+            };
+            const descShardList = [ descShard ];
+
+            // Deprecated items and items with no description
+            searchIndexDeprecated.set(crate, new RoaringBitmap(crateCorpus.c));
+            searchIndexEmptyDesc.set(crate, new RoaringBitmap(crateCorpus.e));
+            let descIndex = 0;
+
             // This object should have exactly the same set of fields as the "row"
             // object defined below. Your JavaScript runtime will thank you.
             // https://mathiasbynens.be/notes/shapes-ics
             const crateRow = {
-                crate: crate,
+                crate,
                 ty: 3, // == ExternCrate
                 name: crate,
                 path: "",
-                desc: crateCorpus.doc,
+                descShard,
+                descIndex,
                 parent: undefined,
                 type: null,
-                id: id,
+                id,
                 word: crate,
                 normalizedName: crate.indexOf("_") === -1 ? crate : crate.replace(/_/g, ""),
-                deprecated: null,
+                bitIndex: 0,
                 implDisambiguator: null,
             };
             id += 1;
             searchIndex.push(crateRow);
             currentIndex += 1;
+            if (!searchIndexEmptyDesc.get(crate).contains(0)) {
+                descIndex += 1;
+            }
 
             // a String of one character item type codes
             const itemTypes = crateCorpus.t;
@@ -3302,19 +3478,9 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             // i.e. if indices 4 and 11 are present, but 5-10 and 12-13 are not present,
             // 5-10 will fall back to the path for 4 and 12-13 will fall back to the path for 11
             const itemPaths = new Map(crateCorpus.q);
-            // an array of (String) descriptions
-            const itemDescs = crateCorpus.d;
             // an array of (Number) the parent path index + 1 to `paths`, or 0 if none
             const itemParentIdxs = crateCorpus.i;
-            // a string representing the list of function types
-            const itemFunctionDecoder = {
-                string: crateCorpus.f,
-                offset: 0,
-                backrefQueue: [],
-            };
-            // an array of (Number) indices for the deprecated items
-            const deprecatedItems = new Set(crateCorpus.c);
-            // an array of (Number) indices for the deprecated items
+            // a map Number, string for impl disambiguators
             const implDisambiguator = new Map(crateCorpus.b);
             // an array of [(Number) item type,
             //              (String) name]
@@ -3326,6 +3492,12 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             // an array of [{name: String, ty: Number}]
             const lowercasePaths = [];
 
+            // a string representing the list of function types
+            const itemFunctionDecoder = new VlqHexDecoder(
+                crateCorpus.f,
+                buildFunctionSearchTypeCallback(lowercasePaths),
+            );
+
             // convert `rawPaths` entries into object form
             // generate normalizedPaths for function search mode
             let len = paths.length;
@@ -3354,12 +3526,26 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             lastPath = "";
             len = itemTypes.length;
             for (let i = 0; i < len; ++i) {
+                const bitIndex = i + 1;
+                if (descIndex >= descShard.len &&
+                    !searchIndexEmptyDesc.get(crate).contains(bitIndex)) {
+                    descShard = {
+                        crate,
+                        shard: descShard.shard + 1,
+                        start: descShard.start + descShard.len,
+                        len: itemDescShardDecoder.next(),
+                        promise: null,
+                        resolve: null,
+                    };
+                    descIndex = 0;
+                    descShardList.push(descShard);
+                }
                 let word = "";
                 if (typeof itemNames[i] === "string") {
                     word = itemNames[i].toLowerCase();
                 }
                 const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath;
-                const type = buildFunctionSearchType(itemFunctionDecoder, lowercasePaths);
+                const type = itemFunctionDecoder.next();
                 if (type !== null) {
                     if (type) {
                         const fp = functionTypeFingerprint.subarray(id * 4, (id + 1) * 4);
@@ -3380,22 +3566,26 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 // This object should have exactly the same set of fields as the "crateRow"
                 // object defined above.
                 const row = {
-                    crate: crate,
+                    crate,
                     ty: itemTypes.charCodeAt(i) - charA,
                     name: itemNames[i],
-                    path: path,
-                    desc: itemDescs[i],
+                    path,
+                    descShard,
+                    descIndex,
                     parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined,
                     type,
-                    id: id,
+                    id,
                     word,
                     normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""),
-                    deprecated: deprecatedItems.has(i),
+                    bitIndex,
                     implDisambiguator: implDisambiguator.has(i) ? implDisambiguator.get(i) : null,
                 };
                 id += 1;
                 searchIndex.push(row);
                 lastPath = row.path;
+                if (!searchIndexEmptyDesc.get(crate).contains(bitIndex)) {
+                    descIndex += 1;
+                }
             }
 
             if (aliases) {
@@ -3419,6 +3609,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 }
             }
             currentIndex += itemTypes.length;
+            searchState.descShards.set(crate, descShardList);
         }
         // Drop the (rather large) hash table used for reusing function items
         TYPES_POOL = new Map();
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index bda7b3c647e..73c543567c0 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -211,14 +211,14 @@ function updateSidebarWidth() {
     if (desktopSidebarWidth && desktopSidebarWidth !== "null") {
         document.documentElement.style.setProperty(
             "--desktop-sidebar-width",
-            desktopSidebarWidth + "px"
+            desktopSidebarWidth + "px",
         );
     }
     const srcSidebarWidth = getSettingValue("src-sidebar-width");
     if (srcSidebarWidth && srcSidebarWidth !== "null") {
         document.documentElement.style.setProperty(
             "--src-sidebar-width",
-            srcSidebarWidth + "px"
+            srcSidebarWidth + "px",
         );
     }
 }
diff --git a/src/tools/rustdoc-js/.eslintrc.js b/src/tools/rustdoc-js/.eslintrc.js
index 4ab3a315733..b9d0e251c24 100644
--- a/src/tools/rustdoc-js/.eslintrc.js
+++ b/src/tools/rustdoc-js/.eslintrc.js
@@ -6,7 +6,7 @@ module.exports = {
     },
     "extends": "eslint:recommended",
     "parserOptions": {
-        "ecmaVersion": 2015,
+        "ecmaVersion": 8,
         "sourceType": "module"
     },
     "rules": {
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 86881ef362e..43a22f358c3 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -1,3 +1,4 @@
+/* global globalThis */
 const fs = require("fs");
 const path = require("path");
 
@@ -133,7 +134,7 @@ function valueCheck(fullPath, expected, result, error_text, queryName) {
                     expected_value,
                     result.get(key),
                     error_text,
-                    queryName
+                    queryName,
                 );
             } else {
                 error_text.push(`${queryName}==> EXPECTED has extra key in map from field ` +
@@ -212,11 +213,11 @@ function runParser(query, expected, parseQuery, queryName) {
     return error_text;
 }
 
-function runSearch(query, expected, doSearch, loadedFile, queryName) {
+async function runSearch(query, expected, doSearch, loadedFile, queryName) {
     const ignore_order = loadedFile.ignore_order;
     const exact_check = loadedFile.exact_check;
 
-    const results = doSearch(query, loadedFile.FILTER_CRATE);
+    const results = await doSearch(query, loadedFile.FILTER_CRATE);
     const error_text = [];
 
     for (const key in expected) {
@@ -238,7 +239,7 @@ function runSearch(query, expected, doSearch, loadedFile, queryName) {
         }
 
         let prev_pos = -1;
-        entry.forEach((elem, index) => {
+        for (const [index, elem] of entry.entries()) {
             const entry_pos = lookForEntry(elem, results[key]);
             if (entry_pos === -1) {
                 error_text.push(queryName + "==> Result not found in '" + key + "': '" +
@@ -260,13 +261,13 @@ function runSearch(query, expected, doSearch, loadedFile, queryName) {
             } else {
                 prev_pos = entry_pos;
             }
-        });
+        }
     }
     return error_text;
 }
 
-function runCorrections(query, corrections, getCorrections, loadedFile) {
-    const qc = getCorrections(query, loadedFile.FILTER_CRATE);
+async function runCorrections(query, corrections, getCorrections, loadedFile) {
+    const qc = await getCorrections(query, loadedFile.FILTER_CRATE);
     const error_text = [];
 
     if (corrections === null) {
@@ -299,18 +300,27 @@ function checkResult(error_text, loadedFile, displaySuccess) {
     return 1;
 }
 
-function runCheckInner(callback, loadedFile, entry, getCorrections, extra) {
+async function runCheckInner(callback, loadedFile, entry, getCorrections, extra) {
     if (typeof entry.query !== "string") {
         console.log("FAILED");
         console.log("==> Missing `query` field");
         return false;
     }
-    let error_text = callback(entry.query, entry, extra ? "[ query `" + entry.query + "`]" : "");
+    let error_text = await callback(
+        entry.query,
+        entry,
+        extra ? "[ query `" + entry.query + "`]" : "",
+    );
     if (checkResult(error_text, loadedFile, false) !== 0) {
         return false;
     }
     if (entry.correction !== undefined) {
-        error_text = runCorrections(entry.query, entry.correction, getCorrections, loadedFile);
+        error_text = await runCorrections(
+            entry.query,
+            entry.correction,
+            getCorrections,
+            loadedFile,
+        );
         if (checkResult(error_text, loadedFile, false) !== 0) {
             return false;
         }
@@ -318,16 +328,16 @@ function runCheckInner(callback, loadedFile, entry, getCorrections, extra) {
     return true;
 }
 
-function runCheck(loadedFile, key, getCorrections, callback) {
+async function runCheck(loadedFile, key, getCorrections, callback) {
     const expected = loadedFile[key];
 
     if (Array.isArray(expected)) {
         for (const entry of expected) {
-            if (!runCheckInner(callback, loadedFile, entry, getCorrections, true)) {
+            if (!await runCheckInner(callback, loadedFile, entry, getCorrections, true)) {
                 return 1;
             }
         }
-    } else if (!runCheckInner(callback, loadedFile, expected, getCorrections, false)) {
+    } else if (!await runCheckInner(callback, loadedFile, expected, getCorrections, false)) {
         return 1;
     }
     console.log("OK");
@@ -338,7 +348,7 @@ function hasCheck(content, checkName) {
     return content.startsWith(`const ${checkName}`) || content.includes(`\nconst ${checkName}`);
 }
 
-function runChecks(testFile, doSearch, parseQuery, getCorrections) {
+async function runChecks(testFile, doSearch, parseQuery, getCorrections) {
     let checkExpected = false;
     let checkParsed = false;
     let testFileContent = readFile(testFile);
@@ -367,12 +377,12 @@ function runChecks(testFile, doSearch, parseQuery, getCorrections) {
     let res = 0;
 
     if (checkExpected) {
-        res += runCheck(loadedFile, "EXPECTED", getCorrections, (query, expected, text) => {
+        res += await runCheck(loadedFile, "EXPECTED", getCorrections, (query, expected, text) => {
             return runSearch(query, expected, doSearch, loadedFile, text);
         });
     }
     if (checkParsed) {
-        res += runCheck(loadedFile, "PARSED", getCorrections, (query, expected, text) => {
+        res += await runCheck(loadedFile, "PARSED", getCorrections, (query, expected, text) => {
             return runParser(query, expected, parseQuery, text);
         });
     }
@@ -393,6 +403,35 @@ function loadSearchJS(doc_folder, resource_suffix) {
     const searchIndexJs = path.join(doc_folder, "search-index" + resource_suffix + ".js");
     const searchIndex = require(searchIndexJs);
 
+    globalThis.searchState = {
+        descShards: new Map(),
+        loadDesc: async function({descShard, descIndex}) {
+            if (descShard.promise === null) {
+                descShard.promise = new Promise((resolve, reject) => {
+                    descShard.resolve = resolve;
+                    const ds = descShard;
+                    const fname = `${ds.crate}-desc-${ds.shard}-${resource_suffix}.js`;
+                    fs.readFile(
+                        `${doc_folder}/search.desc/${descShard.crate}/${fname}`,
+                        (err, data) => {
+                            if (err) {
+                                reject(err);
+                            } else {
+                                eval(data.toString("utf8"));
+                            }
+                        },
+                    );
+                });
+            }
+            const list = await descShard.promise;
+            return list[descIndex];
+        },
+        loadedDescShard: function(crate, shard, data) {
+            //console.log(this.descShards);
+            this.descShards.get(crate)[shard].resolve(data.split("\n"));
+        },
+    };
+
     const staticFiles = path.join(doc_folder, "static.files");
     const searchJs = fs.readdirSync(staticFiles).find(f => f.match(/search.*\.js$/));
     const searchModule = require(path.join(staticFiles, searchJs));
@@ -474,7 +513,7 @@ function parseOptions(args) {
     return null;
 }
 
-function main(argv) {
+async function main(argv) {
     const opts = parseOptions(argv.slice(2));
     if (opts === null) {
         return 1;
@@ -482,7 +521,7 @@ function main(argv) {
 
     const parseAndSearch = loadSearchJS(
         opts["doc_folder"],
-        opts["resource_suffix"]
+        opts["resource_suffix"],
     );
     let errors = 0;
 
@@ -494,21 +533,29 @@ function main(argv) {
     };
 
     if (opts["test_file"].length !== 0) {
-        opts["test_file"].forEach(file => {
+        for (const file of opts["test_file"]) {
             process.stdout.write(`Testing ${file} ... `);
-            errors += runChecks(file, doSearch, parseAndSearch.parseQuery, getCorrections);
-        });
+            errors += await runChecks(file, doSearch, parseAndSearch.parseQuery, getCorrections);
+        }
     } else if (opts["test_folder"].length !== 0) {
-        fs.readdirSync(opts["test_folder"]).forEach(file => {
+        for (const file of fs.readdirSync(opts["test_folder"])) {
             if (!file.endsWith(".js")) {
-                return;
+                continue;
             }
             process.stdout.write(`Testing ${file} ... `);
-            errors += runChecks(path.join(opts["test_folder"], file), doSearch,
+            errors += await runChecks(path.join(opts["test_folder"], file), doSearch,
                     parseAndSearch.parseQuery, getCorrections);
-        });
+        }
     }
     return errors > 0 ? 1 : 0;
 }
 
-process.exit(main(process.argv));
+main(process.argv).catch(e => {
+    console.log(e);
+    process.exit(1);
+}).then(x => process.exit(x));
+
+process.on("beforeExit", () => {
+    console.log("process did not complete");
+    process.exit(1);
+});
diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml
index 72e0bcd77e0..3239e54a866 100644
--- a/tests/rustdoc-gui/anchors.goml
+++ b/tests/rustdoc-gui/anchors.goml
@@ -2,7 +2,7 @@
 
 define-function: (
     "check-colors",
-    (theme, main_color, title_color, main_heading_color, main_heading_type_color, src_link_color, sidebar_link_color),
+    [theme, main_color, title_color, main_heading_color, main_heading_type_color, src_link_color, sidebar_link_color],
     block {
         go-to: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html"
         // This is needed to ensure that the text color is computed.
diff --git a/tests/rustdoc-gui/code-color.goml b/tests/rustdoc-gui/code-color.goml
index 92bdfb25b00..e17af5e7f1f 100644
--- a/tests/rustdoc-gui/code-color.goml
+++ b/tests/rustdoc-gui/code-color.goml
@@ -8,7 +8,7 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (theme, doc_code_color, doc_inline_code_color),
+    [theme, doc_code_color, doc_inline_code_color],
     block {
         // Set the theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
diff --git a/tests/rustdoc-gui/codeblock-tooltip.goml b/tests/rustdoc-gui/codeblock-tooltip.goml
index 7be5e39ba47..19e3927f642 100644
--- a/tests/rustdoc-gui/codeblock-tooltip.goml
+++ b/tests/rustdoc-gui/codeblock-tooltip.goml
@@ -4,7 +4,7 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (theme, background, color, border),
+    [theme, background, color, border],
     block {
         // Setting the theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
diff --git a/tests/rustdoc-gui/cursor.goml b/tests/rustdoc-gui/cursor.goml
index 27c955f5a13..9412987fc32 100644
--- a/tests/rustdoc-gui/cursor.goml
+++ b/tests/rustdoc-gui/cursor.goml
@@ -8,7 +8,7 @@ assert-css: ("#toggle-all-docs", {"cursor": "pointer"})
 assert-css: ("#copy-path", {"cursor": "pointer"})
 
 // the search tabs
-write: (".search-input", "Foo")
+write-into: (".search-input", "Foo")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml
index a50449e1701..cb7bdaab4c8 100644
--- a/tests/rustdoc-gui/docblock-code-block-line-number.goml
+++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml
@@ -10,7 +10,7 @@ assert-false: "pre.example-line-numbers"
 // Let's now check some CSS properties...
 define-function: (
     "check-colors",
-    (theme, color),
+    [theme, color],
     block {
         // We now set the setting to show the line numbers on code examples.
         set-local-storage: {
diff --git a/tests/rustdoc-gui/docblock-table.goml b/tests/rustdoc-gui/docblock-table.goml
index 678b302f22e..db6d065a4b3 100644
--- a/tests/rustdoc-gui/docblock-table.goml
+++ b/tests/rustdoc-gui/docblock-table.goml
@@ -6,7 +6,7 @@ compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock tab
 
 define-function: (
     "check-colors",
-    (theme, border_color, zebra_stripe_color),
+    [theme, border_color, zebra_stripe_color],
     block {
         set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
         reload:
diff --git a/tests/rustdoc-gui/escape-key.goml b/tests/rustdoc-gui/escape-key.goml
index 3ea20fd118e..ff8557b9b81 100644
--- a/tests/rustdoc-gui/escape-key.goml
+++ b/tests/rustdoc-gui/escape-key.goml
@@ -2,7 +2,7 @@
 // current content displayed.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // First, we check that the search results are hidden when the Escape key is pressed.
-write: (".search-input", "test")
+write-into: (".search-input", "test")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 wait-for: "#search h1" // The search element is empty before the first search
diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml
index c01c8bb1019..f8c495ec18a 100644
--- a/tests/rustdoc-gui/globals.goml
+++ b/tests/rustdoc-gui/globals.goml
@@ -10,7 +10,7 @@ assert-window-property: {"srcIndex": null}
 
 // Form input
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "Foo")
+write-into: (".search-input", "Foo")
 press-key: 'Enter'
 wait-for: "#search-tabs"
 assert-window-property-false: {"searchIndex": null}
diff --git a/tests/rustdoc-gui/go-to-collapsed-elem.goml b/tests/rustdoc-gui/go-to-collapsed-elem.goml
index 80e9791775e..e56e7ba08cd 100644
--- a/tests/rustdoc-gui/go-to-collapsed-elem.goml
+++ b/tests/rustdoc-gui/go-to-collapsed-elem.goml
@@ -9,14 +9,14 @@ set-property: ("#implementations-list .implementors-toggle", {"open": "false"})
 click: "//*[@class='sidebar']//a[@href='#method.must_use']"
 assert-property: ("#implementations-list .implementors-toggle", {"open": "true"})
 
-define-function: ("collapsed-from-search", (), block {
+define-function: ("collapsed-from-search", [], block {
     // Now we do the same through search result.
     // First we reload the page without the anchor in the URL.
     go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
     // Then we collapse the section again...
     set-property: ("#implementations-list .implementors-toggle", {"open": "false"})
     // Then we run the search.
-    write: (".search-input", "foo::must_use")
+    write-into: (".search-input", "foo::must_use")
     wait-for: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']"
     click: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']"
     assert-property: ("#implementations-list .implementors-toggle", {"open": "true"})
diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml
index 80d11c9c849..2a181c0669f 100644
--- a/tests/rustdoc-gui/headers-color.goml
+++ b/tests/rustdoc-gui/headers-color.goml
@@ -2,7 +2,7 @@
 
 define-function: (
     "check-colors",
-    (theme, color, code_header_color, focus_background_color, headings_color),
+    [theme, color, code_header_color, focus_background_color, headings_color],
     block {
         go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
         // This is needed so that the text color is computed.
diff --git a/tests/rustdoc-gui/headings-anchor.goml b/tests/rustdoc-gui/headings-anchor.goml
index f568caa3b07..9d52c2ac4b5 100644
--- a/tests/rustdoc-gui/headings-anchor.goml
+++ b/tests/rustdoc-gui/headings-anchor.goml
@@ -4,7 +4,7 @@ show-text: true
 
 define-function: (
     "check-heading-anchor",
-    (heading_id),
+    [heading_id],
     block {
         // The anchor should not be displayed by default.
         assert-css: ("#" + |heading_id| + " .doc-anchor", { "display": "none" })
@@ -27,6 +27,6 @@ move-cursor-to: "#top-doc-prose-title"
 // to prevent it from overlapping with the `[-]` element.
 assert-css: ("#top-doc-prose-title:hover .doc-anchor", { "display": "none" })
 
-call-function: ("check-heading-anchor", ("top-doc-prose-sub-heading"))
-call-function: ("check-heading-anchor", ("top-doc-prose-sub-sub-heading"))
-call-function: ("check-heading-anchor", ("you-know-the-drill"))
+call-function: ("check-heading-anchor", {"heading_id": "top-doc-prose-sub-heading"})
+call-function: ("check-heading-anchor", {"heading_id": "top-doc-prose-sub-sub-heading"})
+call-function: ("check-heading-anchor", {"heading_id": "you-know-the-drill"})
diff --git a/tests/rustdoc-gui/headings.goml b/tests/rustdoc-gui/headings.goml
index 102b699b1dd..cdc61e36be2 100644
--- a/tests/rustdoc-gui/headings.goml
+++ b/tests/rustdoc-gui/headings.goml
@@ -156,7 +156,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"
 
 define-function: (
     "check-colors",
-    (theme, heading_color, small_heading_color, heading_border_color),
+    [theme, heading_color, small_heading_color, heading_border_color],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
@@ -220,7 +220,7 @@ call-function: (
 
 define-function: (
     "check-since-color",
-    (theme),
+    [theme],
     block {
         set-local-storage: {"rustdoc-theme": |theme|}
         reload:
@@ -229,6 +229,6 @@ define-function: (
 )
 
 go-to: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html"
-call-function: ("check-since-color", ("ayu"))
-call-function: ("check-since-color", ("dark"))
-call-function: ("check-since-color", ("light"))
+call-function: ("check-since-color", {"theme": "ayu"})
+call-function: ("check-since-color", {"theme": "dark"})
+call-function: ("check-since-color", {"theme": "light"})
diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml
index 84c20355500..9a7247a737b 100644
--- a/tests/rustdoc-gui/help-page.goml
+++ b/tests/rustdoc-gui/help-page.goml
@@ -7,17 +7,17 @@ assert-css: ("#help dd", {"font-size": "16px"})
 click: "#help-button > a"
 assert-css: ("#help", {"display": "block"})
 compare-elements-property: (".sub", "#help", ["offsetWidth"])
-compare-elements-position: (".sub", "#help", ("x"))
+compare-elements-position: (".sub", "#help", ["x"])
 set-window-size: (500, 1000) // Try mobile next.
 assert-css: ("#help", {"display": "block"})
 compare-elements-property: (".sub", "#help", ["offsetWidth"])
-compare-elements-position: (".sub", "#help", ("x"))
+compare-elements-position: (".sub", "#help", ["x"])
 
 // Checking the color of the elements of the help menu.
 show-text: true
 define-function: (
     "check-colors",
-    (theme, color, background, box_shadow),
+    [theme, color, background, box_shadow],
     block {
         // Setting the theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
@@ -60,7 +60,7 @@ assert-css: ("#help dd", {"font-size": "16px"})
 click: "#help-button > a"
 assert-css: ("#help", {"display": "none"})
 compare-elements-property-false: (".sub", "#help", ["offsetWidth"])
-compare-elements-position-false: (".sub", "#help", ("x"))
+compare-elements-position-false: (".sub", "#help", ["x"])
 
 // This test ensures that the "the rustdoc book" anchor link within the help popover works.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
diff --git a/tests/rustdoc-gui/highlight-colors.goml b/tests/rustdoc-gui/highlight-colors.goml
index d162674fa69..48bef319d42 100644
--- a/tests/rustdoc-gui/highlight-colors.goml
+++ b/tests/rustdoc-gui/highlight-colors.goml
@@ -4,7 +4,7 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (
+    [
         theme,
         kw,
         kw2,
@@ -20,7 +20,7 @@ define-function: (
         question_mark,
         comment,
         doc_comment,
-    ),
+    ],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
diff --git a/tests/rustdoc-gui/item-decl-colors.goml b/tests/rustdoc-gui/item-decl-colors.goml
index 7bbd20c4ee0..e68d206a511 100644
--- a/tests/rustdoc-gui/item-decl-colors.goml
+++ b/tests/rustdoc-gui/item-decl-colors.goml
@@ -6,7 +6,7 @@ fail-on-request-error: false
 
 define-function: (
     "check-colors",
-    (
+    [
         theme,
         attr_color,
         trait_color,
@@ -16,7 +16,7 @@ define-function: (
         constant_color,
         fn_color,
         assoc_type_color,
-    ),
+    ],
     block {
         go-to: "file://" + |DOC_PATH| + "/test_docs/struct.WithGenerics.html"
         show-text: true
diff --git a/tests/rustdoc-gui/item-decl-comment-highlighting.goml b/tests/rustdoc-gui/item-decl-comment-highlighting.goml
index 60772693d6c..056b6a5b1e8 100644
--- a/tests/rustdoc-gui/item-decl-comment-highlighting.goml
+++ b/tests/rustdoc-gui/item-decl-comment-highlighting.goml
@@ -4,7 +4,7 @@ show-text: true
 
 define-function: (
     "check-item-decl-comment",
-    (theme, url, comment_color),
+    [theme, url, comment_color],
     block {
         go-to: |url|
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
@@ -15,7 +15,7 @@ define-function: (
 
 define-function: (
     "check-items-for-theme",
-    (theme, comment_color),
+    [theme, comment_color],
     block {
         call-function: ("check-item-decl-comment", {
             "theme": |theme|,
diff --git a/tests/rustdoc-gui/item-info-alignment.goml b/tests/rustdoc-gui/item-info-alignment.goml
index 6fc365d1f19..cd0624056b9 100644
--- a/tests/rustdoc-gui/item-info-alignment.goml
+++ b/tests/rustdoc-gui/item-info-alignment.goml
@@ -4,7 +4,7 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.ItemInfoAlignmentTest.html"
 
 // First, we try it in "desktop" mode.
 set-window-size: (1200, 870)
-compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ("x"))
+compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ["x"])
 // Next, we try it in "mobile" mode (max-width: 700px).
 set-window-size: (650, 650)
-compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ("x"))
+compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ["x"])
diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml
index b46d4255ee5..1eb46e832b7 100644
--- a/tests/rustdoc-gui/item-info.goml
+++ b/tests/rustdoc-gui/item-info.goml
@@ -31,13 +31,13 @@ assert-count: ("#main-content > .item-info .stab", 2)
 compare-elements-position-false: (
     "#main-content > .item-info .stab:nth-of-type(1)",
     "#main-content > .item-info .stab:nth-of-type(2)",
-    ("y"),
+    ["y"],
 )
 // But they should have the same `x` position.
 compare-elements-position: (
     "#main-content > .item-info .stab:nth-of-type(1)",
     "#main-content > .item-info .stab:nth-of-type(2)",
-    ("x"),
+    ["x"],
 )
 // They are supposed to have the same height too.
 compare-elements-css: (
diff --git a/tests/rustdoc-gui/jump-to-def-background.goml b/tests/rustdoc-gui/jump-to-def-background.goml
index fa7ed3586dd..ae9c0c560cf 100644
--- a/tests/rustdoc-gui/jump-to-def-background.goml
+++ b/tests/rustdoc-gui/jump-to-def-background.goml
@@ -3,7 +3,7 @@ go-to: "file://" + |DOC_PATH| + "/src/link_to_definition/lib.rs.html"
 
 define-function: (
     "check-background-color",
-    (theme, background_color),
+    [theme, background_color],
     block {
         // Set the theme.
         set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }
@@ -17,6 +17,15 @@ define-function: (
     },
 )
 
-call-function: ("check-background-color", ("ayu", "#333"))
-call-function: ("check-background-color", ("dark", "#333"))
-call-function: ("check-background-color", ("light", "#eee"))
+call-function: ("check-background-color", {
+    "theme": "ayu",
+    "background_color": "#333",
+})
+call-function: ("check-background-color", {
+    "theme": "dark",
+    "background_color": "#333",
+})
+call-function: ("check-background-color", {
+    "theme": "light",
+    "background_color": "#eee",
+})
diff --git a/tests/rustdoc-gui/label-next-to-symbol.goml b/tests/rustdoc-gui/label-next-to-symbol.goml
index d23f9114d36..9a7de60bf38 100644
--- a/tests/rustdoc-gui/label-next-to-symbol.goml
+++ b/tests/rustdoc-gui/label-next-to-symbol.goml
@@ -27,14 +27,14 @@ compare-elements-position-near: (
 compare-elements-position: (
     ".item-name .stab.deprecated",
     ".item-name .stab.portability",
-    ("y"),
+    ["y"],
 )
 
 // Ensure no wrap
 compare-elements-position: (
     "//*[@class='item-name']//a[text()='replaced_function']/..",
     "//*[@class='desc docblock-short'][text()='a thing with a label']",
-    ("y"),
+    ["y"],
 )
 
 // Mobile view
@@ -49,19 +49,19 @@ compare-elements-position-near: (
 compare-elements-position: (
     ".item-name .stab.deprecated",
     ".item-name .stab.portability",
-    ("y"),
+    ["y"],
 )
 
 // Ensure wrap
 compare-elements-position-false: (
     "//*[@class='item-name']//a[text()='replaced_function']/..",
     "//*[@class='desc docblock-short'][text()='a thing with a label']",
-    ("y"),
+    ["y"],
 )
 compare-elements-position-false: (
     ".item-name .stab.deprecated",
     "//*[@class='desc docblock-short'][text()='a thing with a label']",
-    ("y"),
+    ["y"],
 )
 
 // Ensure it doesn't expand.
@@ -72,5 +72,5 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/cfgs/index.html"
 compare-elements-position-false: (
     "//*[@class='stab portability']/code[text()='appservice-api-c']",
     "//*[@class='stab portability']/code[text()='server']",
-    ("y"),
+    ["y"],
 )
diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml
index d88ebfb40d7..a1fb619a5d3 100644
--- a/tests/rustdoc-gui/links-color.goml
+++ b/tests/rustdoc-gui/links-color.goml
@@ -6,8 +6,8 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (theme, mod, macro, struct, enum, trait, fn, type, union, keyword,
-     sidebar, sidebar_current, sidebar_current_background),
+    [theme, mod, macro, struct, enum, trait, fn, type, union, keyword,
+     sidebar, sidebar_current, sidebar_current_background],
     block {
         set-local-storage: {
             "rustdoc-theme": |theme|,
diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml
index e10bb538f07..0b1c6622596 100644
--- a/tests/rustdoc-gui/notable-trait.goml
+++ b/tests/rustdoc-gui/notable-trait.goml
@@ -7,13 +7,13 @@ set-window-size: (1100, 600)
 compare-elements-position: (
     "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
-    ("y"),
+    ["y"],
 )
 // Checking they don't have the same x position.
 compare-elements-position-false: (
     "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
-    ("x"),
+    ["x"],
 )
 // The `i` should be *after* the type.
 assert-position: (
@@ -37,7 +37,7 @@ compare-elements-position-near: (
 compare-elements-position-false: (
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
     "//*[@class='tooltip popover']",
-    ("x")
+    ["x"]
 )
 click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
 move-cursor-to: "//h1"
@@ -48,7 +48,7 @@ set-window-size: (1055, 600)
 compare-elements-position-false: (
     "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
-    ("y", "x"),
+    ["y", "x"],
 )
 
 // Now both the `i` and the struct name should be on the next line.
@@ -57,13 +57,13 @@ set-window-size: (980, 600)
 compare-elements-position: (
     "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
-    ("y"),
+    ["y"],
 )
 // Checking they don't have the same x position.
 compare-elements-position-false: (
     "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
-    ("x"),
+    ["x"],
 )
 // The `i` should be *after* the type.
 assert-position: (
@@ -81,13 +81,13 @@ set-window-size: (650, 600)
 compare-elements-position: (
     "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
-    ("y"),
+    ["y"],
 )
 // Checking they don't have the same x position.
 compare-elements-position-false: (
     "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
-    ("x"),
+    ["x"],
 )
 // The `i` should be *after* the type.
 assert-position: (
@@ -109,7 +109,7 @@ compare-elements-position-near: (
 compare-elements-position-false: (
     "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
     "//*[@class='tooltip popover']",
-    ("x")
+    ["x"]
 )
 assert-position: (
     "//*[@class='tooltip popover']",
@@ -122,7 +122,7 @@ assert-count: ("//*[@class='tooltip popover']", 0)
 // Now check the colors.
 define-function: (
     "check-colors",
-    (theme, header_color, content_color, type_color, trait_color, link_color),
+    [theme, header_color, content_color, type_color, trait_color, link_color],
     block {
         go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"
         // This is needed to ensure that the text color is computed.
diff --git a/tests/rustdoc-gui/pocket-menu.goml b/tests/rustdoc-gui/pocket-menu.goml
index 404e5740305..b16150cd0d3 100644
--- a/tests/rustdoc-gui/pocket-menu.goml
+++ b/tests/rustdoc-gui/pocket-menu.goml
@@ -31,7 +31,7 @@ assert-css: ("#settings-menu .popover", {"display": "none"})
 
 define-function: (
     "check-popover-colors",
-    (theme, border_color),
+    [theme, border_color],
     block {
         set-local-storage: {
             "rustdoc-theme": |theme|,
diff --git a/tests/rustdoc-gui/run-on-hover.goml b/tests/rustdoc-gui/run-on-hover.goml
index 1f87febcec6..19b15afbac3 100644
--- a/tests/rustdoc-gui/run-on-hover.goml
+++ b/tests/rustdoc-gui/run-on-hover.goml
@@ -7,7 +7,7 @@ show-text: true
 
 define-function: (
     "check-run-button",
-    (theme, color, background, hover_color, hover_background),
+    [theme, color, background, hover_color, hover_background],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
diff --git a/tests/rustdoc-gui/rust-logo.goml b/tests/rustdoc-gui/rust-logo.goml
index dcf3d6bab63..a3b420e5eb9 100644
--- a/tests/rustdoc-gui/rust-logo.goml
+++ b/tests/rustdoc-gui/rust-logo.goml
@@ -3,7 +3,7 @@ go-to: "file://" + |DOC_PATH| + "/staged_api/index.html"
 
 define-function: (
     "check-logo",
-    (theme, filter),
+    [theme, filter],
     block {
         // Going to the doc page.
         go-to: "file://" + |DOC_PATH| + "/staged_api/index.html"
diff --git a/tests/rustdoc-gui/scrape-examples-color.goml b/tests/rustdoc-gui/scrape-examples-color.goml
index 0052d18dc56..b1675a5f1fd 100644
--- a/tests/rustdoc-gui/scrape-examples-color.goml
+++ b/tests/rustdoc-gui/scrape-examples-color.goml
@@ -4,8 +4,8 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (theme, highlight, highlight_focus, help_border, help_color, help_hover_border,
-     help_hover_color),
+    [theme, highlight, highlight_focus, help_border, help_color, help_hover_border,
+     help_hover_color],
     block {
         set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", }
         reload:
@@ -64,7 +64,7 @@ go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html"
 
 define-function: (
     "check-background",
-    (theme, background_color_start, background_color_end),
+    [theme, background_color_start, background_color_end],
     block {
         set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", }
         reload:
diff --git a/tests/rustdoc-gui/scrape-examples-toggle.goml b/tests/rustdoc-gui/scrape-examples-toggle.goml
index f742b3186e5..ea645d28924 100644
--- a/tests/rustdoc-gui/scrape-examples-toggle.goml
+++ b/tests/rustdoc-gui/scrape-examples-toggle.goml
@@ -5,7 +5,7 @@ go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
 show-text: true
 define-function: (
     "check-color",
-    (theme, toggle_line_color, toggle_line_hover_color),
+    [theme, toggle_line_color, toggle_line_hover_color],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
diff --git a/tests/rustdoc-gui/search-corrections.goml b/tests/rustdoc-gui/search-corrections.goml
index aeb3c9b31a3..b81b1f382a9 100644
--- a/tests/rustdoc-gui/search-corrections.goml
+++ b/tests/rustdoc-gui/search-corrections.goml
@@ -4,7 +4,7 @@
 // First, try a search-by-name
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // Intentionally wrong spelling of "NotableStructWithLongName"
-write: (".search-input", "NotableStructWithLongNamr")
+write-into: (".search-input", "NotableStructWithLongNamr")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -41,7 +41,7 @@ assert-text: (
 // Now, explicit return values
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // Intentionally wrong spelling of "NotableStructWithLongName"
-write: (".search-input", "-> NotableStructWithLongNamr")
+write-into: (".search-input", "-> NotableStructWithLongNamr")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -58,7 +58,7 @@ assert-text: (
 // Now, generic correction
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // Intentionally wrong spelling of "NotableStructWithLongName"
-write: (".search-input", "NotableStructWithLongNamr, NotableStructWithLongNamr")
+write-into: (".search-input", "NotableStructWithLongNamr, NotableStructWithLongNamr")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -75,7 +75,7 @@ assert-text: (
 // Now, generic correction plus error
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // Intentionally wrong spelling of "NotableStructWithLongName"
-write: (".search-input", "Foo<NotableStructWithLongNamr>,y")
+write-into: (".search-input", "Foo<NotableStructWithLongNamr>,y")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -91,7 +91,7 @@ assert-text: (
 
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // Intentionally wrong spelling of "NotableStructWithLongName"
-write: (".search-input", "generic:NotableStructWithLongNamr<x>,y")
+write-into: (".search-input", "generic:NotableStructWithLongNamr<x>,y")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/search-error.goml b/tests/rustdoc-gui/search-error.goml
index 70aeda1769a..d3de77b5635 100644
--- a/tests/rustdoc-gui/search-error.goml
+++ b/tests/rustdoc-gui/search-error.goml
@@ -4,7 +4,7 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (theme, error_background),
+    [theme, error_background],
     block {
         // Setting the theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
diff --git a/tests/rustdoc-gui/search-filter.goml b/tests/rustdoc-gui/search-filter.goml
index 9e2855b5e02..8c50322fcd4 100644
--- a/tests/rustdoc-gui/search-filter.goml
+++ b/tests/rustdoc-gui/search-filter.goml
@@ -1,7 +1,7 @@
 // Checks that the crate search filtering is handled correctly and changes the results.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 show-text: true
-write: (".search-input", "test")
+write-into: (".search-input", "test")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/search-form-elements.goml b/tests/rustdoc-gui/search-form-elements.goml
index 0ea61a4f0eb..2fc66259291 100644
--- a/tests/rustdoc-gui/search-form-elements.goml
+++ b/tests/rustdoc-gui/search-form-elements.goml
@@ -4,10 +4,10 @@ show-text: true
 
 define-function: (
     "check-search-colors",
-    (
+    [
         theme, border, background, search_input_color, search_input_border_focus,
         menu_button_border, menu_button_a_color, menu_button_a_border_hover, menu_a_color,
-    ),
+    ],
     block {
         set-local-storage: {
             "rustdoc-theme": |theme|,
diff --git a/tests/rustdoc-gui/search-keyboard.goml b/tests/rustdoc-gui/search-keyboard.goml
index f1d8024616b..707bb8f5faa 100644
--- a/tests/rustdoc-gui/search-keyboard.goml
+++ b/tests/rustdoc-gui/search-keyboard.goml
@@ -1,7 +1,7 @@
 // Checks that the search tab results work correctly with function signature syntax
 // First, try a search-by-name
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "Foo")
+write-into: (".search-input", "Foo")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/search-no-result.goml b/tests/rustdoc-gui/search-no-result.goml
index e7c64791256..dda50ec3fb6 100644
--- a/tests/rustdoc-gui/search-no-result.goml
+++ b/tests/rustdoc-gui/search-no-result.goml
@@ -4,7 +4,7 @@ show-text: true
 
 define-function: (
     "check-no-result",
-    (theme, link, link_hover),
+    [theme, link, link_hover],
     block {
         // Changing theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
diff --git a/tests/rustdoc-gui/search-reexport.goml b/tests/rustdoc-gui/search-reexport.goml
index b9d2c8f15ce..2e7c967d5c3 100644
--- a/tests/rustdoc-gui/search-reexport.goml
+++ b/tests/rustdoc-gui/search-reexport.goml
@@ -6,7 +6,7 @@ reload:
 // First we check that the reexport has the correct ID and no background color.
 assert-text: ("//*[@id='reexport.TheStdReexport']", "pub use ::std as TheStdReexport;")
 assert-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgba(0, 0, 0, 0)"})
-write: (".search-input", "TheStdReexport")
+write-into: (".search-input", "TheStdReexport")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 wait-for: "//a[@class='result-import']"
@@ -22,7 +22,7 @@ wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a
 // We now check that the alias is working as well on the reexport.
 // To be SURE that the search will be run.
 press-key: 'Enter'
-write: (".search-input", "AliasForTheStdReexport")
+write-into: (".search-input", "AliasForTheStdReexport")
 wait-for: "//a[@class='result-import']"
 assert-text: (
     "a.result-import .result-name",
diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml
index 44677dfbfef..1a19ea2d843 100644
--- a/tests/rustdoc-gui/search-result-color.goml
+++ b/tests/rustdoc-gui/search-result-color.goml
@@ -2,7 +2,7 @@
 
 define-function: (
     "check-result-color",
-    (result_kind, color, hover_color),
+    [result_kind, color, hover_color],
     block {
         assert-css: (".result-" + |result_kind| + " ." + |result_kind|, {"color": |color|}, ALL)
         assert-css: (
@@ -78,60 +78,60 @@ store-value: (hover_background_color, "#3c3c3c") // hover background color
 store-value: (grey, "#999")
 
 call-function: (
-    "check-result-color", (
-        "keyword", // item kind
-        "#39afd7", // color of item kind
-        "#39afd7", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "keyword",
+        "color": "#39afd7",
+        "hover_color": "#39afd7",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "struct", // item kind
-        "#ffa0a5", // color of item kind
-        "#ffa0a5", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "struct",
+        "color": "#ffa0a5",
+        "hover_color": "#ffa0a5",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "associatedtype", // item kind
-        "#39afd7", // color of item kind
-        "#39afd7", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "associatedtype",
+        "color": "#39afd7",
+        "hover_color": "#39afd7",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "tymethod", // item kind
-        "#fdd687", // color of item kind
-        "#fdd687", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "tymethod",
+        "color": "#fdd687",
+        "hover_color": "#fdd687",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "method", // item kind
-        "#fdd687", // color of item kind
-        "#fdd687", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "method",
+        "color": "#fdd687",
+        "hover_color": "#fdd687",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "structfield", // item kind
-        "#0096cf", // color of item kind
-        "#fff", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "structfield",
+        "color": "#0096cf",
+        "hover_color": "#fff",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "macro", // item kind
-        "#a37acc", // color of item kind
-        "#a37acc", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "macro",
+        "color": "#a37acc",
+        "hover_color": "#a37acc",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "fn", // item kind
-        "#fdd687", // color of item kind
-        "#fdd687", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "fn",
+        "color": "#fdd687",
+        "hover_color": "#fdd687",
+    },
 )
 
 // Checking the `<a>` container.
@@ -190,60 +190,60 @@ store-value: (hover_background_color, "#616161") // hover background color
 store-value: (grey, "#ccc")
 
 call-function: (
-    "check-result-color", (
-        "keyword", // item kind
-        "#d2991d", // color of item kind
-        "#d2991d", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "keyword",
+        "color": "#d2991d",
+        "hover_color": "#d2991d",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "struct", // item kind
-        "#2dbfb8", // color of item kind
-        "#2dbfb8", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "struct",
+        "color": "#2dbfb8",
+        "hover_color": "#2dbfb8",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "associatedtype", // item kind
-        "#d2991d", // color of item kind
-        "#d2991d", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "associatedtype",
+        "color": "#d2991d",
+        "hover_color": "#d2991d",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "tymethod", // item kind
-        "#2bab63", // color of item kind
-        "#2bab63", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "tymethod",
+        "color": "#2bab63",
+        "hover_color": "#2bab63",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "method", // item kind
-        "#2bab63", // color of item kind
-        "#2bab63", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "method",
+        "color": "#2bab63",
+        "hover_color": "#2bab63",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "structfield", // item kind
-        "#ddd", // color of item kind
-        "#ddd", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "structfield",
+        "color": "#ddd",
+        "hover_color": "#ddd",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "macro", // item kind
-        "#09bd00", // color of item kind
-        "#09bd00", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "macro",
+        "color": "#09bd00",
+        "hover_color": "#09bd00",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "fn", // item kind
-        "#2bab63", // color of item kind
-        "#2bab63", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "fn",
+        "color": "#2bab63",
+        "hover_color": "#2bab63",
+    },
 )
 
 // Checking the `<a>` container.
@@ -287,60 +287,60 @@ store-value: (hover_background_color, "#ccc") // hover background color
 store-value: (grey, "#999")
 
 call-function: (
-    "check-result-color", (
-        "keyword", // item kind
-        "#3873ad", // color of item kind
-        "#3873ad", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "keyword",
+        "color": "#3873ad",
+        "hover_color": "#3873ad",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "struct", // item kind
-        "#ad378a", // color of item kind
-        "#ad378a", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "struct",
+        "color": "#ad378a",
+        "hover_color": "#ad378a",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "associatedtype", // item kind
-        "#3873ad", // color of item kind
-        "#3873ad", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "associatedtype",
+        "color": "#3873ad",
+        "hover_color": "#3873ad",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "tymethod", // item kind
-        "#ad7c37", // color of item kind
-        "#ad7c37", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "tymethod",
+        "color": "#ad7c37",
+        "hover_color": "#ad7c37",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "method", // item kind
-        "#ad7c37", // color of item kind
-        "#ad7c37", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "method",
+        "color": "#ad7c37",
+        "hover_color": "#ad7c37",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "structfield", // item kind
-        "#000", // color of item kind
-        "#000", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "structfield",
+        "color": "#000",
+        "hover_color": "#000",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "macro", // item kind
-        "#068000", // color of item kind
-        "#068000", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "macro",
+        "color": "#068000",
+        "hover_color": "#068000",
+    },
 )
 call-function: (
-    "check-result-color", (
-        "fn", // item kind
-        "#ad7c37", // color of item kind
-        "#ad7c37", // color of hovered/focused item kind
-    ),
+    "check-result-color", {
+        "result_kind": "fn",
+        "color": "#ad7c37",
+        "hover_color": "#ad7c37",
+    },
 )
 
 // Checking the `<a>` container.
@@ -358,11 +358,11 @@ show-text: true
 
 define-function: (
     "check-alias",
-    (theme, alias, grey),
+    [theme, alias, grey],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
-        write: (".search-input", "thisisanalias")
+        write-into: (".search-input", "thisisanalias")
         // To be SURE that the search will be run.
         press-key: 'Enter'
         // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml
index 6ce13b8c3d3..b1a5548808e 100644
--- a/tests/rustdoc-gui/search-result-display.goml
+++ b/tests/rustdoc-gui/search-result-display.goml
@@ -2,7 +2,7 @@
 // Checks that the search results have the expected width.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 set-window-size: (900, 1000)
-write: (".search-input", "test")
+write-into: (".search-input", "test")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 wait-for: "#crate-search"
@@ -69,7 +69,7 @@ assert-css: ("#search", {"width": "640px"})
 show-text: true
 define-function: (
     "check-filter",
-    (theme, border, filter, hover_border, hover_filter),
+    [theme, border, filter, hover_border, hover_filter],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
diff --git a/tests/rustdoc-gui/search-result-impl-disambiguation.goml b/tests/rustdoc-gui/search-result-impl-disambiguation.goml
index 6d12032e891..3e49ac33025 100644
--- a/tests/rustdoc-gui/search-result-impl-disambiguation.goml
+++ b/tests/rustdoc-gui/search-result-impl-disambiguation.goml
@@ -5,7 +5,7 @@
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 
 // This should link to the inherent impl
-write: (".search-input", "ZyxwvutMethodDisambiguation -> bool")
+write-into: (".search-input", "ZyxwvutMethodDisambiguation -> bool")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -25,7 +25,7 @@ assert: "section:target"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 
 // This should link to the trait impl
-write: (".search-input", "ZyxwvutMethodDisambiguation, usize -> usize")
+write-into: (".search-input", "ZyxwvutMethodDisambiguation, usize -> usize")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/search-result-keyword.goml b/tests/rustdoc-gui/search-result-keyword.goml
index 1b2be6d4e3e..370edce2ddd 100644
--- a/tests/rustdoc-gui/search-result-keyword.goml
+++ b/tests/rustdoc-gui/search-result-keyword.goml
@@ -1,6 +1,6 @@
 // Checks that the "keyword" results have the expected text alongside them.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "CookieMonster")
+write-into: (".search-input", "CookieMonster")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml b/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml
index 156d8d03ca2..7e26229ec6e 100644
--- a/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml
+++ b/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml
@@ -1,7 +1,7 @@
 // Checks that the search tab results work correctly with function signature syntax
 // First, try a search-by-name
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "Foo")
+write-into: (".search-input", "Foo")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -23,7 +23,7 @@ wait-for-attribute: ("#search-tabs > button:nth-of-type(3)", {"class": "selected
 
 // Now try search-by-return
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "-> String")
+write-into: (".search-input", "-> String")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -45,7 +45,7 @@ wait-for-attribute: ("#search-tabs > button:nth-of-type(1)", {"class": "selected
 
 // Try with a search-by-return with no results
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "-> Something")
+write-into: (".search-input", "-> Something")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -55,7 +55,7 @@ assert-text: ("#search-tabs > button:nth-of-type(1)", "In Function Return Types"
 
 // Try with a search-by-parameter
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "usize,pattern")
+write-into: (".search-input", "usize,pattern")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
@@ -65,7 +65,7 @@ assert-text: ("#search-tabs > button:nth-of-type(1)", "In Function Parameters",
 
 // Try with a search-by-parameter-and-return
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "pattern -> str")
+write-into: (".search-input", "pattern -> str")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-gui/search-tab.goml b/tests/rustdoc-gui/search-tab.goml
index b52bb0688c1..c33866593c3 100644
--- a/tests/rustdoc-gui/search-tab.goml
+++ b/tests/rustdoc-gui/search-tab.goml
@@ -4,9 +4,9 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (theme, background, background_selected, background_hover, border_bottom,
+    [theme, background, background_selected, background_hover, border_bottom,
      border_bottom_selected, border_bottom_hover, border_top, border_top_selected,
-     border_top_hover),
+     border_top_hover],
     block {
         // Setting the theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
@@ -93,12 +93,12 @@ assert-property: ("#search-tabs > button:nth-child(3) > .count", {"offsetWidth":
 compare-elements-position: (
     "#search-tabs > button:nth-child(1) > .count",
     "#search-tabs > button:nth-child(2) > .count",
-    ("y")
+    ["y"]
 )
 compare-elements-position: (
     "#search-tabs > button:nth-child(2) > .count",
     "#search-tabs > button:nth-child(3) > .count",
-    ("y")
+    ["y"]
 )
 // Check that counts are beside the titles and haven't wrapped
 compare-elements-position-near: (
@@ -135,12 +135,12 @@ assert-property: ("#search-tabs > button:nth-child(3) > .count", {"offsetWidth":
 compare-elements-position: (
     "#search-tabs > button:nth-child(1) > .count",
     "#search-tabs > button:nth-child(2) > .count",
-    ("y")
+    ["y"]
 )
 compare-elements-position: (
     "#search-tabs > button:nth-child(2) > .count",
     "#search-tabs > button:nth-child(3) > .count",
-    ("y")
+    ["y"]
 )
 // Check that counts are NOT beside the titles; now they have wrapped
 compare-elements-position-near-false: (
diff --git a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml
index b55a1cfd92b..9afde7c61da 100644
--- a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml
+++ b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml
@@ -6,7 +6,7 @@ fail-on-request-error: false
 
 define-function: (
     "check-setting",
-    (storage_value, setting_attribute_value, toggle_attribute_value),
+    [storage_value, setting_attribute_value, toggle_attribute_value],
     block {
         assert-local-storage: {"rustdoc-auto-hide-large-items": |storage_value|}
         click: "#settings-menu"
diff --git a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml
index 5210ad8f793..644396ed578 100644
--- a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml
+++ b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml
@@ -3,7 +3,7 @@
 
 define-function: (
     "check-setting",
-    (storage_value, setting_attribute_value, toggle_attribute_value),
+    [storage_value, setting_attribute_value, toggle_attribute_value],
     block {
         assert-local-storage: {"rustdoc-auto-hide-method-docs": |storage_value|}
         click: "#settings-menu"
diff --git a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml
index ecadd8fa80e..3c09198dae5 100644
--- a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml
+++ b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml
@@ -2,7 +2,7 @@
 
 define-function: (
     "check-setting",
-    (storage_value, setting_attribute_value, toggle_attribute_value),
+    [storage_value, setting_attribute_value, toggle_attribute_value],
     block {
         assert-local-storage: {"rustdoc-auto-hide-trait-implementations": |storage_value|}
         click: "#settings-menu"
diff --git a/tests/rustdoc-gui/setting-go-to-only-result.goml b/tests/rustdoc-gui/setting-go-to-only-result.goml
index 45e0b349051..f8535477c22 100644
--- a/tests/rustdoc-gui/setting-go-to-only-result.goml
+++ b/tests/rustdoc-gui/setting-go-to-only-result.goml
@@ -2,7 +2,7 @@
 
 define-function: (
     "check-setting",
-    (storage_value, setting_attribute_value),
+    [storage_value, setting_attribute_value],
     block {
         assert-local-storage: {"rustdoc-go-to-only-result": |storage_value|}
         click: "#settings-menu"
@@ -32,7 +32,7 @@ assert-local-storage: {"rustdoc-go-to-only-result": "true"}
 
 go-to: "file://" + |DOC_PATH| + "/lib2/index.html"
 // We enter it into the search.
-write: (".search-input", "HasALongTraitWithParams")
+write-into: (".search-input", "HasALongTraitWithParams")
 wait-for-document-property: {"title": "HasALongTraitWithParams in lib2 - Rust"}
 assert-window-property: ({"location": "/lib2/struct.HasALongTraitWithParams.html"}, ENDS_WITH)
 
diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml
index e40c637dcf7..0bb21c28cb5 100644
--- a/tests/rustdoc-gui/settings.goml
+++ b/tests/rustdoc-gui/settings.goml
@@ -304,7 +304,7 @@ wait-for: "#settings"
 assert-css: (".setting-radio", {"cursor": "pointer"})
 
 assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS)
-compare-elements-position: (".sub form", "#settings", ("x"))
+compare-elements-position: (".sub form", "#settings", ["x"])
 
 // Check that setting-line has the same margin in this mode as in the popover.
 assert-css: (".setting-line", {"margin": |setting_line_margin|})
diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml
index 774fbcac1e2..0edffc51a81 100644
--- a/tests/rustdoc-gui/sidebar-links-color.goml
+++ b/tests/rustdoc-gui/sidebar-links-color.goml
@@ -6,12 +6,12 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (
+    [
         theme, struct, struct_hover, struct_hover_background, enum, enum_hover,
         enum_hover_background, union, union_hover, union_hover_background, trait, trait_hover,
         trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover,
         type_hover_background, keyword, keyword_hover, keyword_hover_background,
-    ),
+    ],
     block {
         set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }
         reload:
diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml
index d3a82d9ebe6..8843de8d7e9 100644
--- a/tests/rustdoc-gui/sidebar-mobile.goml
+++ b/tests/rustdoc-gui/sidebar-mobile.goml
@@ -57,7 +57,7 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (theme, color, background),
+    [theme, color, background],
     block {
         set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
         reload:
diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml
index 5149d4991f7..41c8e45f4a6 100644
--- a/tests/rustdoc-gui/sidebar-source-code-display.goml
+++ b/tests/rustdoc-gui/sidebar-source-code-display.goml
@@ -30,9 +30,9 @@ show-text: true
 
 define-function: (
     "check-colors",
-    (
+    [
         theme, color, color_hover, background, background_hover, background_toggle,
-    ),
+    ],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml
index d7de43a2243..3f7ef643d18 100644
--- a/tests/rustdoc-gui/sidebar-source-code.goml
+++ b/tests/rustdoc-gui/sidebar-source-code.goml
@@ -6,7 +6,7 @@ show-text: true
 // First, check the sidebar colors.
 define-function: (
     "check-colors",
-    (theme, color, background_color),
+    [theme, color, background_color],
     block {
         set-local-storage: {
             "rustdoc-theme": |theme|,
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index 82b4f2e9429..115b1eb323c 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -6,7 +6,7 @@ show-text: true
 // First, check the sidebar colors.
 define-function: (
     "check-colors",
-    (theme, color, background_color),
+    [theme, color, background_color],
     block {
         set-local-storage: {
             "rustdoc-theme": |theme|,
diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml
index 8b4d7617e0c..e29d123d227 100644
--- a/tests/rustdoc-gui/source-code-page.goml
+++ b/tests/rustdoc-gui/source-code-page.goml
@@ -21,7 +21,7 @@ assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-h
 
 define-function: (
     "check-colors",
-    (theme, color, background_color, highlight_color, highlight_background_color),
+    [theme, color, background_color, highlight_color, highlight_background_color],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
@@ -61,7 +61,7 @@ call-function: ("check-colors", {
 })
 
 // This is to ensure that the content is correctly align with the line numbers.
-compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))
+compare-elements-position: ("//*[@id='1']", ".rust > code > span", ["y"])
 // Check the `href` property so that users can treat anchors as links.
 assert-property: (".src-line-numbers > a:nth-child(1)", {
     "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#1"
@@ -122,7 +122,7 @@ store-property: (
 )
 define-function: (
     "check-sidebar-dir-entry",
-    (x, y),
+    [x, y],
     block {
         assert: "details:first-of-type.dir-entry[open] > summary::marker"
         assert-css: ("#src-sidebar > details:first-of-type.dir-entry", {"padding-left": "4px"})
diff --git a/tests/rustdoc-gui/stab-badge.goml b/tests/rustdoc-gui/stab-badge.goml
index bb3d2aaa3dc..46df0946c45 100644
--- a/tests/rustdoc-gui/stab-badge.goml
+++ b/tests/rustdoc-gui/stab-badge.goml
@@ -3,7 +3,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 show-text: true
 define-function: (
     "check-badge",
-    (theme, background, color),
+    [theme, background, color],
     block {
         set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
         go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
diff --git a/tests/rustdoc-gui/target.goml b/tests/rustdoc-gui/target.goml
index 26071df8d04..0f8f7709363 100644
--- a/tests/rustdoc-gui/target.goml
+++ b/tests/rustdoc-gui/target.goml
@@ -7,7 +7,7 @@ assert: "#method\.a_method:target"
 
 define-function: (
     "check-style",
-    (theme, background, border),
+    [theme, background, border],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
diff --git a/tests/rustdoc-gui/toggle-docs.goml b/tests/rustdoc-gui/toggle-docs.goml
index 9ea6d9b18f4..cfd18bd2e14 100644
--- a/tests/rustdoc-gui/toggle-docs.goml
+++ b/tests/rustdoc-gui/toggle-docs.goml
@@ -49,7 +49,7 @@ assert-attribute: ("details.toggle", {"open": ""}, ALL)
 show-text: true
 define-function: (
     "check-color",
-    (theme, filter),
+    [theme, filter],
     block {
         // Setting the theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
diff --git a/tests/rustdoc-gui/type-declation-overflow.goml b/tests/rustdoc-gui/type-declation-overflow.goml
index a97cc98897a..3709aa10266 100644
--- a/tests/rustdoc-gui/type-declation-overflow.goml
+++ b/tests/rustdoc-gui/type-declation-overflow.goml
@@ -47,18 +47,18 @@ assert-css: (".mobile-topbar h2", {"overflow-x": "hidden"})
 // On desktop, they wrap when too big.
 set-window-size: (1100, 800)
 go-to: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html"
-compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y"))
+compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ["y"])
 go-to: "file://" + |DOC_PATH| + "/lib2/index.html"
-compare-elements-position: (".main-heading h1", ".main-heading .out-of-band", ("y"))
+compare-elements-position: (".main-heading h1", ".main-heading .out-of-band", ["y"])
 // make sure there is a gap between them
 compare-elements-position-near-false: (".main-heading h1", ".main-heading .out-of-band", {"x": 550})
 
 // On mobile, they always wrap.
 set-window-size: (600, 600)
 go-to: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html"
-compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y"))
+compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ["y"])
 go-to: "file://" + |DOC_PATH| + "/lib2/index.html"
-compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y"))
+compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ["y"])
 
 // Now we will check that the scrolling is working.
 // First on an item with "hidden methods".
diff --git a/tests/rustdoc-gui/unsafe-fn.goml b/tests/rustdoc-gui/unsafe-fn.goml
index 8d26f15f37f..83503121a04 100644
--- a/tests/rustdoc-gui/unsafe-fn.goml
+++ b/tests/rustdoc-gui/unsafe-fn.goml
@@ -13,7 +13,7 @@ define-function: (
     "sup-check",
     // `theme` is the theme being tested.
     // `color` is the expected color of the `<sup>` element.
-    (theme, color),
+    [theme, color],
     block {
         // Set the theme.
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
@@ -23,6 +23,15 @@ define-function: (
     },
 )
 
-call-function: ("sup-check", ("ayu", "#c5c5c5"))
-call-function: ("sup-check", ("dark", "#ddd"))
-call-function: ("sup-check", ("light", "black"))
+call-function: ("sup-check", {
+    "theme": "ayu",
+    "color": "#c5c5c5",
+})
+call-function: ("sup-check", {
+    "theme": "dark",
+    "color": "#ddd",
+})
+call-function: ("sup-check", {
+    "theme": "light",
+    "color": "black",
+})
diff --git a/tests/rustdoc-gui/warning-block.goml b/tests/rustdoc-gui/warning-block.goml
index 10e206049f5..a5a47f868db 100644
--- a/tests/rustdoc-gui/warning-block.goml
+++ b/tests/rustdoc-gui/warning-block.goml
@@ -5,7 +5,7 @@ show-text: true
 store-value: (default_y_pos, 5)
 define-function: (
     "check-warning",
-    (theme, color, border_color),
+    [theme, color, border_color],
     block {
         set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
         reload:
diff --git a/tests/rustdoc-gui/where-whitespace.goml b/tests/rustdoc-gui/where-whitespace.goml
index da104fa4011..823ce970407 100644
--- a/tests/rustdoc-gui/where-whitespace.goml
+++ b/tests/rustdoc-gui/where-whitespace.goml
@@ -3,25 +3,25 @@ go-to: "file://" + |DOC_PATH| + "/lib2/trait.Whitespace.html"
 show-text: true
 // First, we check in the trait definition if the where clause is "on its own" (not on the same
 // line than "pub trait Whitespace<Idx>").
-compare-elements-position-false: (".item-decl code", "div.where", ("y"))
+compare-elements-position-false: (".item-decl code", "div.where", ["y"])
 // And that the code following it isn't on the same line either.
-compare-elements-position-false: (".item-decl .fn", "div.where", ("y"))
+compare-elements-position-false: (".item-decl .fn", "div.where", ["y"])
 
 go-to: "file://" + |DOC_PATH| + "/lib2/struct.WhereWhitespace.html"
 // We make the screen a bit wider to ensure that the trait impl is on one line.
 set-window-size: (915, 915)
 
-compare-elements-position-false: ("#method\.new .fn", "#method\.new div.where", ("y"))
+compare-elements-position-false: ("#method\.new .fn", "#method\.new div.where", ["y"])
 // We ensure that both the trait name and the struct name are on the same line in
 // "impl<K, T> Whitespace<&K> for WhereWhitespace<T>".
 compare-elements-position: (
     "#trait-implementations-list .impl h3 .trait",
     "#trait-implementations-list .impl h3 .struct",
-    ("y"),
+    ["y"],
 )
 // And we now check that the where condition isn't on the same line.
 compare-elements-position-false: (
     "#trait-implementations-list .impl h3 .trait",
     "#trait-implementations-list .impl h3 div.where",
-    ("y"),
+    ["y"],
 )
diff --git a/tests/rustdoc/search-index-summaries.rs b/tests/rustdoc/search-index-summaries.rs
index efd366405bf..529b42d0ca9 100644
--- a/tests/rustdoc/search-index-summaries.rs
+++ b/tests/rustdoc/search-index-summaries.rs
@@ -1,6 +1,6 @@
 #![crate_name = "foo"]
 
-// @hasraw 'search-index.js' 'Foo short link.'
+// @hasraw 'search.desc/foo/foo-desc-0-.js' 'Foo short link.'
 // @!hasraw - 'www.example.com'
 // @!hasraw - 'More Foo.'
 
diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr
deleted file mode 100644
index 34ec8aadbcf..00000000000
--- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/const-extern-fn-requires-unsafe.rs:12:5
-   |
-LL |     foo();
-   |     ^^^^^ call to unsafe function
-   |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
-
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/const-extern-fn-requires-unsafe.rs:9:17
-   |
-LL |     let a: [u8; foo()];
-   |                 ^^^^^ call to unsafe function
-   |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr
deleted file mode 100644
index e6b8173eb05..00000000000
--- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
-  --> $DIR/const-extern-fn-requires-unsafe.rs:12:5
-   |
-LL |     foo();
-   |     ^^^^^ call to unsafe function
-   |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
-
-error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
-  --> $DIR/const-extern-fn-requires-unsafe.rs:9:17
-   |
-LL |     let a: [u8; foo()];
-   |                 ^^^^^ call to unsafe function
-   |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr
deleted file mode 100644
index 7bbd4e15898..00000000000
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/fn-ptr.rs:11:21
-   |
-LL | #[target_feature(enable = "sse2")]
-   | ---------------------------------- `#[target_feature]` added here
-...
-LL |     let foo: fn() = foo;
-   |              ----   ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
-   |              |
-   |              expected due to this
-   |
-   = note: expected fn pointer `fn()`
-                 found fn item `fn() {foo}`
-   = note: fn items are distinct from fn pointers
-   = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
-help: consider casting to a fn pointer
-   |
-LL |     let foo: fn() = foo as fn();
-   |                     ~~~~~~~~~~~
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr
deleted file mode 100644
index 7bbd4e15898..00000000000
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/fn-ptr.rs:11:21
-   |
-LL | #[target_feature(enable = "sse2")]
-   | ---------------------------------- `#[target_feature]` added here
-...
-LL |     let foo: fn() = foo;
-   |              ----   ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
-   |              |
-   |              expected due to this
-   |
-   = note: expected fn pointer `fn()`
-                 found fn item `fn() {foo}`
-   = note: fn items are distinct from fn pointers
-   = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
-help: consider casting to a fn pointer
-   |
-LL |     let foo: fn() = foo as fn();
-   |                     ~~~~~~~~~~~
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr
deleted file mode 100644
index cabc475fa61..00000000000
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr
+++ /dev/null
@@ -1,115 +0,0 @@
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:28:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:31:5
-   |
-LL |     avx_bmi2();
-   |     ^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:34:5
-   |
-LL |     Quux.avx_bmi2();
-   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:41:5
-   |
-LL |     avx_bmi2();
-   |     ^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:44:5
-   |
-LL |     Quux.avx_bmi2();
-   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:51:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:54:5
-   |
-LL |     avx_bmi2();
-   |     ^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:57:5
-   |
-LL |     Quux.avx_bmi2();
-   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:65:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:70:15
-   |
-LL | const _: () = sse2();
-   |               ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:74:15
-   |
-LL | const _: () = sse2_and_fxsr();
-   |               ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: sse2 and fxsr
-   = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
-
-error: call to function with `#[target_feature]` is unsafe and requires unsafe block (error E0133)
-  --> $DIR/safe-calls.rs:82:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-note: an unsafe function restricts its caller, but its body is safe by default
-  --> $DIR/safe-calls.rs:81:1
-   |
-LL | unsafe fn needs_unsafe_block() {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: the lint level is defined here
-  --> $DIR/safe-calls.rs:78:8
-   |
-LL | #[deny(unsafe_op_in_unsafe_fn)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 12 previous errors
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr
deleted file mode 100644
index 13b58fde862..00000000000
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr
+++ /dev/null
@@ -1,115 +0,0 @@
-error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:28:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:31:5
-   |
-LL |     avx_bmi2();
-   |     ^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:34:5
-   |
-LL |     Quux.avx_bmi2();
-   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:41:5
-   |
-LL |     avx_bmi2();
-   |     ^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:44:5
-   |
-LL |     Quux.avx_bmi2();
-   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
-
-error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:51:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:54:5
-   |
-LL |     avx_bmi2();
-   |     ^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
-
-error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:57:5
-   |
-LL |     Quux.avx_bmi2();
-   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
-
-error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:65:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:70:15
-   |
-LL | const _: () = sse2();
-   |               ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-
-error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:74:15
-   |
-LL | const _: () = sse2_and_fxsr();
-   |               ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target features: sse2 and fxsr
-   = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
-
-error: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block (error E0133)
-  --> $DIR/safe-calls.rs:82:5
-   |
-LL |     sse2();
-   |     ^^^^^^ call to function with `#[target_feature]`
-   |
-   = help: in order for the call to be safe, the context requires the following additional target feature: sse2
-   = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
-note: an unsafe function restricts its caller, but its body is safe by default
-  --> $DIR/safe-calls.rs:81:1
-   |
-LL | unsafe fn needs_unsafe_block() {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: the lint level is defined here
-  --> $DIR/safe-calls.rs:78:8
-   |
-LL | #[deny(unsafe_op_in_unsafe_fn)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 12 previous errors
-
-For more information about this error, try `rustc --explain E0133`.