Skip to content

Commit c32124f

Browse files
Rollup merge of #137981 - lolbinarycat:rustdoc-js-less-expect-error, r=notriddle
rustdoc search: increase strictness of typechecking r? `@notriddle` The signature of `makePrimitiveElement` is now more accurate. I believe the intent of the code is that `name` cannot be null if `bindingName.name` is null, and I believe typescript is expressive enough to encode this, but I'm not quite sure how, or if this would be desirable. I'm also introducing mapped types into `rustdoc.d.ts`, but I think it's worth it in order to avoid keeping two interfaces in sync. I may add more commits onto this to remove more ``@ts-expect-error`` instances.
2 parents dfbd9b2 + 8920167 commit c32124f

File tree

2 files changed

+41
-45
lines changed

2 files changed

+41
-45
lines changed

src/librustdoc/html/static/js/rustdoc.d.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,24 @@ declare namespace rustdoc {
123123
* Same as QueryElement, but bindings and typeFilter support strings
124124
*/
125125
interface ParserQueryElement {
126-
name: string,
126+
name: string|null,
127127
id: number|null,
128128
fullPath: Array<string>,
129129
pathWithoutLast: Array<string>,
130130
pathLast: string,
131131
normalizedPathLast: string,
132132
generics: Array<ParserQueryElement>,
133133
bindings: Map<string, Array<ParserQueryElement>>,
134-
bindingName: {name: string, generics: ParserQueryElement[]}|null,
135-
typeFilter: string|null,
134+
bindingName: {name: string|null, generics: ParserQueryElement[]}|null,
135+
typeFilter: number|string|null,
136136
}
137137

138+
/**
139+
* Same as ParserQueryElement, but all fields are optional.
140+
*/
141+
type ParserQueryElementFields = {
142+
[K in keyof ParserQueryElement]?: ParserQueryElement[T]
143+
}
138144
/**
139145
* Intermediate parser state. Discarded when parsing is done.
140146
*/
@@ -176,10 +182,11 @@ declare namespace rustdoc {
176182
name: string,
177183
normalizedName: string,
178184
word: string,
185+
paramNames: string[],
179186
parent: ({ty: number, name: string, path: string, exactPath: string}|null|undefined),
180187
path: string,
181188
ty: number,
182-
type?: FunctionSearchType
189+
type: FunctionSearchType | null,
183190
}
184191

185192
/**
@@ -390,7 +397,7 @@ declare namespace rustdoc {
390397
*/
391398
type RawSearchIndexCrate = {
392399
doc: string,
393-
a: Object,
400+
a: { [key: string]: number[] },
394401
n: Array<string>,
395402
t: string,
396403
D: string,

src/librustdoc/html/static/js/search.js

+29-40
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,6 @@ function getNextElem(query, parserState, elems, isInGenerics) {
638638
getFilteredNextElem(query, parserState, generics, isInGenerics);
639639
generics[generics.length - 1].bindingName = makePrimitiveElement("output");
640640
} else {
641-
// @ts-expect-error
642641
generics.push(makePrimitiveElement(null, {
643642
bindingName: makePrimitiveElement("output"),
644643
typeFilter: null,
@@ -791,7 +790,7 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
791790
generics: generics.filter(gen => {
792791
// Syntactically, bindings are parsed as generics,
793792
// but the query engine treats them differently.
794-
if (gen.bindingName !== null) {
793+
if (gen.bindingName !== null && gen.bindingName.name !== null) {
795794
if (gen.name !== null) {
796795
gen.bindingName.generics.unshift(gen);
797796
}
@@ -811,8 +810,8 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
811810

812811
/**
813812
*
814-
* @param {string} name
815-
* @param {Object=} extra
813+
* @param {string|null} name
814+
* @param {rustdoc.ParserQueryElementFields=} extra
816815
* @returns {rustdoc.ParserQueryElement}
817816
*/
818817
function makePrimitiveElement(name, extra) {
@@ -1478,73 +1477,61 @@ class DocSearch {
14781477
* Special type name IDs for searching by array.
14791478
* @type {number}
14801479
*/
1481-
// @ts-expect-error
14821480
this.typeNameIdOfArray = this.buildTypeMapIndex("array");
14831481
/**
14841482
* Special type name IDs for searching by slice.
14851483
* @type {number}
14861484
*/
1487-
// @ts-expect-error
14881485
this.typeNameIdOfSlice = this.buildTypeMapIndex("slice");
14891486
/**
14901487
* Special type name IDs for searching by both array and slice (`[]` syntax).
14911488
* @type {number}
14921489
*/
1493-
// @ts-expect-error
14941490
this.typeNameIdOfArrayOrSlice = this.buildTypeMapIndex("[]");
14951491
/**
14961492
* Special type name IDs for searching by tuple.
14971493
* @type {number}
14981494
*/
1499-
// @ts-expect-error
15001495
this.typeNameIdOfTuple = this.buildTypeMapIndex("tuple");
15011496
/**
15021497
* Special type name IDs for searching by unit.
15031498
* @type {number}
15041499
*/
1505-
// @ts-expect-error
15061500
this.typeNameIdOfUnit = this.buildTypeMapIndex("unit");
15071501
/**
15081502
* Special type name IDs for searching by both tuple and unit (`()` syntax).
15091503
* @type {number}
15101504
*/
1511-
// @ts-expect-error
15121505
this.typeNameIdOfTupleOrUnit = this.buildTypeMapIndex("()");
15131506
/**
15141507
* Special type name IDs for searching `fn`.
15151508
* @type {number}
15161509
*/
1517-
// @ts-expect-error
15181510
this.typeNameIdOfFn = this.buildTypeMapIndex("fn");
15191511
/**
15201512
* Special type name IDs for searching `fnmut`.
15211513
* @type {number}
15221514
*/
1523-
// @ts-expect-error
15241515
this.typeNameIdOfFnMut = this.buildTypeMapIndex("fnmut");
15251516
/**
15261517
* Special type name IDs for searching `fnonce`.
15271518
* @type {number}
15281519
*/
1529-
// @ts-expect-error
15301520
this.typeNameIdOfFnOnce = this.buildTypeMapIndex("fnonce");
15311521
/**
15321522
* Special type name IDs for searching higher order functions (`->` syntax).
15331523
* @type {number}
15341524
*/
1535-
// @ts-expect-error
15361525
this.typeNameIdOfHof = this.buildTypeMapIndex("->");
15371526
/**
15381527
* Special type name IDs the output assoc type.
15391528
* @type {number}
15401529
*/
1541-
// @ts-expect-error
15421530
this.typeNameIdOfOutput = this.buildTypeMapIndex("output", true);
15431531
/**
15441532
* Special type name IDs for searching by reference.
15451533
* @type {number}
15461534
*/
1547-
// @ts-expect-error
15481535
this.typeNameIdOfReference = this.buildTypeMapIndex("reference");
15491536

15501537
/**
@@ -1586,7 +1573,6 @@ class DocSearch {
15861573
/**
15871574
* @type {Array<rustdoc.Row>}
15881575
*/
1589-
// @ts-expect-error
15901576
this.searchIndex = this.buildIndex(rawSearchIndex);
15911577
}
15921578

@@ -1598,10 +1584,16 @@ class DocSearch {
15981584
* done more quickly. Two types with the same name but different item kinds
15991585
* get the same ID.
16001586
*
1601-
* @param {string} name
1587+
* @template T extends string
1588+
* @overload
1589+
* @param {T} name
16021590
* @param {boolean=} isAssocType - True if this is an assoc type
1591+
* @returns {T extends "" ? null : number}
1592+
*
1593+
* @param {string} name
1594+
* @param {boolean=} isAssocType
1595+
* @returns {number | null}
16031596
*
1604-
* @returns {number?}
16051597
*/
16061598
buildTypeMapIndex(name, isAssocType) {
16071599
if (name === "" || name === null) {
@@ -1909,6 +1901,7 @@ class DocSearch {
19091901
* Convert raw search index into in-memory search index.
19101902
*
19111903
* @param {Map<string, rustdoc.RawSearchIndexCrate>} rawSearchIndex
1904+
* @returns {rustdoc.Row[]}
19121905
*/
19131906
buildIndex(rawSearchIndex) {
19141907
/**
@@ -2008,6 +2001,7 @@ class DocSearch {
20082001
return cb;
20092002
};
20102003

2004+
/** @type {rustdoc.Row[]} */
20112005
const searchIndex = [];
20122006
let currentIndex = 0;
20132007
let id = 0;
@@ -2108,8 +2102,6 @@ class DocSearch {
21082102
// an array of [(Number) item type,
21092103
// (String) name]
21102104
const rawPaths = crateCorpus.p;
2111-
// an array of [(String) alias name
2112-
// [Number] index to items]
21132105
const aliases = crateCorpus.a;
21142106
// an array of [(Number) item index,
21152107
// (String) comma-separated list of function generic param names]
@@ -2232,6 +2224,7 @@ class DocSearch {
22322224
// object defined above.
22332225
const itemParentIdx = itemParentIdxDecoder.next();
22342226
normalizedName = word.indexOf("_") === -1 ? word : word.replace(/_/g, "");
2227+
/** @type {rustdoc.Row} */
22352228
const row = {
22362229
crate,
22372230
ty: itemTypes.charCodeAt(i) - 65, // 65 = "A"
@@ -2274,16 +2267,14 @@ class DocSearch {
22742267
continue;
22752268
}
22762269

2277-
// @ts-expect-error
2270+
/** @type{number[]} */
22782271
let currentNameAliases;
22792272
if (currentCrateAliases.has(alias_name)) {
22802273
currentNameAliases = currentCrateAliases.get(alias_name);
22812274
} else {
22822275
currentNameAliases = [];
2283-
// @ts-expect-error
22842276
currentCrateAliases.set(alias_name, currentNameAliases);
22852277
}
2286-
// @ts-expect-error
22872278
for (const local_alias of aliases[alias_name]) {
22882279
currentNameAliases.push(local_alias + currentIndex);
22892280
}
@@ -2326,15 +2317,13 @@ class DocSearch {
23262317
* @param {rustdoc.ParserQueryElement} elem
23272318
*/
23282319
function convertTypeFilterOnElem(elem) {
2329-
if (elem.typeFilter !== null) {
2320+
if (typeof elem.typeFilter === "string") {
23302321
let typeFilter = elem.typeFilter;
23312322
if (typeFilter === "const") {
23322323
typeFilter = "constant";
23332324
}
2334-
// @ts-expect-error
23352325
elem.typeFilter = itemTypeFromName(typeFilter);
23362326
} else {
2337-
// @ts-expect-error
23382327
elem.typeFilter = NO_TYPE_FILTER;
23392328
}
23402329
for (const elem2 of elem.generics) {
@@ -2407,9 +2396,9 @@ class DocSearch {
24072396
continue;
24082397
}
24092398
if (!foundStopChar) {
2410-
let extra = "";
2399+
/** @type String[] */
2400+
let extra = [];
24112401
if (isLastElemGeneric(query.elems, parserState)) {
2412-
// @ts-expect-error
24132402
extra = [" after ", ">"];
24142403
} else if (prevIs(parserState, "\"")) {
24152404
throw ["Cannot have more than one element if you use quotes"];
@@ -2547,7 +2536,7 @@ class DocSearch {
25472536
* See `buildTypeMapIndex` for more information.
25482537
*
25492538
* @param {rustdoc.QueryElement} elem
2550-
* @param {boolean} isAssocType
2539+
* @param {boolean=} isAssocType
25512540
*/
25522541
const convertNameToId = (elem, isAssocType) => {
25532542
const loweredName = elem.pathLast.toLowerCase();
@@ -2627,7 +2616,6 @@ class DocSearch {
26272616
];
26282617
}
26292618
for (const elem2 of elem.generics) {
2630-
// @ts-expect-error
26312619
convertNameToId(elem2);
26322620
}
26332621
elem.bindings = new Map(Array.from(elem.bindings.entries())
@@ -2750,7 +2738,11 @@ class DocSearch {
27502738
return [displayPath, href, `${exactPath}::${name}`];
27512739
};
27522740

2753-
// @ts-expect-error
2741+
/**
2742+
*
2743+
* @param {string} path
2744+
* @returns {string}
2745+
*/
27542746
function pathSplitter(path) {
27552747
const tmp = "<span>" + path.replace(/::/g, "::</span><span>");
27562748
if (tmp.endsWith("<span>")) {
@@ -2763,9 +2755,9 @@ class DocSearch {
27632755
* Add extra data to result objects, and filter items that have been
27642756
* marked for removal.
27652757
*
2766-
* @param {[rustdoc.ResultObject]} results
2758+
* @param {rustdoc.ResultObject[]} results
27672759
* @param {"sig"|"elems"|"returned"|null} typeInfo
2768-
* @returns {[rustdoc.ResultObject]}
2760+
* @returns {rustdoc.ResultObject[]}
27692761
*/
27702762
const transformResults = (results, typeInfo) => {
27712763
const duplicates = new Set();
@@ -2840,7 +2832,7 @@ class DocSearch {
28402832
}
28412833
let fnInputs = null;
28422834
let fnOutput = null;
2843-
// @ts-expect-error
2835+
/** @type {Map<number, number> | null} */
28442836
let mgens = null;
28452837
if (typeInfo !== "elems" && typeInfo !== "returned") {
28462838
fnInputs = unifyFunctionTypes(
@@ -3053,7 +3045,6 @@ class DocSearch {
30533045
writeFn(nested, result);
30543046
}
30553047
return;
3056-
// @ts-expect-error
30573048
} else if (mgens) {
30583049
for (const [queryId, fnId] of mgens) {
30593050
if (fnId === fnType.id) {
@@ -3069,7 +3060,7 @@ class DocSearch {
30693060
name: fnParamNames[-1 - fnType.id],
30703061
highlighted: !!fnType.highlighted,
30713062
}, result);
3072-
// @ts-expect-error
3063+
/** @type{string[]} */
30733064
const where = [];
30743065
onEachBtwn(
30753066
fnType.generics,
@@ -3079,7 +3070,6 @@ class DocSearch {
30793070
() => pushText({ name: " + ", highlighted: false }, where),
30803071
);
30813072
if (where.length > 0) {
3082-
// @ts-expect-error
30833073
whereClause.set(fnParamNames[-1 - fnType.id], where);
30843074
}
30853075
} else {
@@ -3181,7 +3171,7 @@ class DocSearch {
31813171
* @param {rustdoc.Results} results
31823172
* @param {"sig"|"elems"|"returned"|null} typeInfo
31833173
* @param {string} preferredCrate
3184-
* @returns {Promise<[rustdoc.ResultObject]>}
3174+
* @returns {Promise<rustdoc.ResultObject[]>}
31853175
*/
31863176
const sortResults = async(results, typeInfo, preferredCrate) => {
31873177
const userQuery = parsedQuery.userQuery;
@@ -3337,7 +3327,6 @@ class DocSearch {
33373327
return 0;
33383328
});
33393329

3340-
// @ts-expect-error
33413330
return transformResults(result_list, typeInfo);
33423331
};
33433332

0 commit comments

Comments
 (0)