Skip to content

Commit dcce41e

Browse files
committed
rustdoc: fix generics tracking bug in type binding
1 parent c157abe commit dcce41e

File tree

3 files changed

+114
-7
lines changed

3 files changed

+114
-7
lines changed

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,11 +1506,12 @@ function initSearch(rawSearchIndex) {
15061506
for (j = i; j !== fl; ++j) {
15071507
const fnType = fnTypes[j];
15081508
if (unifyFunctionTypeIsMatchCandidate(fnType, queryElem, whereClause, mgens)) {
1509+
const mgensScratch = new Map(mgens);
15091510
const simplifiedGenerics = unifyFunctionTypeCheckBindings(
15101511
fnType,
15111512
queryElem,
15121513
whereClause,
1513-
mgens
1514+
mgensScratch
15141515
);
15151516
if (simplifiedGenerics) {
15161517
if (!fnTypesScratch) {
@@ -1520,7 +1521,7 @@ function initSearch(rawSearchIndex) {
15201521
simplifiedGenerics,
15211522
queryElem.generics,
15221523
whereClause,
1523-
mgens,
1524+
mgensScratch,
15241525
mgensScratch => {
15251526
matchCandidates.push({
15261527
fnTypesScratch,
@@ -1596,7 +1597,7 @@ function initSearch(rawSearchIndex) {
15961597
*
15971598
* @param {FunctionType} fnType
15981599
* @param {QueryElement} queryElem
1599-
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
1600+
* @param {[FunctionSearchType]} whereClause - Trait bounds for generic items.
16001601
* @param {Map<number,number>|null} mgensIn - Map functions generics to query generics.
16011602
* @returns {boolean}
16021603
*/
@@ -1686,10 +1687,11 @@ function initSearch(rawSearchIndex) {
16861687
* @param {FunctionType} fnType
16871688
* @param {QueryElement} queryElem
16881689
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
1689-
* @param {Map<number,number>|null} mgensIn - Map functions generics to query generics.
1690+
* @param {Map<number,number>|null} mgensInout - Map functions generics to query generics.
1691+
* Written on success.
16901692
* @returns {boolean|FunctionType[]}
16911693
*/
1692-
function unifyFunctionTypeCheckBindings(fnType, queryElem, whereClause, mgensIn) {
1694+
function unifyFunctionTypeCheckBindings(fnType, queryElem, whereClause, mgensInout) {
16931695
// Simplify generics now
16941696
let simplifiedGenerics = fnType.generics;
16951697
if (!simplifiedGenerics) {
@@ -1699,17 +1701,24 @@ function initSearch(rawSearchIndex) {
16991701
return false;
17001702
}
17011703
if (fnType.bindings.size > 0) {
1704+
const mgensResults = new Map(mgensInout);
17021705
for (const [name, constraints] of queryElem.bindings.entries()) {
17031706
if (!fnType.bindings.has(name)) {
17041707
return false;
17051708
}
17061709
// Since both items must have exactly one entry per name,
1707-
// we don't need to backtrack here.
1710+
// we don't need to backtrack here, but do need to write mgens.
17081711
if (!unifyFunctionTypes(
17091712
fnType.bindings.get(name),
17101713
constraints,
17111714
whereClause,
1712-
mgensIn
1715+
mgensResults,
1716+
mgens => {
1717+
for (const [fid, qid] of mgens.entries()) {
1718+
mgensResults.set(fid, qid);
1719+
}
1720+
return true;
1721+
}
17131722
)) {
17141723
return false;
17151724
}
@@ -1727,6 +1736,11 @@ function initSearch(rawSearchIndex) {
17271736
} else {
17281737
simplifiedGenerics = binds;
17291738
}
1739+
if (mgensInout) {
1740+
for (const [fid, qid] of mgensResults.entries()) {
1741+
mgensInout.set(fid, qid);
1742+
}
1743+
}
17301744
}
17311745
return simplifiedGenerics;
17321746
}
Lines changed: 66 additions & 0 deletions
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+
];
Lines changed: 27 additions & 0 deletions
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)