Skip to content

Commit b4dec52

Browse files
committed
rustdoc: fix generics tracking bug in type binding
1 parent 6837943 commit b4dec52

File tree

3 files changed

+114
-7
lines changed

3 files changed

+114
-7
lines changed

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

+21-7
Original file line numberDiff line numberDiff line change
@@ -1545,11 +1545,12 @@ function initSearch(rawSearchIndex) {
15451545
for (j = i; j !== fl; ++j) {
15461546
const fnType = fnTypes[j];
15471547
if (unifyFunctionTypeIsMatchCandidate(fnType, queryElem, whereClause, mgens)) {
1548+
const mgensScratch = new Map(mgens);
15481549
const simplifiedGenerics = unifyFunctionTypeCheckBindings(
15491550
fnType,
15501551
queryElem,
15511552
whereClause,
1552-
mgens
1553+
mgensScratch
15531554
);
15541555
if (simplifiedGenerics) {
15551556
if (!fnTypesScratch) {
@@ -1559,7 +1560,7 @@ function initSearch(rawSearchIndex) {
15591560
simplifiedGenerics,
15601561
queryElem.generics,
15611562
whereClause,
1562-
mgens,
1563+
mgensScratch,
15631564
mgensScratch => {
15641565
matchCandidates.push({
15651566
fnTypesScratch,
@@ -1635,7 +1636,7 @@ function initSearch(rawSearchIndex) {
16351636
*
16361637
* @param {FunctionType} fnType
16371638
* @param {QueryElement} queryElem
1638-
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
1639+
* @param {[FunctionSearchType]} whereClause - Trait bounds for generic items.
16391640
* @param {Map<number,number>|null} mgensIn - Map functions generics to query generics.
16401641
* @returns {boolean}
16411642
*/
@@ -1725,10 +1726,11 @@ function initSearch(rawSearchIndex) {
17251726
* @param {FunctionType} fnType
17261727
* @param {QueryElement} queryElem
17271728
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
1728-
* @param {Map<number,number>|null} mgensIn - Map functions generics to query generics.
1729+
* @param {Map<number,number>|null} mgensInout - Map functions generics to query generics.
1730+
* Written on success.
17291731
* @returns {boolean|FunctionType[]}
17301732
*/
1731-
function unifyFunctionTypeCheckBindings(fnType, queryElem, whereClause, mgensIn) {
1733+
function unifyFunctionTypeCheckBindings(fnType, queryElem, whereClause, mgensInout) {
17321734
// Simplify generics now
17331735
let simplifiedGenerics = fnType.generics;
17341736
if (!simplifiedGenerics) {
@@ -1738,17 +1740,24 @@ function initSearch(rawSearchIndex) {
17381740
return false;
17391741
}
17401742
if (fnType.bindings.size > 0) {
1743+
const mgensResults = new Map(mgensInout);
17411744
for (const [name, constraints] of queryElem.bindings.entries()) {
17421745
if (!fnType.bindings.has(name)) {
17431746
return false;
17441747
}
17451748
// Since both items must have exactly one entry per name,
1746-
// we don't need to backtrack here.
1749+
// we don't need to backtrack here, but do need to write mgens.
17471750
if (!unifyFunctionTypes(
17481751
fnType.bindings.get(name),
17491752
constraints,
17501753
whereClause,
1751-
mgensIn
1754+
mgensResults,
1755+
mgens => {
1756+
for (const [fid, qid] of mgens.entries()) {
1757+
mgensResults.set(fid, qid);
1758+
}
1759+
return true;
1760+
}
17521761
)) {
17531762
return false;
17541763
}
@@ -1766,6 +1775,11 @@ function initSearch(rawSearchIndex) {
17661775
} else {
17671776
simplifiedGenerics = binds;
17681777
}
1778+
if (mgensInout) {
1779+
for (const [fid, qid] of mgensResults.entries()) {
1780+
mgensInout.set(fid, qid);
1781+
}
1782+
}
17691783
}
17701784
return simplifiedGenerics;
17711785
}
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// exact-check
2+
3+
const EXPECTED = [
4+
{
5+
'query': 'mytrait, mytrait2 -> T',
6+
'correction': null,
7+
'others': [
8+
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
9+
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
10+
],
11+
},
12+
{
13+
'query': 'mytrait<U>, mytrait2 -> T',
14+
'correction': null,
15+
'others': [
16+
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
17+
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
18+
],
19+
},
20+
{
21+
'query': 'mytrait<Item=U>, mytrait2 -> T',
22+
'correction': null,
23+
'others': [
24+
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
25+
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
26+
],
27+
},
28+
{
29+
'query': 'mytrait<T>, mytrait2 -> T',
30+
'correction': null,
31+
'others': [],
32+
},
33+
{
34+
'query': 'mytrait<Item=T>, mytrait2 -> T',
35+
'correction': null,
36+
'others': [],
37+
},
38+
{
39+
'query': 'mytrait<T> -> Option<T>',
40+
'correction': null,
41+
'others': [
42+
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'next' },
43+
],
44+
},
45+
{
46+
'query': 'mytrait<Item=T> -> Option<T>',
47+
'correction': null,
48+
'others': [
49+
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'next' },
50+
],
51+
},
52+
{
53+
'query': 'mytrait<U> -> Option<T>',
54+
'correction': null,
55+
'others': [
56+
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
57+
],
58+
},
59+
{
60+
'query': 'mytrait<Item=U> -> Option<T>',
61+
'correction': null,
62+
'others': [
63+
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
64+
],
65+
},
66+
];
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
pub trait MyTrait2<X> {
2+
type Output;
3+
}
4+
5+
pub trait MyTrait {
6+
type Item;
7+
fn next(&mut self) -> Option<Self::Item>;
8+
fn fold<B, F>(self, init: B, f: F) -> B where
9+
Self: Sized,
10+
F: MyTrait2<(B, Self::Item), Output=B>;
11+
}
12+
13+
pub struct Cloned<I>(I);
14+
15+
impl<'a, T, I> MyTrait for Cloned<I> where
16+
T: 'a + Clone,
17+
I: MyTrait<Item = &'a T>
18+
{
19+
type Item = T;
20+
fn next(&mut self) -> Option<Self::Item> { loop {} }
21+
fn fold<B, F>(self, init: B, f: F) -> B where
22+
Self: Sized,
23+
F: MyTrait2<(B, Self::Item), Output=B>
24+
{
25+
loop {}
26+
}
27+
}

0 commit comments

Comments
 (0)