From 759df539ae2d4f231552162c2ad0ef5fc0ff72bf Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 10 Jul 2024 14:00:35 -0700 Subject: [PATCH] rustdoc-search: simplify rules for generics and type params This commit is a response to feedback on the displayed type signatures results, by making type params looser and generics act stricter. Type params are loosened by allowing a single function type param to match multiple query params. In other words, the relationship is loosened to N:1 instead of the older 1:1 rule. This change also allows a type param to be unboxed in one spot and matched in another. Generics are tightened by making order significant. This means `Vec` now matches only with a true vector of allocators, instead of matching the second type param. It also makes unboxing within generics stricter, so `Result` only matches if `B` is in the error type and `A` is in the success type. The top level of the function search is unaffected. Find the discussion on: * * --- .../rustdoc/src/read-documentation/search.md | 12 +- src/librustdoc/html/static/js/search.js | 290 ++++++++++++++---- .../rustdoc-gui/search-about-this-result.goml | 4 +- .../rustdoc-js-std/option-type-signatures.js | 21 +- tests/rustdoc-js-std/vec-type-signatures.js | 4 +- tests/rustdoc-js/assoc-type-backtrack.js | 38 ++- tests/rustdoc-js/assoc-type-unbound.js | 4 +- tests/rustdoc-js/generics-match-ambiguity.js | 12 +- tests/rustdoc-js/generics-nested.js | 5 +- tests/rustdoc-js/generics-unbox.js | 4 - tests/rustdoc-js/nested-unboxed.js | 9 +- tests/rustdoc-js/reference.js | 15 +- 12 files changed, 287 insertions(+), 131 deletions(-) diff --git a/src/doc/rustdoc/src/read-documentation/search.md b/src/doc/rustdoc/src/read-documentation/search.md index e912ca0fe5b45..718d2201c3a5d 100644 --- a/src/doc/rustdoc/src/read-documentation/search.md +++ b/src/doc/rustdoc/src/read-documentation/search.md @@ -130,29 +130,31 @@ pub trait MyTrait { /// This function can be found using the following search queries: /// /// MyTrait -> bool -/// MyTrait -> bool /// MyTrait -> bool -/// MyTrait -> bool /// /// The following queries, however, will *not* match it: /// /// MyTrait -> bool /// MyTrait -> bool +/// MyTrait -> bool +/// MyTrait -> bool pub fn my_fn(x: impl MyTrait) -> bool { true } ``` -Generics and function parameters are order-agnostic, but sensitive to nesting +Function parameters are order-agnostic, but sensitive to nesting and number of matches. For example, a function with the signature `fn read_all(&mut self: impl Read) -> Result, Error>` will match these queries: * `&mut Read -> Result, Error>` * `Read -> Result, Error>` -* `Read -> Result` * `Read -> Result>` * `Read -> u8` -But it *does not* match `Result` or `Result>`. +But it *does not* match `Result` or `Result>`, +because those are nested incorrectly, and it does not match +`Result>` or `Result`, because those are +in the wrong order. To search for a function that accepts a function as a parameter, like `Iterator::all`, wrap the nested signature in parenthesis, diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index f724142a466a7..e8008aac3d0a9 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1630,17 +1630,20 @@ function initSearch(rawSearchIndex) { */ function writeFn(fnType, result) { if (fnType.id < 0) { - const queryId = mgens && mgens.has(fnType.id) ? mgens.get(fnType.id) : null; if (fnParamNames[-1 - fnType.id] === "") { for (const nested of fnType.generics) { writeFn(nested, result); } return; - } else if (queryId < 0) { - mappedNames.set( - fnParamNames[-1 - fnType.id], - queryParamNames[-1 - queryId], - ); + } else if (mgens) { + for (const [queryId, fnId] of mgens) { + if (fnId === fnType.id) { + mappedNames.set( + queryParamNames[-1 - queryId], + fnParamNames[-1 - fnType.id], + ); + } + } } pushText({ name: fnParamNames[-1 - fnType.id], @@ -1863,7 +1866,7 @@ function initSearch(rawSearchIndex) { * @param {Array} queryElems - The elements from the parsed query. * @param {[FunctionType]} whereClause - Trait bounds for generic items. * @param {Map|null} mgensIn - * - Map functions generics to query generics (never modified). + * - Map query generics to function generics (never modified). * @param {null|Map -> bool} solutionCb - Called for each `mgens` solution. * @param {number} unboxingDepth * - Limit checks that Ty matches Vec, @@ -1904,12 +1907,12 @@ function initSearch(rawSearchIndex) { continue; } if (fnType.id < 0 && queryElem.id < 0) { - if (mgens && mgens.has(fnType.id) && - mgens.get(fnType.id) !== queryElem.id) { + if (mgens && mgens.has(queryElem.id) && + mgens.get(queryElem.id) !== fnType.id) { continue; } const mgensScratch = new Map(mgens); - mgensScratch.set(fnType.id, queryElem.id); + mgensScratch.set(queryElem.id, fnType.id); if (!solutionCb || solutionCb(mgensScratch)) { const highlighted = [...fnTypesIn]; highlighted[i] = Object.assign({ @@ -1925,7 +1928,7 @@ function initSearch(rawSearchIndex) { highlighted[i] = Object.assign({ highlighted: true, }, fnType, { - generics: unifyFunctionTypes( + generics: unifyGenericTypes( fnType.generics, queryElem.generics, whereClause, @@ -1948,17 +1951,11 @@ function initSearch(rawSearchIndex) { continue; } if (fnType.id < 0) { - if (mgens && mgens.has(fnType.id) && - mgens.get(fnType.id) !== 0) { - continue; - } - const mgensScratch = new Map(mgens); - mgensScratch.set(fnType.id, 0); const highlightedGenerics = unifyFunctionTypes( whereClause[(-fnType.id) - 1], queryElems, whereClause, - mgensScratch, + mgens, solutionCb, unboxingDepth + 1, ); @@ -2029,11 +2026,11 @@ function initSearch(rawSearchIndex) { let mgensScratch; if (fnType.id < 0) { mgensScratch = new Map(mgens); - if (mgensScratch.has(fnType.id) - && mgensScratch.get(fnType.id) !== queryElem.id) { + if (mgensScratch.has(queryElem.id) + && mgensScratch.get(queryElem.id) !== fnType.id) { continue; } - mgensScratch.set(fnType.id, queryElem.id); + mgensScratch.set(queryElem.id, fnType.id); } else { mgensScratch = mgens; } @@ -2070,7 +2067,7 @@ function initSearch(rawSearchIndex) { } const simplifiedGenerics = solution.simplifiedGenerics; for (const simplifiedMgens of solution.mgens) { - unifiedGenerics = unifyFunctionTypes( + unifiedGenerics = unifyGenericTypes( simplifiedGenerics, queryElem.generics, whereClause, @@ -2078,7 +2075,7 @@ function initSearch(rawSearchIndex) { solutionCb, unboxingDepth, ); - if (unifiedGenerics) { + if (unifiedGenerics !== null) { unifiedGenericsMgens = simplifiedMgens; return true; } @@ -2122,16 +2119,6 @@ function initSearch(rawSearchIndex) { )) { continue; } - let mgensScratch; - if (fnType.id < 0) { - mgensScratch = new Map(mgens); - if (mgensScratch.has(fnType.id) && mgensScratch.get(fnType.id) !== 0) { - continue; - } - mgensScratch.set(fnType.id, 0); - } else { - mgensScratch = mgens; - } const generics = fnType.id < 0 ? whereClause[(-fnType.id) - 1] : fnType.generics; @@ -2142,7 +2129,7 @@ function initSearch(rawSearchIndex) { fnTypes.toSpliced(i, 1, ...bindings, ...generics), queryElems, whereClause, - mgensScratch, + mgens, solutionCb, unboxingDepth + 1, ); @@ -2166,6 +2153,199 @@ function initSearch(rawSearchIndex) { } return null; } + /** + * This function compares two lists of generics. + * + * This function behaves very similarly to `unifyFunctionTypes`, except that it + * doesn't skip or reorder anything. This is intended to match the behavior of + * the ordinary Rust type system, so that `Vec` only matches an actual + * `Vec` of `Allocators` and not the implicit `Allocator` parameter that every + * `Vec` has. + * + * @param {Array} fnTypesIn - The objects to check. + * @param {Array} queryElems - The elements from the parsed query. + * @param {[FunctionType]} whereClause - Trait bounds for generic items. + * @param {Map|null} mgensIn + * - Map functions generics to query generics (never modified). + * @param {null|Map -> bool} solutionCb - Called for each `mgens` solution. + * @param {number} unboxingDepth + * - Limit checks that Ty matches Vec, + * but not Vec>>>> + * + * @return {[FunctionType]|null} - Returns highlighed results if a match, null otherwise. + */ + function unifyGenericTypes( + fnTypesIn, + queryElems, + whereClause, + mgensIn, + solutionCb, + unboxingDepth, + ) { + if (unboxingDepth >= UNBOXING_LIMIT) { + return null; + } + /** + * @type Map|null + */ + const mgens = mgensIn === null ? null : new Map(mgensIn); + if (queryElems.length === 0) { + return (!solutionCb || solutionCb(mgens)) ? fnTypesIn : null; + } + if (!fnTypesIn || fnTypesIn.length === 0) { + return null; + } + const fnType = fnTypesIn[0]; + const queryElem = queryElems[0]; + if (unifyFunctionTypeIsMatchCandidate(fnType, queryElem, mgens)) { + if (fnType.id < 0 && queryElem.id < 0) { + if (!mgens || !mgens.has(queryElem.id) || + mgens.get(queryElem.id) === fnType.id + ) { + const mgensScratch = new Map(mgens); + mgensScratch.set(queryElem.id, fnType.id); + const fnTypesRemaining = unifyGenericTypes( + fnTypesIn.slice(1), + queryElems.slice(1), + whereClause, + mgensScratch, + solutionCb, + unboxingDepth, + ); + if (fnTypesRemaining) { + const highlighted = [fnType, ...fnTypesRemaining]; + highlighted[0] = Object.assign({ + highlighted: true, + }, fnType, { + generics: whereClause[-1 - fnType.id], + }); + return highlighted; + } + } + } else { + let unifiedGenerics; + const fnTypesRemaining = unifyGenericTypes( + fnTypesIn.slice(1), + queryElems.slice(1), + whereClause, + mgens, + mgensScratch => { + const solution = unifyFunctionTypeCheckBindings( + fnType, + queryElem, + whereClause, + mgensScratch, + unboxingDepth, + ); + if (!solution) { + return false; + } + const simplifiedGenerics = solution.simplifiedGenerics; + for (const simplifiedMgens of solution.mgens) { + unifiedGenerics = unifyGenericTypes( + simplifiedGenerics, + queryElem.generics, + whereClause, + simplifiedMgens, + solutionCb, + unboxingDepth, + ); + if (unifiedGenerics !== null) { + return true; + } + } + }, + unboxingDepth, + ); + if (fnTypesRemaining) { + const highlighted = [fnType, ...fnTypesRemaining]; + highlighted[0] = Object.assign({ + highlighted: true, + }, fnType, { + generics: unifiedGenerics || fnType.generics, + }); + return highlighted; + } + } + } + if (unifyFunctionTypeIsUnboxCandidate( + fnType, + queryElem, + whereClause, + mgens, + unboxingDepth + 1, + )) { + let highlightedRemaining; + if (fnType.id < 0) { + // Where clause corresponds to `F: A + B` + // ^^^^^ + // The order of the constraints doesn't matter, so + // use order-agnostic matching for it. + const highlightedGenerics = unifyFunctionTypes( + whereClause[(-fnType.id) - 1], + [queryElem], + whereClause, + mgens, + mgensScratch => { + const hl = unifyGenericTypes( + fnTypesIn.slice(1), + queryElems.slice(1), + whereClause, + mgensScratch, + solutionCb, + unboxingDepth, + ); + if (hl) { + highlightedRemaining = hl; + } + return hl; + }, + unboxingDepth + 1, + ); + if (highlightedGenerics) { + return [Object.assign({ + highlighted: true, + }, fnType, { + generics: highlightedGenerics, + }), ...highlightedRemaining]; + } + } else { + const highlightedGenerics = unifyGenericTypes( + [ + ...Array.from(fnType.bindings.values()).flat(), + ...fnType.generics, + ], + [queryElem], + whereClause, + mgens, + mgensScratch => { + const hl = unifyGenericTypes( + fnTypesIn.slice(1), + queryElems.slice(1), + whereClause, + mgensScratch, + solutionCb, + unboxingDepth, + ); + if (hl) { + highlightedRemaining = hl; + } + return hl; + }, + unboxingDepth + 1, + ); + if (highlightedGenerics) { + return [Object.assign({}, fnType, { + generics: highlightedGenerics, + bindings: new Map([...fnType.bindings.entries()].map(([k, v]) => { + return [k, highlightedGenerics.splice(0, v.length)]; + })), + }), ...highlightedRemaining]; + } + } + } + return null; + } /** * Check if this function is a match candidate. * @@ -2177,7 +2357,7 @@ function initSearch(rawSearchIndex) { * * @param {FunctionType} fnType * @param {QueryElement} queryElem - * @param {Map|null} mgensIn - Map functions generics to query generics. + * @param {Map|null} mgensIn - Map query generics to function generics. * @returns {boolean} */ function unifyFunctionTypeIsMatchCandidate(fnType, queryElem, mgensIn) { @@ -2187,22 +2367,13 @@ function initSearch(rawSearchIndex) { } // fnType.id < 0 means generic // queryElem.id < 0 does too - // mgensIn[fnType.id] = queryElem.id - // or, if mgensIn[fnType.id] = 0, then we've matched this generic with a bare trait - // and should make that same decision everywhere it appears + // mgensIn[queryElem.id] = fnType.id if (fnType.id < 0 && queryElem.id < 0) { - if (mgensIn) { - if (mgensIn.has(fnType.id) && mgensIn.get(fnType.id) !== queryElem.id) { - return false; - } - for (const [fid, qid] of mgensIn.entries()) { - if (fnType.id !== fid && queryElem.id === qid) { - return false; - } - if (fnType.id === fid && queryElem.id !== qid) { - return false; - } - } + if ( + mgensIn && mgensIn.has(queryElem.id) && + mgensIn.get(queryElem.id) !== fnType.id + ) { + return false; } return true; } else { @@ -2279,7 +2450,7 @@ function initSearch(rawSearchIndex) { * @param {FunctionType} fnType * @param {QueryElement} queryElem * @param {[FunctionType]} whereClause - Trait bounds for generic items. - * @param {Map} mgensIn - Map functions generics to query generics. + * @param {Map} mgensIn - Map query generics to function generics. * Never modified. * @param {number} unboxingDepth * @returns {false|{mgens: [Map], simplifiedGenerics: [FunctionType]}} @@ -2347,7 +2518,7 @@ function initSearch(rawSearchIndex) { * @param {FunctionType} fnType * @param {QueryElement} queryElem * @param {[FunctionType]} whereClause - Trait bounds for generic items. - * @param {Map|null} mgens - Map functions generics to query generics. + * @param {Map|null} mgens - Map query generics to function generics. * @param {number} unboxingDepth * @returns {boolean} */ @@ -2361,19 +2532,10 @@ function initSearch(rawSearchIndex) { if (unboxingDepth >= UNBOXING_LIMIT) { return false; } - if (fnType.id < 0 && queryElem.id >= 0) { + if (fnType.id < 0) { if (!whereClause) { return false; } - // mgens[fnType.id] === 0 indicates that we committed to unboxing this generic - // mgens[fnType.id] === null indicates that we haven't decided yet - if (mgens && mgens.has(fnType.id) && mgens.get(fnType.id) !== 0) { - return false; - } - // Where clauses can represent cyclical data. - // `null` prevents it from trying to unbox in an infinite loop - const mgensTmp = new Map(mgens); - mgensTmp.set(fnType.id, null); // This is only a potential unbox if the search query appears in the where clause // for example, searching `Read -> usize` should find // `fn read_all(R) -> Result` @@ -2382,7 +2544,7 @@ function initSearch(rawSearchIndex) { whereClause[(-fnType.id) - 1], queryElem, whereClause, - mgensTmp, + mgens, unboxingDepth, ); } else if (fnType.generics.length > 0 || fnType.bindings.size > 0) { @@ -3143,7 +3305,7 @@ ${item.displayPath}${name}\ displayType.appendChild(line); addWhereLineFn = () => {}; }; - for (const [name, qname] of mappedNames) { + for (const [qname, name] of mappedNames) { // don't care unless the generic name is different if (name === qname) { continue; diff --git a/tests/rustdoc-gui/search-about-this-result.goml b/tests/rustdoc-gui/search-about-this-result.goml index 62780d01ed7e8..1d45c06dc43d4 100644 --- a/tests/rustdoc-gui/search-about-this-result.goml +++ b/tests/rustdoc-gui/search-about-this-result.goml @@ -11,8 +11,8 @@ assert-count: ("#search-tabs button", 1) assert-count: (".search-results > a", 1) assert: "//div[@class='type-signature']/strong[text()='Iterator']" -assert: "//div[@class='type-signature']/strong[text()='(']" -assert: "//div[@class='type-signature']/strong[text()=')']" +assert: "//div[@class='type-signature']/strong[text()='(B']" +assert: "//div[@class='type-signature']/strong[text()='B)']" assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='FnMut']" assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='Iterator::Item']" diff --git a/tests/rustdoc-js-std/option-type-signatures.js b/tests/rustdoc-js-std/option-type-signatures.js index 1690d5dc8b5bb..6ae755c69a669 100644 --- a/tests/rustdoc-js-std/option-type-signatures.js +++ b/tests/rustdoc-js-std/option-type-signatures.js @@ -80,11 +80,6 @@ const EXPECTED = [ 'name': 'and', 'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`U`>', }, - { - 'path': 'std::option::Option', - 'name': 'zip', - 'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<(T, `U`)>', - }, ], }, { @@ -103,12 +98,12 @@ const EXPECTED = [ ], }, { - 'query': 'option, option -> option', + 'query': 'option, option -> option<(t, u)>', 'others': [ { 'path': 'std::option::Option', 'name': 'zip', - 'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<(`T`, `U`)>', + 'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`(T`, `U)`>', }, ], }, @@ -174,35 +169,35 @@ const EXPECTED = [ 'path': 'std::option::Option', 'name': 'map', 'displayType': '`Option`<`T`>, F -> `Option`', - 'displayMappedNames': `T = t, U = u`, + 'displayMappedNames': `t = T, u = U`, 'displayWhereClause': "F: `FnOnce` (T) -> `U`", }, { 'path': 'std::option::Option', 'name': 'and_then', 'displayType': '`Option`<`T`>, F -> `Option`', - 'displayMappedNames': `T = t, U = u`, + 'displayMappedNames': `t = T, u = U`, 'displayWhereClause': "F: `FnOnce` (T) -> Option<`U`>", }, { 'path': 'std::option::Option', 'name': 'zip_with', 'displayType': 'Option, `Option`<`U`>, F -> `Option`', - 'displayMappedNames': `U = t, R = u`, + 'displayMappedNames': `t = U, u = R`, 'displayWhereClause': "F: `FnOnce` (T, U) -> `R`", }, { 'path': 'std::task::Poll', 'name': 'map_ok', 'displayType': 'Poll<`Option`>>, F -> Poll<`Option`>>', - 'displayMappedNames': `T = t, U = u`, + 'displayMappedNames': `t = T, u = U`, 'displayWhereClause': "F: `FnOnce` (T) -> `U`", }, { 'path': 'std::task::Poll', 'name': 'map_err', 'displayType': 'Poll<`Option`>>, F -> Poll<`Option`>>', - 'displayMappedNames': `T = t, U = u`, + 'displayMappedNames': `t = T, u = U`, 'displayWhereClause': "F: `FnOnce` (E) -> `U`", }, ], @@ -214,7 +209,7 @@ const EXPECTED = [ 'path': 'std::option::Option', 'name': 'and_then', 'displayType': '`Option`<`T`>, F -> `Option`', - 'displayMappedNames': `T = t, U = u`, + 'displayMappedNames': `t = T, u = U`, 'displayWhereClause': "F: `FnOnce` (T) -> `Option`<`U`>", }, ], diff --git a/tests/rustdoc-js-std/vec-type-signatures.js b/tests/rustdoc-js-std/vec-type-signatures.js index 4e93caf53beeb..3c2ff30a83330 100644 --- a/tests/rustdoc-js-std/vec-type-signatures.js +++ b/tests/rustdoc-js-std/vec-type-signatures.js @@ -20,12 +20,12 @@ const EXPECTED = [ ], }, { - 'query': 'vec -> Box<[T]>', + 'query': 'vec -> Box<[T]>', 'others': [ { 'path': 'std::boxed::Box', 'name': 'from', - 'displayType': '`Vec` -> `Box`<`[T]`, A>', + 'displayType': '`Vec`<`T`, `A`> -> `Box`<`[T]`, A>', 'displayMappedNames': `T = T`, 'displayWhereClause': 'A: `Allocator`', }, diff --git a/tests/rustdoc-js/assoc-type-backtrack.js b/tests/rustdoc-js/assoc-type-backtrack.js index 493e1a9910d18..24b82b7b92c7e 100644 --- a/tests/rustdoc-js/assoc-type-backtrack.js +++ b/tests/rustdoc-js/assoc-type-backtrack.js @@ -89,19 +89,21 @@ const EXPECTED = [ ], }, { - 'query': 'myintofuture> -> myfuture', + 'query': 'myintofuture> -> myfuture', 'correction': null, 'others': [ { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' }, { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, ], }, - // Invalid unboxing of the one-argument case. - // If you unbox one of the myfutures, you need to unbox both of them. + // Unboxings of the one-argument case. { 'query': 'myintofuture -> myfuture', 'correction': null, - 'others': [], + 'others': [ + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' }, + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, + ], }, // Unboxings of the two-argument case. { @@ -119,7 +121,7 @@ const EXPECTED = [ ], }, { - 'query': 'myintofuture, myintofuture -> myfuture', + 'query': 'myintofuture, myintofuture -> myfuture', 'correction': null, 'others': [ { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, @@ -132,32 +134,42 @@ const EXPECTED = [ { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, ], }, - // Invalid unboxings of the two-argument case. - // If you unbox one of the myfutures, you need to unbox all of them. + // If you unbox one of the myfutures, you don't need to unbox all of them. { 'query': 'myintofuture, myintofuture> -> myfuture', 'correction': null, - 'others': [], + 'others': [ + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, + ], }, { 'query': 'myintofuture>, myintofuture -> myfuture', 'correction': null, - 'others': [], + 'others': [ + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, + ], }, { 'query': 'myintofuture>, myintofuture> -> t', 'correction': null, - 'others': [], + 'others': [ + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, + ], }, - // different generics don't match up either + // different generics will match up (didn't used to, but does now) { 'query': 'myintofuture>, myintofuture> -> myfuture', 'correction': null, - 'others': [], + 'others': [ + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, + ], }, { 'query': 'myintofuture -> myfuture', 'correction': null, - 'others': [], + 'others': [ + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' }, + { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, + ], }, ]; diff --git a/tests/rustdoc-js/assoc-type-unbound.js b/tests/rustdoc-js/assoc-type-unbound.js index 611b8bd1501c7..9fd14f9d9fb59 100644 --- a/tests/rustdoc-js/assoc-type-unbound.js +++ b/tests/rustdoc-js/assoc-type-unbound.js @@ -13,7 +13,7 @@ const EXPECTED = [ 'path': 'assoc_type_unbound::MyIter', 'name': 'next', 'displayType': '&mut `MyIter` -> `Option`<`MyIter::Item`>', - 'displayMappedNames': 'MyIter::Item = T', + 'displayMappedNames': 'T = MyIter::Item', 'displayWhereClause': '', }, ], @@ -26,7 +26,7 @@ const EXPECTED = [ 'path': 'assoc_type_unbound::MyIter', 'name': 'next', 'displayType': '&mut `MyIter` -> `Option`<`MyIter::Item`>', - 'displayMappedNames': 'MyIter::Item = T', + 'displayMappedNames': 'T = MyIter::Item', 'displayWhereClause': '', }, ], diff --git a/tests/rustdoc-js/generics-match-ambiguity.js b/tests/rustdoc-js/generics-match-ambiguity.js index edce4268c5ac7..aadb179321cf2 100644 --- a/tests/rustdoc-js/generics-match-ambiguity.js +++ b/tests/rustdoc-js/generics-match-ambiguity.js @@ -60,18 +60,14 @@ const EXPECTED = [ ], }, { + // strict generics matching; W2 doesn't match W2>, + // even though W2 works just fine (ignoring the W3) 'query': 'W2, W2', - 'others': [ - { 'path': 'generics_match_ambiguity', 'name': 'baag' }, - { 'path': 'generics_match_ambiguity', 'name': 'baah' }, - ], + 'others': [], }, { 'query': 'W2, W2', - 'others': [ - { 'path': 'generics_match_ambiguity', 'name': 'baag' }, - { 'path': 'generics_match_ambiguity', 'name': 'baah' }, - ], + 'others': [], }, { 'query': 'W2, W3', diff --git a/tests/rustdoc-js/generics-nested.js b/tests/rustdoc-js/generics-nested.js index 294c194907489..b3184dde0d0c9 100644 --- a/tests/rustdoc-js/generics-nested.js +++ b/tests/rustdoc-js/generics-nested.js @@ -18,9 +18,8 @@ const EXPECTED = [ ], }, { + // can't put generics out of order 'query': '-> Out', - 'others': [ - { 'path': 'generics_nested', 'name': 'bet' }, - ], + 'others': [], }, ]; diff --git a/tests/rustdoc-js/generics-unbox.js b/tests/rustdoc-js/generics-unbox.js index 9cdfc7ac8b6e5..6baf00c814bba 100644 --- a/tests/rustdoc-js/generics-unbox.js +++ b/tests/rustdoc-js/generics-unbox.js @@ -11,20 +11,17 @@ const EXPECTED = [ 'query': 'Inside -> Out3', 'others': [ { 'path': 'generics_unbox', 'name': 'beta' }, - { 'path': 'generics_unbox', 'name': 'gamma' }, ], }, { 'query': 'Inside -> Out4', 'others': [ - { 'path': 'generics_unbox', 'name': 'beta' }, { 'path': 'generics_unbox', 'name': 'gamma' }, ], }, { 'query': 'Inside -> Out3', 'others': [ - { 'path': 'generics_unbox', 'name': 'beta' }, { 'path': 'generics_unbox', 'name': 'gamma' }, ], }, @@ -32,7 +29,6 @@ const EXPECTED = [ 'query': 'Inside -> Out4', 'others': [ { 'path': 'generics_unbox', 'name': 'beta' }, - { 'path': 'generics_unbox', 'name': 'gamma' }, ], }, ]; diff --git a/tests/rustdoc-js/nested-unboxed.js b/tests/rustdoc-js/nested-unboxed.js index 44f784eb1f638..5f9eabc12f60f 100644 --- a/tests/rustdoc-js/nested-unboxed.js +++ b/tests/rustdoc-js/nested-unboxed.js @@ -33,9 +33,8 @@ const EXPECTED = [ }, { 'query': '-> Result', - 'others': [ - { 'path': 'nested_unboxed', 'name': 'something' }, - ], + // can't put nested generics out of order + 'others': [], }, { 'query': '-> Result, bool>', @@ -45,9 +44,7 @@ const EXPECTED = [ }, { 'query': '-> Result, bool>', - 'others': [ - { 'path': 'nested_unboxed', 'name': 'something' }, - ], + 'others': [], }, { 'query': '-> Result, u32, bool>', diff --git a/tests/rustdoc-js/reference.js b/tests/rustdoc-js/reference.js index b4a1fb15d369a..378fc03475b87 100644 --- a/tests/rustdoc-js/reference.js +++ b/tests/rustdoc-js/reference.js @@ -79,9 +79,8 @@ const EXPECTED = [ }, { 'query': 'reference, reference -> ()', - 'others': [ - { 'path': 'reference::Ring', 'name': 'wear' }, - ], + // can't leave out the `mut`, because can't reorder like that + 'others': [], }, { 'query': 'reference, reference -> ()', @@ -102,9 +101,8 @@ const EXPECTED = [ }, { 'query': 'reference, reference -> ()', - 'others': [ - { 'path': 'reference', 'name': 'show' }, - ], + // can't leave out the mut + 'others': [], }, { 'query': 'reference, reference -> ()', @@ -203,9 +201,8 @@ const EXPECTED = [ // middle with shorthand { 'query': '&middle, &middle -> ()', - 'others': [ - { 'path': 'reference', 'name': 'show' }, - ], + // can't leave out the mut + 'others': [], }, { 'query': '&mut middle, &mut middle -> ()',