diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 498b688ef995..ab0d663e26d7 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -1545,11 +1545,12 @@ function initSearch(rawSearchIndex) {
for (j = i; j !== fl; ++j) {
const fnType = fnTypes[j];
if (unifyFunctionTypeIsMatchCandidate(fnType, queryElem, whereClause, mgens)) {
+ const mgensScratch = new Map(mgens);
const simplifiedGenerics = unifyFunctionTypeCheckBindings(
fnType,
queryElem,
whereClause,
- mgens
+ mgensScratch
);
if (simplifiedGenerics) {
if (!fnTypesScratch) {
@@ -1559,7 +1560,7 @@ function initSearch(rawSearchIndex) {
simplifiedGenerics,
queryElem.generics,
whereClause,
- mgens,
+ mgensScratch,
mgensScratch => {
matchCandidates.push({
fnTypesScratch,
@@ -1635,7 +1636,7 @@ function initSearch(rawSearchIndex) {
*
* @param {FunctionType} fnType
* @param {QueryElement} queryElem
- * @param {[FunctionType]} whereClause - Trait bounds for generic items.
+ * @param {[FunctionSearchType]} whereClause - Trait bounds for generic items.
* @param {Map|null} mgensIn - Map functions generics to query generics.
* @returns {boolean}
*/
@@ -1725,10 +1726,11 @@ function initSearch(rawSearchIndex) {
* @param {FunctionType} fnType
* @param {QueryElement} queryElem
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
- * @param {Map|null} mgensIn - Map functions generics to query generics.
+ * @param {Map|null} mgensInout - Map functions generics to query generics.
+ * Written on success.
* @returns {boolean|FunctionType[]}
*/
- function unifyFunctionTypeCheckBindings(fnType, queryElem, whereClause, mgensIn) {
+ function unifyFunctionTypeCheckBindings(fnType, queryElem, whereClause, mgensInout) {
// Simplify generics now
let simplifiedGenerics = fnType.generics;
if (!simplifiedGenerics) {
@@ -1738,17 +1740,24 @@ function initSearch(rawSearchIndex) {
return false;
}
if (fnType.bindings.size > 0) {
+ const mgensResults = new Map(mgensInout);
for (const [name, constraints] of queryElem.bindings.entries()) {
if (!fnType.bindings.has(name)) {
return false;
}
// Since both items must have exactly one entry per name,
- // we don't need to backtrack here.
+ // we don't need to backtrack here, but do need to write mgens.
if (!unifyFunctionTypes(
fnType.bindings.get(name),
constraints,
whereClause,
- mgensIn
+ mgensResults,
+ mgens => {
+ for (const [fid, qid] of mgens.entries()) {
+ mgensResults.set(fid, qid);
+ }
+ return true;
+ }
)) {
return false;
}
@@ -1766,6 +1775,11 @@ function initSearch(rawSearchIndex) {
} else {
simplifiedGenerics = binds;
}
+ if (mgensInout) {
+ for (const [fid, qid] of mgensResults.entries()) {
+ mgensInout.set(fid, qid);
+ }
+ }
}
return simplifiedGenerics;
}
diff --git a/tests/rustdoc-js/assoc-type-backtrack.js b/tests/rustdoc-js/assoc-type-backtrack.js
new file mode 100644
index 000000000000..6560cac7ca45
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-backtrack.js
@@ -0,0 +1,66 @@
+// exact-check
+
+const EXPECTED = [
+ {
+ 'query': 'mytrait, mytrait2 -> T',
+ 'correction': null,
+ 'others': [
+ { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
+ { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
+ ],
+ },
+ {
+ 'query': 'mytrait, mytrait2 -> T',
+ 'correction': null,
+ 'others': [
+ { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
+ { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
+ ],
+ },
+ {
+ 'query': 'mytrait- , mytrait2 -> T',
+ 'correction': null,
+ 'others': [
+ { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
+ { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
+ ],
+ },
+ {
+ 'query': 'mytrait, mytrait2 -> T',
+ 'correction': null,
+ 'others': [],
+ },
+ {
+ 'query': 'mytrait
- , mytrait2 -> T',
+ 'correction': null,
+ 'others': [],
+ },
+ {
+ 'query': 'mytrait -> Option',
+ 'correction': null,
+ 'others': [
+ { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'next' },
+ ],
+ },
+ {
+ 'query': 'mytrait
- -> Option',
+ 'correction': null,
+ 'others': [
+ { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'next' },
+ ],
+ },
+ {
+ 'query': 'mytrait -> Option',
+ 'correction': null,
+ 'others': [
+ { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
+ ],
+ },
+ {
+ 'query': 'mytrait
- -> Option',
+ 'correction': null,
+ 'others': [
+ { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
+ ],
+ },
+];
diff --git a/tests/rustdoc-js/assoc-type-backtrack.rs b/tests/rustdoc-js/assoc-type-backtrack.rs
new file mode 100644
index 000000000000..8e167ad8e7b7
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-backtrack.rs
@@ -0,0 +1,27 @@
+pub trait MyTrait2 {
+ type Output;
+}
+
+pub trait MyTrait {
+ type Item;
+ fn next(&mut self) -> Option;
+ fn fold(self, init: B, f: F) -> B where
+ Self: Sized,
+ F: MyTrait2<(B, Self::Item), Output=B>;
+}
+
+pub struct Cloned(I);
+
+impl<'a, T, I> MyTrait for Cloned where
+ T: 'a + Clone,
+ I: MyTrait
-
+{
+ type Item = T;
+ fn next(&mut self) -> Option { loop {} }
+ fn fold(self, init: B, f: F) -> B where
+ Self: Sized,
+ F: MyTrait2<(B, Self::Item), Output=B>
+ {
+ loop {}
+ }
+}