@@ -1389,29 +1389,35 @@ function initSearch(rawSearchIndex) {
1389
1389
* @return {boolean } - Returns true if a match, false otherwise.
1390
1390
*/
1391
1391
function checkGenerics ( fnType , queryElem , whereClause , mgensInout ) {
1392
- const simplifiedGenerics = unifyFunctionTypeCheckBindings (
1392
+ const solutions = unifyFunctionTypeCheckBindings (
1393
1393
fnType ,
1394
1394
queryElem ,
1395
1395
whereClause ,
1396
1396
mgensInout
1397
1397
) ;
1398
- if ( ! simplifiedGenerics ) {
1398
+ if ( ! solutions ) {
1399
1399
return false ;
1400
1400
}
1401
- return unifyFunctionTypes (
1402
- simplifiedGenerics ,
1403
- queryElem . generics ,
1404
- whereClause ,
1405
- mgensInout ,
1406
- mgens => {
1407
- if ( mgensInout ) {
1408
- for ( const [ fid , qid ] of mgens . entries ( ) ) {
1409
- mgensInout . set ( fid , qid ) ;
1401
+ const simplifiedGenerics = solutions . simplifiedGenerics ;
1402
+ for ( const mgens of solutions . mgens ) {
1403
+ if ( unifyFunctionTypes (
1404
+ simplifiedGenerics ,
1405
+ queryElem . generics ,
1406
+ whereClause ,
1407
+ mgens ,
1408
+ mgens => {
1409
+ if ( mgensInout ) {
1410
+ for ( const [ fid , qid ] of mgens . entries ( ) ) {
1411
+ mgensInout . set ( fid , qid ) ;
1412
+ }
1410
1413
}
1414
+ return true ;
1411
1415
}
1416
+ ) ) {
1412
1417
return true ;
1413
1418
}
1414
- ) ;
1419
+ }
1420
+ return false ;
1415
1421
}
1416
1422
/**
1417
1423
* This function checks if a list of search query `queryElems` can all be found in the
@@ -1545,33 +1551,36 @@ function initSearch(rawSearchIndex) {
1545
1551
for ( j = i ; j !== fl ; ++ j ) {
1546
1552
const fnType = fnTypes [ j ] ;
1547
1553
if ( unifyFunctionTypeIsMatchCandidate ( fnType , queryElem , whereClause , mgens ) ) {
1548
- const mgensScratch = new Map ( mgens ) ;
1549
- const simplifiedGenerics = unifyFunctionTypeCheckBindings (
1554
+ const solution = unifyFunctionTypeCheckBindings (
1550
1555
fnType ,
1551
1556
queryElem ,
1552
1557
whereClause ,
1553
- mgensScratch
1558
+ mgens
1554
1559
) ;
1555
- if ( simplifiedGenerics ) {
1560
+ if ( solution ) {
1556
1561
if ( ! fnTypesScratch ) {
1557
1562
fnTypesScratch = fnTypes . slice ( ) ;
1558
1563
}
1559
- unifyFunctionTypes (
1560
- simplifiedGenerics ,
1561
- queryElem . generics ,
1562
- whereClause ,
1563
- mgensScratch ,
1564
- mgensScratch => {
1565
- matchCandidates . push ( {
1566
- fnTypesScratch,
1567
- mgensScratch,
1568
- queryElemsOffset : i ,
1569
- fnTypesOffset : j ,
1570
- unbox : false ,
1571
- } ) ;
1572
- return false ; // "reject" all candidates to gather all of them
1573
- }
1574
- ) ;
1564
+ const simplifiedGenerics = solution . simplifiedGenerics ;
1565
+ for ( const solutionMgens of solution . mgens ) {
1566
+ unifyFunctionTypes (
1567
+ simplifiedGenerics ,
1568
+ queryElem . generics ,
1569
+ whereClause ,
1570
+ solutionMgens ,
1571
+ mgensScratch => {
1572
+ matchCandidates . push ( {
1573
+ fnTypesScratch,
1574
+ mgensScratch,
1575
+ queryElemsOffset : i ,
1576
+ fnTypesOffset : j ,
1577
+ unbox : false ,
1578
+ } ) ;
1579
+ // "reject" all candidates to gather all of them
1580
+ return false ;
1581
+ }
1582
+ ) ;
1583
+ }
1575
1584
}
1576
1585
}
1577
1586
if ( unifyFunctionTypeIsUnboxCandidate ( fnType , queryElem , whereClause , mgens ) ) {
@@ -1726,41 +1735,44 @@ function initSearch(rawSearchIndex) {
1726
1735
* @param {FunctionType } fnType
1727
1736
* @param {QueryElement } queryElem
1728
1737
* @param {[FunctionType] } whereClause - Trait bounds for generic items.
1729
- * @param {Map<number,number>|null } mgensInout - Map functions generics to query generics.
1730
- * Written on success .
1731
- * @returns {boolean|FunctionType[] }
1738
+ * @param {Map<number,number> } mgensIn - Map functions generics to query generics.
1739
+ * Never modified .
1740
+ * @returns {false|{mgens: [Map<number,number>], simplifiedGenerics: [FunctionType]} }
1732
1741
*/
1733
- function unifyFunctionTypeCheckBindings ( fnType , queryElem , whereClause , mgensInout ) {
1734
- // Simplify generics now
1735
- let simplifiedGenerics = fnType . generics ;
1736
- if ( ! simplifiedGenerics ) {
1737
- simplifiedGenerics = [ ] ;
1738
- }
1742
+ function unifyFunctionTypeCheckBindings ( fnType , queryElem , whereClause , mgensIn ) {
1739
1743
if ( fnType . bindings . size < queryElem . bindings . size ) {
1740
1744
return false ;
1741
1745
}
1746
+ let simplifiedGenerics = fnType . generics || [ ] ;
1742
1747
if ( fnType . bindings . size > 0 ) {
1743
- const mgensResults = new Map ( mgensInout ) ;
1748
+ let mgensSolutionSet = [ mgensIn ] ;
1744
1749
for ( const [ name , constraints ] of queryElem . bindings . entries ( ) ) {
1745
- if ( ! fnType . bindings . has ( name ) ) {
1750
+ if ( mgensSolutionSet . length === 0 ) {
1746
1751
return false ;
1747
1752
}
1748
- // Since both items must have exactly one entry per name,
1749
- // we don't need to backtrack here, but do need to write mgens.
1750
- if ( ! unifyFunctionTypes (
1751
- fnType . bindings . get ( name ) ,
1752
- constraints ,
1753
- whereClause ,
1754
- mgensResults ,
1755
- mgens => {
1756
- for ( const [ fid , qid ] of mgens . entries ( ) ) {
1757
- mgensResults . set ( fid , qid ) ;
1758
- }
1759
- return true ;
1760
- }
1761
- ) ) {
1753
+ if ( ! fnType . bindings . has ( name ) ) {
1762
1754
return false ;
1763
1755
}
1756
+ const fnTypeBindings = fnType . bindings . get ( name ) ;
1757
+ mgensSolutionSet = mgensSolutionSet . flatMap ( mgens => {
1758
+ const newSolutions = [ ] ;
1759
+ unifyFunctionTypes (
1760
+ fnTypeBindings ,
1761
+ constraints ,
1762
+ whereClause ,
1763
+ mgens ,
1764
+ newMgens => {
1765
+ newSolutions . push ( newMgens ) ;
1766
+ // return `false` makes unifyFunctionTypes return the full set of
1767
+ // possible solutions
1768
+ return false ;
1769
+ }
1770
+ ) ;
1771
+ return newSolutions ;
1772
+ } ) ;
1773
+ }
1774
+ if ( mgensSolutionSet . length === 0 ) {
1775
+ return false ;
1764
1776
}
1765
1777
const binds = Array . from ( fnType . bindings . entries ( ) ) . flatMap ( entry => {
1766
1778
const [ name , constraints ] = entry ;
@@ -1775,13 +1787,9 @@ function initSearch(rawSearchIndex) {
1775
1787
} else {
1776
1788
simplifiedGenerics = binds ;
1777
1789
}
1778
- if ( mgensInout ) {
1779
- for ( const [ fid , qid ] of mgensResults . entries ( ) ) {
1780
- mgensInout . set ( fid , qid ) ;
1781
- }
1782
- }
1790
+ return { simplifiedGenerics, mgens : mgensSolutionSet } ;
1783
1791
}
1784
- return simplifiedGenerics ;
1792
+ return { simplifiedGenerics, mgens : [ mgensIn ] } ;
1785
1793
}
1786
1794
/**
1787
1795
* @param {FunctionType } fnType
@@ -1805,7 +1813,7 @@ function initSearch(rawSearchIndex) {
1805
1813
// `fn read_all<R: Read>(R) -> Result<usize>`
1806
1814
// generic `R` is considered "unboxed"
1807
1815
return checkIfInList ( whereClause [ ( - fnType . id ) - 1 ] , queryElem , whereClause ) ;
1808
- } else if ( fnType . generics . length > 0 || fnType . bindings . length > 0 ) {
1816
+ } else if ( fnType . generics . length > 0 || fnType . bindings . size > 0 ) {
1809
1817
const simplifiedGenerics = [
1810
1818
...fnType . generics ,
1811
1819
...Array . from ( fnType . bindings . values ( ) ) . flat ( ) ,
0 commit comments