From ca5a25496fea0f9ece6440c1d23cd63b1c0e7e50 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 19 Jan 2026 15:48:35 -0600 Subject: [PATCH 1/7] rustdoc: change getVar signature This has two advantages: * removes a bunch of @ts-expect-error * typos of var names will cause type errors instead of runtime errors --- src/librustdoc/html/static/js/main.js | 3 --- src/librustdoc/html/static/js/rustdoc.d.ts | 12 ++++++++++++ src/librustdoc/html/static/js/storage.js | 10 +++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index f438fe173810..28d3522e47e8 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -231,7 +231,6 @@ function preLoadCss(cssUrl) { // When loading settings.html as a standalone page, the equivalent HTML is // generated in context.rs. setTimeout(() => { - // @ts-expect-error const themes = getVar("themes").split(","); for (const theme of themes) { // if there are no themes, do nothing @@ -415,12 +414,10 @@ function preLoadCss(cssUrl) { } window.StringdexOnload.push(() => { loadScript( - // @ts-expect-error getVar("static-root-path") + getVar("search-js"), sendSearchForm, ); }); - // @ts-expect-error loadScript(getVar("static-root-path") + getVar("stringdex-js"), sendSearchForm); loadScript(resourcePath("search.index/root", ".js"), sendSearchForm); } diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 60df4fc10b8c..f53c98b9672d 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -576,4 +576,16 @@ declare namespace rustdoc { "typeNameIdOfHof": number, "typeNameIdOfNever": number, }; + + type VarName = "name" + | "root-path" + | "static-root-path" + | "current-crate" + | "themes" + | "resource-suffix" + | "rustdoc-version" + | "channel" + | "search-js" + | "stringdex-js" + | "settings-js"; } diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 40ab8be03c93..2d544eaa237a 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -199,12 +199,16 @@ function getCurrentValue(name) { * Get a value from the rustdoc-vars div, which is used to convey data from * Rust to the JS. If there is no such element, return null. * - * @param {string} name - * @returns {string|null} + * @param {rustdoc.VarName} name + * @returns {string} */ function getVar(name) { const el = document.querySelector("head > meta[name='rustdoc-vars']"); - return el ? el.getAttribute("data-" + name) : null; + const v = el ? el.getAttribute("data-" + name) : null; + if (v !== null) { + return v; + } + throw `rustdoc var "${name}" is missing`; } /** From b7ba80d2ad2d94e81e67e2063f33962aaa6aa760 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 19 Jan 2026 15:53:50 -0600 Subject: [PATCH 2/7] rustdoc(storage.js): add comment explaining use of @ts-ignore --- src/librustdoc/html/static/js/storage.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 2d544eaa237a..e722d8573783 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -298,6 +298,8 @@ const updateTheme = (function() { return updateTheme; })(); +// typescript thinks we're forgetting to call window.matchMedia, +// but we're checking browser support of media queries. // @ts-ignore if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) { // update the preferred dark theme if the user is already using a dark theme From 760d8868f045433d67a3c5e01754682da08f9e78 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 19 Jan 2026 16:00:46 -0600 Subject: [PATCH 3/7] rustdoc(main.js): use instanceof instead of tagName where applicable --- src/librustdoc/html/static/js/main.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 28d3522e47e8..4b37ae1f4296 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -619,8 +619,7 @@ function preLoadCss(cssUrl) { */ function openParentDetails(elem) { while (elem) { - if (elem.tagName === "DETAILS") { - // @ts-expect-error + if (elem instanceof HTMLDetailsElement) { elem.open = true; } elem = elem.parentElement; @@ -656,10 +655,8 @@ function preLoadCss(cssUrl) { } if (document.activeElement && - document.activeElement.tagName === "INPUT" && - // @ts-expect-error + document.activeElement instanceof HTMLInputElement && document.activeElement.type !== "checkbox" && - // @ts-expect-error document.activeElement.type !== "radio") { switch (getVirtualKey(ev)) { case "Escape": From 38d7b5309236c5a2898a378217455ad71f4b3aa9 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 19 Jan 2026 16:09:38 -0600 Subject: [PATCH 4/7] rustdoc(main.js): use nonnull to clear up type errors --- src/librustdoc/html/static/js/main.js | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 4b37ae1f4296..447aa1e02a4c 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -963,19 +963,19 @@ function preLoadCss(cssUrl) { const selfPath = script ? script.getAttribute("data-self-path") : null; // These sidebar blocks need filled in, too. - const mainContent = document.querySelector("#main-content"); - const sidebarSection = document.querySelector(".sidebar section"); + const mainContent = nonnull(document.querySelector("#main-content")); + const sidebarSection = nonnull(document.querySelector(".sidebar section")); let methods = document.querySelector(".sidebar .block.method"); let associatedTypes = document.querySelector(".sidebar .block.associatedtype"); let associatedConstants = document.querySelector(".sidebar .block.associatedconstant"); let sidebarTraitList = document.querySelector(".sidebar .block.trait-implementation"); - // @ts-expect-error - for (const impList of imp[window.currentCrate]) { + for (const impList of imp[nonnull(window.currentCrate)]) { const types = impList.slice(2); const text = impList[0]; const isTrait = impList[1] !== 0; const traitName = impList[1]; + // @ts-expect-error if (types.indexOf(selfPath) === -1) { continue; } @@ -999,33 +999,26 @@ function preLoadCss(cssUrl) { h.appendChild(link); trait_implementations = outputList; trait_implementations_header = outputListHeader; - // @ts-expect-error sidebarSection.appendChild(h); sidebarTraitList = document.createElement("ul"); sidebarTraitList.className = "block trait-implementation"; - // @ts-expect-error sidebarSection.appendChild(sidebarTraitList); - // @ts-expect-error mainContent.appendChild(outputListHeader); - // @ts-expect-error mainContent.appendChild(outputList); } else { implementations = outputList; if (trait_implementations) { - // @ts-expect-error mainContent.insertBefore(outputListHeader, trait_implementations_header); - // @ts-expect-error mainContent.insertBefore(outputList, trait_implementations_header); } else { - const mainContent = document.querySelector("#main-content"); - // @ts-expect-error + const mainContent = nonnull(document.querySelector("#main-content")); mainContent.appendChild(outputListHeader); - // @ts-expect-error mainContent.appendChild(outputList); } } } const template = document.createElement("template"); + // @ts-expect-error template.innerHTML = text; onEachLazy(template.content.querySelectorAll("a"), elem => { @@ -1065,8 +1058,8 @@ function preLoadCss(cssUrl) { if (isTrait) { const li = document.createElement("li"); const a = document.createElement("a"); + a.href = `#${nonnull(template.content.querySelector(".impl")).id}`; // @ts-expect-error - a.href = `#${template.content.querySelector(".impl").id}`; a.textContent = traitName; li.appendChild(a); // @ts-expect-error @@ -1093,14 +1086,10 @@ function preLoadCss(cssUrl) { const insertionReference = methods || sidebarTraitList; if (insertionReference) { const insertionReferenceH = insertionReference.previousElementSibling; - // @ts-expect-error sidebarSection.insertBefore(blockHeader, insertionReferenceH); - // @ts-expect-error sidebarSection.insertBefore(block, insertionReferenceH); } else { - // @ts-expect-error sidebarSection.appendChild(blockHeader); - // @ts-expect-error sidebarSection.appendChild(block); } if (hasClass(item, "associatedtype")) { From 3b4de4b21d93e349d83b5cb59b98cb832c764746 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 19 Jan 2026 16:44:05 -0600 Subject: [PATCH 5/7] rustdoc: make TypeImpls more specific. --- src/librustdoc/html/static/js/main.js | 1 - src/librustdoc/html/static/js/rustdoc.d.ts | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 447aa1e02a4c..eca1bd366d4b 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1018,7 +1018,6 @@ function preLoadCss(cssUrl) { } } const template = document.createElement("template"); - // @ts-expect-error template.innerHTML = text; onEachLazy(template.content.querySelectorAll("a"), elem => { diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index f53c98b9672d..a7dfaa61bfec 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -524,7 +524,8 @@ declare namespace rustdoc { } type TypeImpls = { - [cratename: string]: Array> + /* [text, traitName (0 if not a trait), ...types] */ + [cratename: string]: Array<[string, string|0, ...string[]]> } /** From 519c0d9d433debe17a877e6ee46e9d81fc603763 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 19 Jan 2026 17:07:31 -0600 Subject: [PATCH 6/7] rustdoc: remove redundant mainContent variable --- src/librustdoc/html/static/js/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index eca1bd366d4b..a26683e2e9bb 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1011,7 +1011,6 @@ function preLoadCss(cssUrl) { mainContent.insertBefore(outputListHeader, trait_implementations_header); mainContent.insertBefore(outputList, trait_implementations_header); } else { - const mainContent = nonnull(document.querySelector("#main-content")); mainContent.appendChild(outputListHeader); mainContent.appendChild(outputList); } From bd1c36a115eee3542053a38be5e996b8e7908bc4 Mon Sep 17 00:00:00 2001 From: binarycat Date: Wed, 28 Jan 2026 11:14:09 -0600 Subject: [PATCH 7/7] rustdoc(main.js): use typeof in register_type_impls for isTrait this allows TypeScript to understand the relation between isTrait and traitName's type, getting rid of a type error. --- src/librustdoc/html/static/js/main.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index a26683e2e9bb..f980c92d8f7a 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -973,8 +973,8 @@ function preLoadCss(cssUrl) { for (const impList of imp[nonnull(window.currentCrate)]) { const types = impList.slice(2); const text = impList[0]; - const isTrait = impList[1] !== 0; const traitName = impList[1]; + const isTrait = typeof traitName === "string"; // @ts-expect-error if (types.indexOf(selfPath) === -1) { continue; @@ -1057,7 +1057,6 @@ function preLoadCss(cssUrl) { const li = document.createElement("li"); const a = document.createElement("a"); a.href = `#${nonnull(template.content.querySelector(".impl")).id}`; - // @ts-expect-error a.textContent = traitName; li.appendChild(a); // @ts-expect-error