@@ -260,6 +260,18 @@ function initSearch(rawSearchIndex) {
260
260
* Special type name IDs for searching by both array and slice (`[]` syntax).
261
261
*/
262
262
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 ;
263
275
264
276
/**
265
277
* Add an item to the type Name->ID map, or, if one already exists, use it.
@@ -296,17 +308,13 @@ function initSearch(rawSearchIndex) {
296
308
}
297
309
298
310
function isEndCharacter ( c ) {
299
- return "=,>-]" . indexOf ( c ) !== - 1 ;
311
+ return "=,>-]) " . indexOf ( c ) !== - 1 ;
300
312
}
301
313
302
314
function isStopCharacter ( c ) {
303
315
return isEndCharacter ( c ) ;
304
316
}
305
317
306
- function isErrorCharacter ( c ) {
307
- return "()" . indexOf ( c ) !== - 1 ;
308
- }
309
-
310
318
function itemTypeFromName ( typename ) {
311
319
const index = itemTypes . findIndex ( i => i === typename ) ;
312
320
if ( index < 0 ) {
@@ -592,8 +600,6 @@ function initSearch(rawSearchIndex) {
592
600
throw [ "Unexpected " , "!" , ": it can only be at the end of an ident" ] ;
593
601
}
594
602
foundExclamation = parserState . pos ;
595
- } else if ( isErrorCharacter ( c ) ) {
596
- throw [ "Unexpected " , c ] ;
597
603
} else if ( isPathSeparator ( c ) ) {
598
604
if ( c === ":" ) {
599
605
if ( ! isPathStart ( parserState ) ) {
@@ -623,6 +629,7 @@ function initSearch(rawSearchIndex) {
623
629
}
624
630
} else if (
625
631
c === "[" ||
632
+ c === "(" ||
626
633
c === "=" ||
627
634
isStopCharacter ( c ) ||
628
635
isSpecialStartCharacter ( c ) ||
@@ -669,42 +676,49 @@ function initSearch(rawSearchIndex) {
669
676
skipWhitespace ( parserState ) ;
670
677
let start = parserState . pos ;
671
678
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" ;
673
683
parserState . pos += 1 ;
674
- getItemsBefore ( query , parserState , generics , "]" ) ;
684
+ const { foundSeparator } = getItemsBefore ( query , parserState , generics , endChar ) ;
675
685
const typeFilter = parserState . typeFilter ;
676
686
const isInBinding = parserState . isInBinding ;
677
687
if ( typeFilter !== null && typeFilter !== "primitive" ) {
678
688
throw [
679
689
"Invalid search type: primitive " ,
680
- "[]" ,
690
+ name ,
681
691
" and " ,
682
692
typeFilter ,
683
693
" both specified" ,
684
694
] ;
685
695
}
686
696
parserState . typeFilter = null ;
687
697
parserState . isInBinding = null ;
688
- parserState . totalElems += 1 ;
689
- if ( isInGenerics ) {
690
- parserState . genericsElems += 1 ;
691
- }
692
698
for ( const gen of generics ) {
693
699
if ( gen . bindingName !== null ) {
694
- throw [ "Type parameter " , "=" , " cannot be within slice " , "[]" ] ;
700
+ throw [ "Type parameter " , "=" , ` cannot be within ${ friendlyName } ` , name ] ;
695
701
}
696
702
}
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
+ }
708
722
} else {
709
723
const isStringElem = parserState . userQuery [ start ] === "\"" ;
710
724
// We handle the strings on their own mostly to make code easier to follow.
@@ -777,9 +791,11 @@ function initSearch(rawSearchIndex) {
777
791
* @param {Array<QueryElement> } elems - This is where the new {QueryElement} will be added.
778
792
* @param {string } endChar - This function will stop when it'll encounter this
779
793
* character.
794
+ * @returns {{foundSeparator: bool} }
780
795
*/
781
796
function getItemsBefore ( query , parserState , elems , endChar ) {
782
797
let foundStopChar = true ;
798
+ let foundSeparator = false ;
783
799
let start = parserState . pos ;
784
800
785
801
// If this is a generic, keep the outer item's type filter around.
@@ -793,6 +809,8 @@ function initSearch(rawSearchIndex) {
793
809
extra = "<" ;
794
810
} else if ( endChar === "]" ) {
795
811
extra = "[" ;
812
+ } else if ( endChar === ")" ) {
813
+ extra = "(" ;
796
814
} else if ( endChar === "" ) {
797
815
extra = "->" ;
798
816
} else {
@@ -809,6 +827,7 @@ function initSearch(rawSearchIndex) {
809
827
} else if ( isSeparatorCharacter ( c ) ) {
810
828
parserState . pos += 1 ;
811
829
foundStopChar = true ;
830
+ foundSeparator = true ;
812
831
continue ;
813
832
} else if ( c === ":" && isPathStart ( parserState ) ) {
814
833
throw [ "Unexpected " , "::" , ": paths cannot start with " , "::" ] ;
@@ -886,6 +905,8 @@ function initSearch(rawSearchIndex) {
886
905
887
906
parserState . typeFilter = oldTypeFilter ;
888
907
parserState . isInBinding = oldIsInBinding ;
908
+
909
+ return { foundSeparator } ;
889
910
}
890
911
891
912
/**
@@ -1625,6 +1646,11 @@ function initSearch(rawSearchIndex) {
1625
1646
) {
1626
1647
// [] matches primitive:array or primitive:slice
1627
1648
// 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
1628
1654
} else if ( fnType . id !== queryElem . id || queryElem . id === null ) {
1629
1655
return false ;
1630
1656
}
@@ -1807,7 +1833,7 @@ function initSearch(rawSearchIndex) {
1807
1833
if ( row . id > 0 && elem . id > 0 && elem . pathWithoutLast . length === 0 &&
1808
1834
typePassesFilter ( elem . typeFilter , row . ty ) && elem . generics . length === 0 &&
1809
1835
// special case
1810
- elem . id !== typeNameIdOfArrayOrSlice
1836
+ elem . id !== typeNameIdOfArrayOrSlice && elem . id !== typeNameIdOfTupleOrUnit
1811
1837
) {
1812
1838
return row . id === elem . id || checkIfInList ( row . generics , elem , whereClause ) ;
1813
1839
}
@@ -2861,7 +2887,10 @@ ${item.displayPath}<span class="${type}">${name}</span>\
2861
2887
// that can be searched using `[]` syntax.
2862
2888
typeNameIdOfArray = buildTypeMapIndex ( "array" ) ;
2863
2889
typeNameIdOfSlice = buildTypeMapIndex ( "slice" ) ;
2890
+ typeNameIdOfTuple = buildTypeMapIndex ( "tuple" ) ;
2891
+ typeNameIdOfUnit = buildTypeMapIndex ( "unit" ) ;
2864
2892
typeNameIdOfArrayOrSlice = buildTypeMapIndex ( "[]" ) ;
2893
+ typeNameIdOfTupleOrUnit = buildTypeMapIndex ( "()" ) ;
2865
2894
2866
2895
for ( const crate in rawSearchIndex ) {
2867
2896
if ( ! hasOwnPropertyRustdoc ( rawSearchIndex , crate ) ) {
0 commit comments