about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbinarycat <binarycat@envs.net>2024-11-03 13:17:39 -0600
committerbinarycat <binarycat@envs.net>2024-11-15 16:32:40 -0600
commitcd46ff6c052421277a7a3548b4fe40be4973feb1 (patch)
tree724b164c4f05e504f9835550e220a9cc56f3ce8e
parentce40196577ecc0b72f6de7e2c8e43fdc728fb69a (diff)
downloadrust-cd46ff6c052421277a7a3548b4fe40be4973feb1.tar.gz
rust-cd46ff6c052421277a7a3548b4fe40be4973feb1.zip
rustdoc search: allow queries to end in an empty path segment
fixes https://github.com/rust-lang/rust/issues/129707

this can be used to show all items in a module,
or all associated items for a type.
currently sufferes slightly due to case insensitivity,
so `Option::` will also show items in the `option::` module.

it disables the checking of the last path element,
otherwise only items with short names will be shown
-rw-r--r--src/librustdoc/html/static/js/search.js20
-rw-r--r--tests/rustdoc-js-std/parser-errors.js8
-rw-r--r--tests/rustdoc-js-std/path-end-empty.js6
3 files changed, 21 insertions, 13 deletions
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 6d118ae5784..c1a021e9f8d 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -692,8 +692,6 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
     const quadcolon = /::\s*::/.exec(path);
     if (path.startsWith("::")) {
         throw ["Paths cannot start with ", "::"];
-    } else if (path.endsWith("::")) {
-        throw ["Paths cannot end with ", "::"];
     } else if (quadcolon !== null) {
         throw ["Unexpected ", quadcolon[0]];
     }
@@ -3974,18 +3972,19 @@ class DocSearch {
 
             if (parsedQuery.foundElems === 1 && !parsedQuery.hasReturnArrow) {
                 const elem = parsedQuery.elems[0];
-                for (const id of this.nameTrie.search(elem.normalizedPathLast, this.tailTable)) {
+                // use arrow functions to preserve `this`.
+                const handleNameSearch = id => {
                     const row = this.searchIndex[id];
                     if (!typePassesFilter(elem.typeFilter, row.ty) ||
                         (filterCrates !== null && row.crate !== filterCrates)) {
-                        continue;
+                        return;
                     }
 
                     let pathDist = 0;
                     if (elem.fullPath.length > 1) {
                         pathDist = checkPath(elem.pathWithoutLast, row);
                         if (pathDist === null) {
-                            continue;
+                            return;
                         }
                     }
 
@@ -4008,9 +4007,20 @@ class DocSearch {
                             maxEditDistance,
                         );
                     }
+                };
+                if (elem.normalizedPathLast !== "") {
+                    const last = elem.normalizedPathLast;
+                    for (const id of this.nameTrie.search(last, this.tailTable)) {
+                        handleNameSearch(id);
+                    }
                 }
                 const length = this.searchIndex.length;
+
                 for (let i = 0, nSearchIndex = length; i < nSearchIndex; ++i) {
+                    // queries that end in :: bypass the trie
+                    if (elem.normalizedPathLast === "") {
+                        handleNameSearch(i);
+                    }
                     const row = this.searchIndex[i];
                     if (filterCrates !== null && row.crate !== filterCrates) {
                         continue;
diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js
index 068298e7236..8bffef61c8f 100644
--- a/tests/rustdoc-js-std/parser-errors.js
+++ b/tests/rustdoc-js-std/parser-errors.js
@@ -144,14 +144,6 @@ const PARSED = [
         error: "Unexpected `:: ::`",
     },
     {
-        query: "a::b::",
-        elems: [],
-        foundElems: 0,
-        userQuery: "a::b::",
-        returned: [],
-        error: "Paths cannot end with `::`",
-    },
-    {
         query: ":a",
         elems: [],
         foundElems: 0,
diff --git a/tests/rustdoc-js-std/path-end-empty.js b/tests/rustdoc-js-std/path-end-empty.js
new file mode 100644
index 00000000000..6e853c61b4d
--- /dev/null
+++ b/tests/rustdoc-js-std/path-end-empty.js
@@ -0,0 +1,6 @@
+const EXPECTED = {
+    'query': 'Option::',
+    'others': [
+        { 'path': 'std::option::Option', 'name': 'get_or_insert_default' },
+    ],
+}