@@ -1506,33 +1506,36 @@ 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 ) ;
1510- const simplifiedGenerics = unifyFunctionTypeCheckBindings (
1509+ const solution = unifyFunctionTypeCheckBindings (
15111510 fnType ,
15121511 queryElem ,
15131512 whereClause ,
1514- mgensScratch
1513+ mgens
15151514 ) ;
1516- if ( simplifiedGenerics ) {
1515+ if ( solution ) {
15171516 if ( ! fnTypesScratch ) {
15181517 fnTypesScratch = fnTypes . slice ( ) ;
15191518 }
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+ }
15361539 }
15371540 }
15381541 if ( unifyFunctionTypeIsUnboxCandidate ( fnType , queryElem , whereClause , mgens ) ) {
@@ -1687,41 +1690,44 @@ function initSearch(rawSearchIndex) {
16871690 * @param {FunctionType } fnType
16881691 * @param {QueryElement } queryElem
16891692 * @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]} }
16931696 */
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 ) {
17001698 if ( fnType . bindings . size < queryElem . bindings . size ) {
17011699 return false ;
17021700 }
1701+ let simplifiedGenerics = fnType . generics || [ ] ;
17031702 if ( fnType . bindings . size > 0 ) {
1704- const mgensResults = new Map ( mgensInout ) ;
1703+ let mgensSolutionSet = [ mgensIn ] ;
17051704 for ( const [ name , constraints ] of queryElem . bindings . entries ( ) ) {
1706- if ( ! fnType . bindings . has ( name ) ) {
1705+ if ( mgensSolutionSet . length === 0 ) {
17071706 return false ;
17081707 }
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 ) ) {
17231709 return false ;
17241710 }
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 ;
17251731 }
17261732 const binds = Array . from ( fnType . bindings . entries ( ) ) . flatMap ( entry => {
17271733 const [ name , constraints ] = entry ;
@@ -1736,13 +1742,9 @@ function initSearch(rawSearchIndex) {
17361742 } else {
17371743 simplifiedGenerics = binds ;
17381744 }
1739- if ( mgensInout ) {
1740- for ( const [ fid , qid ] of mgensResults . entries ( ) ) {
1741- mgensInout . set ( fid , qid ) ;
1742- }
1743- }
1745+ return { simplifiedGenerics, mgens : mgensSolutionSet } ;
17441746 }
1745- return simplifiedGenerics ;
1747+ return { simplifiedGenerics, mgens : [ mgensIn ] } ;
17461748 }
17471749 /**
17481750 * @param {FunctionType } fnType
@@ -1766,7 +1768,7 @@ function initSearch(rawSearchIndex) {
17661768 // `fn read_all<R: Read>(R) -> Result<usize>`
17671769 // generic `R` is considered "unboxed"
17681770 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 ) {
17701772 const simplifiedGenerics = [
17711773 ...fnType . generics ,
17721774 ...Array . from ( fnType . bindings . values ( ) ) . flat ( ) ,
0 commit comments