@@ -1389,29 +1389,35 @@ function initSearch(rawSearchIndex) {
13891389 * @return {boolean } - Returns true if a match, false otherwise.
13901390 */
13911391 function checkGenerics ( fnType , queryElem , whereClause , mgensInout ) {
1392- const simplifiedGenerics = unifyFunctionTypeCheckBindings (
1392+ const solutions = unifyFunctionTypeCheckBindings (
13931393 fnType ,
13941394 queryElem ,
13951395 whereClause ,
13961396 mgensInout
13971397 ) ;
1398- if ( ! simplifiedGenerics ) {
1398+ if ( ! solutions ) {
13991399 return false ;
14001400 }
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+ }
14101413 }
1414+ return true ;
14111415 }
1416+ ) ) {
14121417 return true ;
14131418 }
1414- ) ;
1419+ }
1420+ return false ;
14151421 }
14161422 /**
14171423 * This function checks if a list of search query `queryElems` can all be found in the
@@ -1545,33 +1551,36 @@ function initSearch(rawSearchIndex) {
15451551 for ( j = i ; j !== fl ; ++ j ) {
15461552 const fnType = fnTypes [ j ] ;
15471553 if ( unifyFunctionTypeIsMatchCandidate ( fnType , queryElem , whereClause , mgens ) ) {
1548- const mgensScratch = new Map ( mgens ) ;
1549- const simplifiedGenerics = unifyFunctionTypeCheckBindings (
1554+ const solution = unifyFunctionTypeCheckBindings (
15501555 fnType ,
15511556 queryElem ,
15521557 whereClause ,
1553- mgensScratch
1558+ mgens
15541559 ) ;
1555- if ( simplifiedGenerics ) {
1560+ if ( solution ) {
15561561 if ( ! fnTypesScratch ) {
15571562 fnTypesScratch = fnTypes . slice ( ) ;
15581563 }
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+ }
15751584 }
15761585 }
15771586 if ( unifyFunctionTypeIsUnboxCandidate ( fnType , queryElem , whereClause , mgens ) ) {
@@ -1726,41 +1735,44 @@ function initSearch(rawSearchIndex) {
17261735 * @param {FunctionType } fnType
17271736 * @param {QueryElement } queryElem
17281737 * @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]} }
17321741 */
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 ) {
17391743 if ( fnType . bindings . size < queryElem . bindings . size ) {
17401744 return false ;
17411745 }
1746+ let simplifiedGenerics = fnType . generics || [ ] ;
17421747 if ( fnType . bindings . size > 0 ) {
1743- const mgensResults = new Map ( mgensInout ) ;
1748+ let mgensSolutionSet = [ mgensIn ] ;
17441749 for ( const [ name , constraints ] of queryElem . bindings . entries ( ) ) {
1745- if ( ! fnType . bindings . has ( name ) ) {
1750+ if ( mgensSolutionSet . length === 0 ) {
17461751 return false ;
17471752 }
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 ) ) {
17621754 return false ;
17631755 }
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 ;
17641776 }
17651777 const binds = Array . from ( fnType . bindings . entries ( ) ) . flatMap ( entry => {
17661778 const [ name , constraints ] = entry ;
@@ -1775,13 +1787,9 @@ function initSearch(rawSearchIndex) {
17751787 } else {
17761788 simplifiedGenerics = binds ;
17771789 }
1778- if ( mgensInout ) {
1779- for ( const [ fid , qid ] of mgensResults . entries ( ) ) {
1780- mgensInout . set ( fid , qid ) ;
1781- }
1782- }
1790+ return { simplifiedGenerics, mgens : mgensSolutionSet } ;
17831791 }
1784- return simplifiedGenerics ;
1792+ return { simplifiedGenerics, mgens : [ mgensIn ] } ;
17851793 }
17861794 /**
17871795 * @param {FunctionType } fnType
@@ -1805,7 +1813,7 @@ function initSearch(rawSearchIndex) {
18051813 // `fn read_all<R: Read>(R) -> Result<usize>`
18061814 // generic `R` is considered "unboxed"
18071815 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 ) {
18091817 const simplifiedGenerics = [
18101818 ...fnType . generics ,
18111819 ...Array . from ( fnType . bindings . values ( ) ) . flat ( ) ,
0 commit comments