From a66972d5516c9d2e6e1fb99c263ca2aa2fc67b9e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 17 Nov 2023 15:44:29 -0700 Subject: [PATCH] rustdoc-search: fix accidental shared, mutable map --- src/librustdoc/html/static/js/search.js | 44 ++++++++----------------- tests/rustdoc-js/generics2.js | 22 +++++++++++++ tests/rustdoc-js/generics2.rs | 13 ++++++++ 3 files changed, 49 insertions(+), 30 deletions(-) create mode 100644 tests/rustdoc-js/generics2.js create mode 100644 tests/rustdoc-js/generics2.rs diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 38391436aea..a2aa50194e4 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1349,24 +1349,16 @@ function initSearch(rawSearchIndex) { continue; } if (fnType.id < 0 && queryElem.id < 0) { - if (mgens === null) { - mgens = new Map(); + if (mgens && mgens.has(fnType.id) && + mgens.get(fnType.id) !== queryElem.id) { + continue; } - const alreadyAssigned = mgens.has(fnType.id); - if (alreadyAssigned) { - if (mgens.get(fnType.id) !== queryElem.id) { - continue; - } - } else { - mgens.set(fnType.id, queryElem.id); - } - if (!solutionCb || solutionCb(mgens)) { + const mgensScratch = new Map(mgens); + mgensScratch.set(fnType.id, queryElem.id); + if (!solutionCb || solutionCb(mgensScratch)) { return true; } - if (!alreadyAssigned) { - mgens.delete(fnType.id); - } - } else if (!solutionCb || solutionCb(mgens)) { + } else if (!solutionCb || solutionCb(mgens ? new Map(mgens) : null)) { // unifyFunctionTypeIsMatchCandidate already checks that ids match return true; } @@ -1376,34 +1368,26 @@ function initSearch(rawSearchIndex) { continue; } if (fnType.id < 0) { - if (mgens === null) { - mgens = new Map(); - } - const alreadyAssigned = mgens.has(fnType.id); - if (alreadyAssigned) { - if (mgens.get(fnType.id) !== 0) { - continue; - } - } else { - mgens.set(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); if (unifyFunctionTypes( whereClause[(-fnType.id) - 1], queryElems, whereClause, - mgens, + mgensScratch, solutionCb )) { return true; } - if (!alreadyAssigned) { - mgens.delete(fnType.id); - } } else if (unifyFunctionTypes( fnType.generics, queryElems, whereClause, - mgens, + mgens ? new Map(mgens) : null, solutionCb )) { return true; diff --git a/tests/rustdoc-js/generics2.js b/tests/rustdoc-js/generics2.js new file mode 100644 index 00000000000..f08704349a4 --- /dev/null +++ b/tests/rustdoc-js/generics2.js @@ -0,0 +1,22 @@ +// exact-check + +const EXPECTED = [ + { + 'query': 'outside, outside -> outside', + 'others': [], + }, + { + 'query': 'outside, outside -> outside', + 'others': [], + }, + { + 'query': 'outside, outside -> outside', + 'others': [], + }, + { + 'query': 'outside, outside -> outside', + 'others': [ + {"path": "generics2", "name": "should_match_3"} + ], + }, +]; diff --git a/tests/rustdoc-js/generics2.rs b/tests/rustdoc-js/generics2.rs new file mode 100644 index 00000000000..1177ade6831 --- /dev/null +++ b/tests/rustdoc-js/generics2.rs @@ -0,0 +1,13 @@ +pub struct Outside(T); + +pub fn no_match(a: Outside, b: Outside) -> (Outside, Outside) { + unimplemented!(); +} + +pub fn no_match_2(a: Outside, b: Outside) -> (Outside, Outside) { + unimplemented!(); +} + +pub fn should_match_3(a: Outside, b: Outside) -> (Outside, Outside) { + unimplemented!(); +}