@@ -1506,33 +1506,36 @@ function initSearch(rawSearchIndex) {
1506
1506
for ( j = i ; j !== fl ; ++ j ) {
1507
1507
const fnType = fnTypes [ j ] ;
1508
1508
if ( unifyFunctionTypeIsMatchCandidate ( fnType , queryElem , whereClause , mgens ) ) {
1509
- const mgensScratch = new Map ( mgens ) ;
1510
- const simplifiedGenerics = unifyFunctionTypeCheckBindings (
1509
+ const solution = unifyFunctionTypeCheckBindings (
1511
1510
fnType ,
1512
1511
queryElem ,
1513
1512
whereClause ,
1514
- mgensScratch
1513
+ mgens
1515
1514
) ;
1516
- if ( simplifiedGenerics ) {
1515
+ if ( solution ) {
1517
1516
if ( ! fnTypesScratch ) {
1518
1517
fnTypesScratch = fnTypes . slice ( ) ;
1519
1518
}
1520
- unifyFunctionTypes (
1521
- simplifiedGenerics ,
1522
- queryElem . generics ,
1523
- whereClause ,
1524
- mgensScratch ,
1525
- mgensScratch => {
1526
- matchCandidates . push ( {
1527
- fnTypesScratch,
1528
- mgensScratch,
1529
- queryElemsOffset : i ,
1530
- fnTypesOffset : j ,
1531
- unbox : false ,
1532
- } ) ;
1533
- return false ; // "reject" all candidates to gather all of them
1534
- }
1535
- ) ;
1519
+ const simplifiedGenerics = solution . simplifiedGenerics ;
1520
+ for ( const solutionMgens of solution . mgens ) {
1521
+ unifyFunctionTypes (
1522
+ simplifiedGenerics ,
1523
+ queryElem . generics ,
1524
+ whereClause ,
1525
+ solutionMgens ,
1526
+ mgensScratch => {
1527
+ matchCandidates . push ( {
1528
+ fnTypesScratch,
1529
+ mgensScratch,
1530
+ queryElemsOffset : i ,
1531
+ fnTypesOffset : j ,
1532
+ unbox : false ,
1533
+ } ) ;
1534
+ // "reject" all candidates to gather all of them
1535
+ return false ;
1536
+ }
1537
+ ) ;
1538
+ }
1536
1539
}
1537
1540
}
1538
1541
if ( unifyFunctionTypeIsUnboxCandidate ( fnType , queryElem , whereClause , mgens ) ) {
@@ -1687,41 +1690,44 @@ function initSearch(rawSearchIndex) {
1687
1690
* @param {FunctionType } fnType
1688
1691
* @param {QueryElement } queryElem
1689
1692
* @param {[FunctionType] } whereClause - Trait bounds for generic items.
1690
- * @param {Map<number,number>|null } mgensInout - Map functions generics to query generics.
1691
- * Written on success .
1692
- * @returns {boolean|FunctionType[] }
1693
+ * @param {Map<number,number> } mgensIn - Map functions generics to query generics.
1694
+ * Never modified .
1695
+ * @returns {false|{mgens: [Map<number,number>], simplifiedGenerics: [FunctionType]} }
1693
1696
*/
1694
- function unifyFunctionTypeCheckBindings ( fnType , queryElem , whereClause , mgensInout ) {
1695
- // Simplify generics now
1696
- let simplifiedGenerics = fnType . generics ;
1697
- if ( ! simplifiedGenerics ) {
1698
- simplifiedGenerics = [ ] ;
1699
- }
1697
+ function unifyFunctionTypeCheckBindings ( fnType , queryElem , whereClause , mgensIn ) {
1700
1698
if ( fnType . bindings . size < queryElem . bindings . size ) {
1701
1699
return false ;
1702
1700
}
1701
+ let simplifiedGenerics = fnType . generics || [ ] ;
1703
1702
if ( fnType . bindings . size > 0 ) {
1704
- const mgensResults = new Map ( mgensInout ) ;
1703
+ let mgensSolutionSet = [ mgensIn ] ;
1705
1704
for ( const [ name , constraints ] of queryElem . bindings . entries ( ) ) {
1706
- if ( ! fnType . bindings . has ( name ) ) {
1705
+ if ( mgensSolutionSet . length === 0 ) {
1707
1706
return false ;
1708
1707
}
1709
- // Since both items must have exactly one entry per name,
1710
- // we don't need to backtrack here, but do need to write mgens.
1711
- if ( ! unifyFunctionTypes (
1712
- fnType . bindings . get ( name ) ,
1713
- constraints ,
1714
- whereClause ,
1715
- mgensResults ,
1716
- mgens => {
1717
- for ( const [ fid , qid ] of mgens . entries ( ) ) {
1718
- mgensResults . set ( fid , qid ) ;
1719
- }
1720
- return true ;
1721
- }
1722
- ) ) {
1708
+ if ( ! fnType . bindings . has ( name ) ) {
1723
1709
return false ;
1724
1710
}
1711
+ const fnTypeBindings = fnType . bindings . get ( name ) ;
1712
+ mgensSolutionSet = mgensSolutionSet . flatMap ( mgens => {
1713
+ const newSolutions = [ ] ;
1714
+ unifyFunctionTypes (
1715
+ fnTypeBindings ,
1716
+ constraints ,
1717
+ whereClause ,
1718
+ mgens ,
1719
+ newMgens => {
1720
+ newSolutions . push ( newMgens ) ;
1721
+ // return `false` makes unifyFunctionTypes return the full set of
1722
+ // possible solutions
1723
+ return false ;
1724
+ }
1725
+ ) ;
1726
+ return newSolutions ;
1727
+ } ) ;
1728
+ }
1729
+ if ( mgensSolutionSet . length === 0 ) {
1730
+ return false ;
1725
1731
}
1726
1732
const binds = Array . from ( fnType . bindings . entries ( ) ) . flatMap ( entry => {
1727
1733
const [ name , constraints ] = entry ;
@@ -1736,13 +1742,9 @@ function initSearch(rawSearchIndex) {
1736
1742
} else {
1737
1743
simplifiedGenerics = binds ;
1738
1744
}
1739
- if ( mgensInout ) {
1740
- for ( const [ fid , qid ] of mgensResults . entries ( ) ) {
1741
- mgensInout . set ( fid , qid ) ;
1742
- }
1743
- }
1745
+ return { simplifiedGenerics, mgens : mgensSolutionSet } ;
1744
1746
}
1745
- return simplifiedGenerics ;
1747
+ return { simplifiedGenerics, mgens : [ mgensIn ] } ;
1746
1748
}
1747
1749
/**
1748
1750
* @param {FunctionType } fnType
@@ -1766,7 +1768,7 @@ function initSearch(rawSearchIndex) {
1766
1768
// `fn read_all<R: Read>(R) -> Result<usize>`
1767
1769
// generic `R` is considered "unboxed"
1768
1770
return checkIfInList ( whereClause [ ( - fnType . id ) - 1 ] , queryElem , whereClause ) ;
1769
- } else if ( fnType . generics . length > 0 || fnType . bindings . length > 0 ) {
1771
+ } else if ( fnType . generics . length > 0 || fnType . bindings . size > 0 ) {
1770
1772
const simplifiedGenerics = [
1771
1773
...fnType . generics ,
1772
1774
...Array . from ( fnType . bindings . values ( ) ) . flat ( ) ,
0 commit comments