about summary refs log tree commit diff
path: root/src/librustdoc/html
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2023-06-12 14:56:54 -0700
committerMichael Howell <michael@notriddle.com>2023-06-12 17:30:23 -0700
commitdb277f528407864e24d3d7934d9c23e28d950165 (patch)
tree27f6edb2a3b0e81f6e3265af83b2cd19ba4993fe /src/librustdoc/html
parentdf77afbcaf3365a32066a8ca4a00ae6fc9a69647 (diff)
downloadrust-db277f528407864e24d3d7934d9c23e28d950165.tar.gz
rust-db277f528407864e24d3d7934d9c23e28d950165.zip
rustdoc-search: search never type with `!`
This feature extends rustdoc to support the syntax that most users will
naturally attempt to use to search for diverging functions.
Part of #60485

It's already possible to do this search with `primitive:never`, but
that's not what the Rust language itself uses, so nobody will try it if
they aren't told or helped along.
Diffstat (limited to 'src/librustdoc/html')
-rw-r--r--src/librustdoc/html/static/js/search.js48
1 files changed, 43 insertions, 5 deletions
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 984358396ab..1ccfca8d0d5 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -386,6 +386,35 @@ function initSearch(rawSearchIndex) {
         if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) {
             throw ["You cannot have more than one element if you use quotes"];
         }
+        const typeFilter = parserState.typeFilter;
+        parserState.typeFilter = null;
+        if (name === "!") {
+            if (typeFilter !== null && typeFilter !== "primitive") {
+                throw [
+                    "Invalid search type: primitive never type ",
+                    "!",
+                    " and ",
+                    typeFilter,
+                    " both specified",
+                ];
+            }
+            if (generics.length !== 0) {
+                throw [
+                    "Never type ",
+                    "!",
+                    " does not accept generic parameters",
+                ];
+            }
+            return {
+                name: "never",
+                id: -1,
+                fullPath: ["never"],
+                pathWithoutLast: [],
+                pathLast: "never",
+                generics: [],
+                typeFilter: "primitive",
+            };
+        }
         const pathSegments = name.split("::");
         if (pathSegments.length > 1) {
             for (let i = 0, len = pathSegments.length; i < len; ++i) {
@@ -399,6 +428,13 @@ function initSearch(rawSearchIndex) {
                     }
                     throw ["Unexpected ", "::::"];
                 }
+
+                if (pathSegment === "!") {
+                    pathSegments[i] = "never";
+                    if (i !== 0) {
+                        throw ["Never type ", "!", " is not associated item"];
+                    }
+                }
             }
         }
         // In case we only have something like `<p>`, there is no name.
@@ -409,8 +445,6 @@ function initSearch(rawSearchIndex) {
         if (isInGenerics) {
             parserState.genericsElems += 1;
         }
-        const typeFilter = parserState.typeFilter;
-        parserState.typeFilter = null;
         return {
             name: name,
             id: -1,
@@ -459,10 +493,11 @@ function initSearch(rawSearchIndex) {
                         break;
                     }
                     if (foundExclamation !== -1) {
-                        if (start <= (end - 2)) {
+                        if (foundExclamation !== start &&
+                            isIdentCharacter(parserState.userQuery[foundExclamation - 1])
+                        ) {
                             throw ["Cannot have associated items in macros"];
                         } else {
-                            // if start == end - 1, we got the never type
                             // while the never type has no associated macros, we still
                             // can parse a path like that
                             foundExclamation = -1;
@@ -478,7 +513,10 @@ function initSearch(rawSearchIndex) {
             end = parserState.pos;
         }
         // if start == end - 1, we got the never type
-        if (foundExclamation !== -1 && start <= (end - 2)) {
+        if (foundExclamation !== -1 &&
+            foundExclamation !== start &&
+            isIdentCharacter(parserState.userQuery[foundExclamation - 1])
+        ) {
             if (parserState.typeFilter === null) {
                 parserState.typeFilter = "macro";
             } else if (parserState.typeFilter !== "macro") {