about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2023-03-30 21:53:11 -0700
committerMichael Howell <michael@notriddle.com>2023-04-14 14:55:45 -0700
commitafee2411e3fd5c6e8b3301fa748a760e01615904 (patch)
treeacfe106f4aa933d1a4a76f5e1b9104924cfcec25
parent276fa294809e914b1d04192392d256814aa5ce1a (diff)
downloadrust-afee2411e3fd5c6e8b3301fa748a760e01615904.tar.gz
rust-afee2411e3fd5c6e8b3301fa748a760e01615904.zip
rustdoc-search: add support for nested generics
-rw-r--r--src/librustdoc/html/static/js/search.js21
-rw-r--r--tests/rustdoc-js-std/parser-generics.js124
-rw-r--r--tests/rustdoc-js/generics-nested.js33
-rw-r--r--tests/rustdoc-js/generics-nested.rs19
4 files changed, 184 insertions, 13 deletions
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 40cdc55bbc3..929dae81c8d 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -461,9 +461,7 @@ function initSearch(rawSearchIndex) {
         if (parserState.pos < parserState.length &&
             parserState.userQuery[parserState.pos] === "<"
         ) {
-            if (isInGenerics) {
-                throw ["Unexpected ", "<", " after ", "<"];
-            } else if (start >= end) {
+            if (start >= end) {
                 throw ["Found generics without a path"];
             }
             parserState.pos += 1;
@@ -765,13 +763,10 @@ function initSearch(rawSearchIndex) {
      * ident = *(ALPHA / DIGIT / "_")
      * path = ident *(DOUBLE-COLON ident) [!]
      * arg = [type-filter *WS COLON *WS] path [generics]
-     * arg-without-generic = [type-filter *WS COLON *WS] path
      * type-sep = COMMA/WS *(COMMA/WS)
      * nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep)
-     * nonempty-arg-list-without-generics = *(type-sep) arg-without-generic
-     *                                      *(type-sep arg-without-generic) *(type-sep)
-     * generics = OPEN-ANGLE-BRACKET [ nonempty-arg-list-without-generics ] *(type-sep)
-     *            CLOSE-ANGLE-BRACKET/EOF
+     * generics = OPEN-ANGLE-BRACKET [ nonempty-arg-list ] *(type-sep)
+     *            CLOSE-ANGLE-BRACKET
      * return-args = RETURN-ARROW *(type-sep) nonempty-arg-list
      *
      * exact-search = [type-filter *WS COLON] [ RETURN-ARROW ] *WS QUOTE ident QUOTE [ generics ]
@@ -1127,7 +1122,7 @@ function initSearch(rawSearchIndex) {
                         currentEntryElems = [];
                         elems.set(entry.name, currentEntryElems);
                     }
-                    currentEntryElems.push(entry.ty);
+                    currentEntryElems.push(entry);
                 }
                 // We need to find the type that matches the most to remove it in order
                 // to move forward.
@@ -1136,8 +1131,12 @@ function initSearch(rawSearchIndex) {
                         return false;
                     }
                     const matchElems = elems.get(generic.name);
-                    const matchIdx = matchElems.findIndex(tmp_elem =>
-                        typePassesFilter(generic.typeFilter, tmp_elem));
+                    const matchIdx = matchElems.findIndex(tmp_elem => {
+                        if (checkGenerics(tmp_elem, generic, 0, maxEditDistance) !== 0) {
+                            return false;
+                        }
+                        return typePassesFilter(generic.typeFilter, tmp_elem.ty);
+                    });
                     if (matchIdx === -1) {
                         return false;
                     }
diff --git a/tests/rustdoc-js-std/parser-generics.js b/tests/rustdoc-js-std/parser-generics.js
index c448d845acb..5a2266dbe36 100644
--- a/tests/rustdoc-js-std/parser-generics.js
+++ b/tests/rustdoc-js-std/parser-generics.js
@@ -1,4 +1,11 @@
-const QUERY = ['A<B<C<D>,  E>', 'p<> u8', '"p"<a>'];
+const QUERY = [
+    'A<B<C<D>,  E>',
+    'p<> u8',
+    '"p"<a>',
+    'p<u<x>>',
+    'p<u<x>, r>',
+    'p<u<x, r>>',
+];
 
 const PARSED = [
     {
@@ -7,7 +14,7 @@ const PARSED = [
         original: 'A<B<C<D>,  E>',
         returned: [],
         userQuery: 'a<b<c<d>,  e>',
-        error: 'Unexpected `<` after `<`',
+        error: 'Unclosed `<`',
     },
     {
         elems: [
@@ -59,4 +66,117 @@ const PARSED = [
         userQuery: '"p"<a>',
         error: null,
     },
+    {
+        elems: [
+            {
+                name: "p",
+                fullPath: ["p"],
+                pathWithoutLast: [],
+                pathLast: "p",
+                generics: [
+                    {
+                        name: "u",
+                        fullPath: ["u"],
+                        pathWithoutLast: [],
+                        pathLast: "u",
+                        generics: [
+                            {
+                                name: "x",
+                                fullPath: ["x"],
+                                pathWithoutLast: [],
+                                pathLast: "x",
+                                generics: [],
+                            },
+                        ],
+                    },
+                ],
+                typeFilter: -1,
+            },
+        ],
+        foundElems: 1,
+        original: 'p<u<x>>',
+        returned: [],
+        userQuery: 'p<u<x>>',
+        error: null,
+    },
+    {
+        elems: [
+            {
+                name: "p",
+                fullPath: ["p"],
+                pathWithoutLast: [],
+                pathLast: "p",
+                generics: [
+                    {
+                        name: "u",
+                        fullPath: ["u"],
+                        pathWithoutLast: [],
+                        pathLast: "u",
+                        generics: [
+                            {
+                                name: "x",
+                                fullPath: ["x"],
+                                pathWithoutLast: [],
+                                pathLast: "x",
+                                generics: [],
+                            },
+                        ],
+                    },
+                    {
+                        name: "r",
+                        fullPath: ["r"],
+                        pathWithoutLast: [],
+                        pathLast: "r",
+                        generics: [],
+                    },
+                ],
+                typeFilter: -1,
+            },
+        ],
+        foundElems: 1,
+        original: 'p<u<x>, r>',
+        returned: [],
+        userQuery: 'p<u<x>, r>',
+        error: null,
+    },
+    {
+        elems: [
+            {
+                name: "p",
+                fullPath: ["p"],
+                pathWithoutLast: [],
+                pathLast: "p",
+                generics: [
+                    {
+                        name: "u",
+                        fullPath: ["u"],
+                        pathWithoutLast: [],
+                        pathLast: "u",
+                        generics: [
+                            {
+                                name: "x",
+                                fullPath: ["x"],
+                                pathWithoutLast: [],
+                                pathLast: "x",
+                                generics: [],
+                            },
+                            {
+                                name: "r",
+                                fullPath: ["r"],
+                                pathWithoutLast: [],
+                                pathLast: "r",
+                                generics: [],
+                            },
+                        ],
+                    },
+                ],
+                typeFilter: -1,
+            },
+        ],
+        foundElems: 1,
+        original: 'p<u<x, r>>',
+        returned: [],
+        userQuery: 'p<u<x, r>>',
+        error: null,
+    },
 ];
diff --git a/tests/rustdoc-js/generics-nested.js b/tests/rustdoc-js/generics-nested.js
new file mode 100644
index 00000000000..8701f2d4986
--- /dev/null
+++ b/tests/rustdoc-js/generics-nested.js
@@ -0,0 +1,33 @@
+// exact-check
+
+const QUERY = [
+    '-> Out<First<Second>>',
+    '-> Out<Second<First>>',
+    '-> Out<First, Second>',
+    '-> Out<Second, First>',
+];
+
+const EXPECTED = [
+    {
+        // -> Out<First<Second>>
+        'others': [
+            { 'path': 'generics_nested', 'name': 'alef' },
+        ],
+    },
+    {
+        // -> Out<Second<First>>
+        'others': [],
+    },
+    {
+        // -> Out<First, Second>
+        'others': [
+            { 'path': 'generics_nested', 'name': 'bet' },
+        ],
+    },
+    {
+        // -> Out<Second, First>
+        'others': [
+            { 'path': 'generics_nested', 'name': 'bet' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/generics-nested.rs b/tests/rustdoc-js/generics-nested.rs
new file mode 100644
index 00000000000..5140422e384
--- /dev/null
+++ b/tests/rustdoc-js/generics-nested.rs
@@ -0,0 +1,19 @@
+pub struct Out<A, B = ()> {
+    a: A,
+    b: B,
+}
+
+pub struct First<In = ()> {
+    in_: In,
+}
+
+pub struct Second;
+
+// Out<First<Second>>
+pub fn alef() -> Out<First<Second>> {
+    loop {}
+}
+
+pub fn bet() -> Out<First, Second> {
+    loop {}
+}