@@ -1318,7 +1318,7 @@ function initSearch(rawSearchIndex) {
13181318 * then this function will try with a different solution, or bail with false if it
13191319 * runs out of candidates.
13201320 *
1321- * @param {Array<FunctionType> } fnTypes - The objects to check.
1321+ * @param {Array<FunctionType> } fnTypesIn - The objects to check.
13221322 * @param {Array<QueryElement> } queryElems - The elements from the parsed query.
13231323 * @param {[FunctionType] } whereClause - Trait bounds for generic items.
13241324 * @param {Map<number,number>|null } mgensIn
@@ -1340,6 +1340,79 @@ function initSearch(rawSearchIndex) {
13401340 }
13411341 const ql = queryElems . length ;
13421342 let fl = fnTypesIn . length ;
1343+
1344+ // Fast path
1345+ if ( queryElems . length === 1 && queryElems [ 0 ] . generics . length === 0 ) {
1346+ const queryElem = queryElems [ 0 ] ;
1347+ for ( const fnType of fnTypesIn ) {
1348+ if ( ! unifyFunctionTypeIsMatchCandidate ( fnType , queryElem , whereClause , mgens ) ) {
1349+ continue ;
1350+ }
1351+ if ( fnType . id < 0 && queryElem . id < 0 ) {
1352+ if ( mgens === null ) {
1353+ mgens = new Map ( ) ;
1354+ }
1355+ const alreadyAssigned = mgens . has ( fnType . id ) ;
1356+ if ( alreadyAssigned ) {
1357+ if ( mgens . get ( fnType . id ) !== queryElem . id ) {
1358+ continue ;
1359+ }
1360+ } else {
1361+ mgens . set ( fnType . id , queryElem . id ) ;
1362+ }
1363+ if ( ! solutionCb || solutionCb ( mgens ) ) {
1364+ return true ;
1365+ }
1366+ if ( ! alreadyAssigned ) {
1367+ mgens . delete ( fnType . id ) ;
1368+ }
1369+ } else if ( ! solutionCb || solutionCb ( mgens ) ) {
1370+ // unifyFunctionTypeIsMatchCandidate already checks that ids match
1371+ return true ;
1372+ }
1373+ }
1374+ for ( const fnType of fnTypesIn ) {
1375+ if ( ! unifyFunctionTypeIsUnboxCandidate ( fnType , queryElem , whereClause , mgens ) ) {
1376+ continue ;
1377+ }
1378+ if ( fnType . id < 0 ) {
1379+ if ( mgens === null ) {
1380+ mgens = new Map ( ) ;
1381+ }
1382+ const alreadyAssigned = mgens . has ( fnType . id ) ;
1383+ if ( alreadyAssigned ) {
1384+ if ( mgens . get ( fnType . id ) !== 0 ) {
1385+ continue ;
1386+ }
1387+ } else {
1388+ mgens . set ( fnType . id , 0 ) ;
1389+ }
1390+ if ( unifyFunctionTypes (
1391+ whereClause [ ( - fnType . id ) - 1 ] ,
1392+ queryElems ,
1393+ whereClause ,
1394+ mgens ,
1395+ solutionCb
1396+ ) ) {
1397+ return true ;
1398+ }
1399+ if ( ! alreadyAssigned ) {
1400+ mgens . delete ( fnType . id ) ;
1401+ }
1402+ } else if ( unifyFunctionTypes (
1403+ fnType . generics ,
1404+ queryElems ,
1405+ whereClause ,
1406+ mgens ,
1407+ solutionCb
1408+ ) ) {
1409+ return true ;
1410+ }
1411+ }
1412+ return false ;
1413+ }
1414+
1415+ // Slow path
13431416 /**
13441417 * @type Array<FunctionType>
13451418 */
@@ -1405,7 +1478,8 @@ function initSearch(rawSearchIndex) {
14051478 if ( fnType . id < 0 ) {
14061479 if ( mgens === null ) {
14071480 mgens = new Map ( ) ;
1408- } else if ( mgens . has ( fnType . id ) && mgens . get ( fnType . id ) !== queryElem . id ) {
1481+ } else if ( mgens . has ( fnType . id ) &&
1482+ mgens . get ( fnType . id ) !== queryElem . id ) {
14091483 continue ;
14101484 }
14111485 mgens . set ( fnType . id , queryElem . id ) ;
0 commit comments