@@ -260,6 +260,18 @@ function initSearch(rawSearchIndex) {
260260 * Special type name IDs for searching by both array and slice (`[]` syntax).
261261 */
262262 let typeNameIdOfArrayOrSlice ;
263+ /**
264+ * Special type name IDs for searching by tuple.
265+ */
266+ let typeNameIdOfTuple ;
267+ /**
268+ * Special type name IDs for searching by unit.
269+ */
270+ let typeNameIdOfUnit ;
271+ /**
272+ * Special type name IDs for searching by both tuple and unit (`()` syntax).
273+ */
274+ let typeNameIdOfTupleOrUnit ;
263275
264276 /**
265277 * Add an item to the type Name->ID map, or, if one already exists, use it.
@@ -296,17 +308,13 @@ function initSearch(rawSearchIndex) {
296308 }
297309
298310 function isEndCharacter ( c ) {
299- return "=,>-]" . indexOf ( c ) !== - 1 ;
311+ return "=,>-]) " . indexOf ( c ) !== - 1 ;
300312 }
301313
302314 function isStopCharacter ( c ) {
303315 return isEndCharacter ( c ) ;
304316 }
305317
306- function isErrorCharacter ( c ) {
307- return "()" . indexOf ( c ) !== - 1 ;
308- }
309-
310318 function itemTypeFromName ( typename ) {
311319 const index = itemTypes . findIndex ( i => i === typename ) ;
312320 if ( index < 0 ) {
@@ -592,8 +600,6 @@ function initSearch(rawSearchIndex) {
592600 throw [ "Unexpected " , "!" , ": it can only be at the end of an ident" ] ;
593601 }
594602 foundExclamation = parserState . pos ;
595- } else if ( isErrorCharacter ( c ) ) {
596- throw [ "Unexpected " , c ] ;
597603 } else if ( isPathSeparator ( c ) ) {
598604 if ( c === ":" ) {
599605 if ( ! isPathStart ( parserState ) ) {
@@ -623,6 +629,7 @@ function initSearch(rawSearchIndex) {
623629 }
624630 } else if (
625631 c === "[" ||
632+ c === "(" ||
626633 c === "=" ||
627634 isStopCharacter ( c ) ||
628635 isSpecialStartCharacter ( c ) ||
@@ -669,42 +676,49 @@ function initSearch(rawSearchIndex) {
669676 skipWhitespace ( parserState ) ;
670677 let start = parserState . pos ;
671678 let end ;
672- if ( parserState . userQuery [ parserState . pos ] === "[" ) {
679+ if ( "[(" . indexOf ( parserState . userQuery [ parserState . pos ] ) !== - 1 ) {
680+ const endChar = parserState . userQuery [ parserState . pos ] === "[" ? "]" : ")" ;
681+ const name = parserState . userQuery [ parserState . pos ] === "[" ? "[]" : "()" ;
682+ const friendlyName = parserState . userQuery [ parserState . pos ] === "[" ? "slice" : "tuple" ;
673683 parserState . pos += 1 ;
674- getItemsBefore ( query , parserState , generics , "]" ) ;
684+ const { foundSeparator } = getItemsBefore ( query , parserState , generics , endChar ) ;
675685 const typeFilter = parserState . typeFilter ;
676686 const isInBinding = parserState . isInBinding ;
677687 if ( typeFilter !== null && typeFilter !== "primitive" ) {
678688 throw [
679689 "Invalid search type: primitive " ,
680- "[]" ,
690+ name ,
681691 " and " ,
682692 typeFilter ,
683693 " both specified" ,
684694 ] ;
685695 }
686696 parserState . typeFilter = null ;
687697 parserState . isInBinding = null ;
688- parserState . totalElems += 1 ;
689- if ( isInGenerics ) {
690- parserState . genericsElems += 1 ;
691- }
692698 for ( const gen of generics ) {
693699 if ( gen . bindingName !== null ) {
694- throw [ "Type parameter " , "=" , " cannot be within slice " , "[]" ] ;
700+ throw [ "Type parameter " , "=" , ` cannot be within ${ friendlyName } ` , name ] ;
695701 }
696702 }
697- elems . push ( {
698- name : "[]" ,
699- id : null ,
700- fullPath : [ "[]" ] ,
701- pathWithoutLast : [ ] ,
702- pathLast : "[]" ,
703- generics,
704- typeFilter : "primitive" ,
705- bindingName : isInBinding ,
706- bindings : new Map ( ) ,
707- } ) ;
703+ if ( name === "()" && ! foundSeparator && generics . length === 1 && typeFilter === null ) {
704+ elems . push ( generics [ 0 ] ) ;
705+ } else {
706+ parserState . totalElems += 1 ;
707+ if ( isInGenerics ) {
708+ parserState . genericsElems += 1 ;
709+ }
710+ elems . push ( {
711+ name : name ,
712+ id : null ,
713+ fullPath : [ name ] ,
714+ pathWithoutLast : [ ] ,
715+ pathLast : name ,
716+ generics,
717+ bindings : new Map ( ) ,
718+ typeFilter : "primitive" ,
719+ bindingName : isInBinding ,
720+ } ) ;
721+ }
708722 } else {
709723 const isStringElem = parserState . userQuery [ start ] === "\"" ;
710724 // We handle the strings on their own mostly to make code easier to follow.
@@ -777,9 +791,11 @@ function initSearch(rawSearchIndex) {
777791 * @param {Array<QueryElement> } elems - This is where the new {QueryElement} will be added.
778792 * @param {string } endChar - This function will stop when it'll encounter this
779793 * character.
794+ * @returns {{foundSeparator: bool} }
780795 */
781796 function getItemsBefore ( query , parserState , elems , endChar ) {
782797 let foundStopChar = true ;
798+ let foundSeparator = false ;
783799 let start = parserState . pos ;
784800
785801 // If this is a generic, keep the outer item's type filter around.
@@ -793,6 +809,8 @@ function initSearch(rawSearchIndex) {
793809 extra = "<" ;
794810 } else if ( endChar === "]" ) {
795811 extra = "[" ;
812+ } else if ( endChar === ")" ) {
813+ extra = "(" ;
796814 } else if ( endChar === "" ) {
797815 extra = "->" ;
798816 } else {
@@ -809,6 +827,7 @@ function initSearch(rawSearchIndex) {
809827 } else if ( isSeparatorCharacter ( c ) ) {
810828 parserState . pos += 1 ;
811829 foundStopChar = true ;
830+ foundSeparator = true ;
812831 continue ;
813832 } else if ( c === ":" && isPathStart ( parserState ) ) {
814833 throw [ "Unexpected " , "::" , ": paths cannot start with " , "::" ] ;
@@ -886,6 +905,8 @@ function initSearch(rawSearchIndex) {
886905
887906 parserState . typeFilter = oldTypeFilter ;
888907 parserState . isInBinding = oldIsInBinding ;
908+
909+ return { foundSeparator } ;
889910 }
890911
891912 /**
@@ -1625,6 +1646,11 @@ function initSearch(rawSearchIndex) {
16251646 ) {
16261647 // [] matches primitive:array or primitive:slice
16271648 // if it matches, then we're fine, and this is an appropriate match candidate
1649+ } else if ( queryElem . id === typeNameIdOfTupleOrUnit &&
1650+ ( fnType . id === typeNameIdOfTuple || fnType . id === typeNameIdOfUnit )
1651+ ) {
1652+ // () matches primitive:tuple or primitive:unit
1653+ // if it matches, then we're fine, and this is an appropriate match candidate
16281654 } else if ( fnType . id !== queryElem . id || queryElem . id === null ) {
16291655 return false ;
16301656 }
@@ -1807,7 +1833,7 @@ function initSearch(rawSearchIndex) {
18071833 if ( row . id > 0 && elem . id > 0 && elem . pathWithoutLast . length === 0 &&
18081834 typePassesFilter ( elem . typeFilter , row . ty ) && elem . generics . length === 0 &&
18091835 // special case
1810- elem . id !== typeNameIdOfArrayOrSlice
1836+ elem . id !== typeNameIdOfArrayOrSlice && elem . id !== typeNameIdOfTupleOrUnit
18111837 ) {
18121838 return row . id === elem . id || checkIfInList ( row . generics , elem , whereClause ) ;
18131839 }
@@ -2861,7 +2887,10 @@ ${item.displayPath}<span class="${type}">${name}</span>\
28612887 // that can be searched using `[]` syntax.
28622888 typeNameIdOfArray = buildTypeMapIndex ( "array" ) ;
28632889 typeNameIdOfSlice = buildTypeMapIndex ( "slice" ) ;
2890+ typeNameIdOfTuple = buildTypeMapIndex ( "tuple" ) ;
2891+ typeNameIdOfUnit = buildTypeMapIndex ( "unit" ) ;
28642892 typeNameIdOfArrayOrSlice = buildTypeMapIndex ( "[]" ) ;
2893+ typeNameIdOfTupleOrUnit = buildTypeMapIndex ( "()" ) ;
28652894
28662895 for ( const crate in rawSearchIndex ) {
28672896 if ( ! hasOwnPropertyRustdoc ( rawSearchIndex , crate ) ) {
0 commit comments