about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/rustdoc/src/how-to-read-rustdoc.md5
-rw-r--r--src/librustdoc/html/static/js/search.js247
-rw-r--r--tests/rustdoc-gui/search-tab-change-title-fn-sig.goml2
-rw-r--r--tests/rustdoc-js-std/parser-errors.js200
-rw-r--r--tests/rustdoc-js-std/parser-filter.js2
-rw-r--r--tests/rustdoc-js-std/parser-generics.js6
-rw-r--r--tests/rustdoc-js-std/parser-quote.js2
-rw-r--r--tests/rustdoc-js-std/parser-separators.js80
-rw-r--r--tests/rustdoc-js-std/parser-slice-array.js6
-rw-r--r--tests/rustdoc-js-std/parser-weird-queries.js40
-rw-r--r--tests/rustdoc-js-std/vec-new.js29
11 files changed, 431 insertions, 188 deletions
diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md
index 55cce8ab570..9deb7009cfe 100644
--- a/src/doc/rustdoc/src/how-to-read-rustdoc.md
+++ b/src/doc/rustdoc/src/how-to-read-rustdoc.md
@@ -110,6 +110,11 @@ Function signature searches also support arrays and slices. The explicit name
 or array of bytes, while square brackets `[u8]` will match either one. Empty
 square brackets, `[]`, will match any slice regardless of what it contains.
 
+Paths are supported as well, you can look for `Vec::new` or `Option::Some` or
+even `module::module_child::another_child::struct::field`. Whitespace characters
+are considered the same as `::`, so if you write `Vec    new`, it will be
+considered the same as `Vec::new`.
+
 ### Shortcuts
 
 Pressing `S` while focused elsewhere on the page will move focus to the
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 345750395f0..51d8e81ca86 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -290,7 +290,7 @@ function initSearch(rawSearchIndex) {
     }
 
     function isStopCharacter(c) {
-        return isWhitespace(c) || isEndCharacter(c);
+        return isEndCharacter(c);
     }
 
     function isErrorCharacter(c) {
@@ -386,18 +386,69 @@ function initSearch(rawSearchIndex) {
      * @return {boolean}
      */
     function isSeparatorCharacter(c) {
-        return c === "," || isWhitespaceCharacter(c);
+        return c === ",";
     }
 
-    /**
-     * Returns `true` if the given `c` character is a whitespace.
+/**
+     * Returns `true` if the given `c` character is a path separator. For example
+     * `:` in `a::b` or a whitespace in `a b`.
      *
      * @param {string} c
      *
      * @return {boolean}
      */
-    function isWhitespaceCharacter(c) {
-        return c === " " || c === "\t";
+    function isPathSeparator(c) {
+        return c === ":" || isWhitespace(c);
+    }
+
+    /**
+     * Returns `true` if the previous character is `lookingFor`.
+     *
+     * @param {ParserState} parserState
+     * @param {String} lookingFor
+     *
+     * @return {boolean}
+     */
+    function prevIs(parserState, lookingFor) {
+        let pos = parserState.pos;
+        while (pos > 0) {
+            const c = parserState.userQuery[pos - 1];
+            if (c === lookingFor) {
+                return true;
+            } else if (!isWhitespace(c)) {
+                break;
+            }
+            pos -= 1;
+        }
+        return false;
+    }
+
+    /**
+     * Returns `true` if the last element in the `elems` argument has generics.
+     *
+     * @param {Array<QueryElement>} elems
+     * @param {ParserState} parserState
+     *
+     * @return {boolean}
+     */
+    function isLastElemGeneric(elems, parserState) {
+        return (elems.length > 0 && elems[elems.length - 1].generics.length > 0) ||
+            prevIs(parserState, ">");
+    }
+
+    /**
+     * Increase current parser position until it doesn't find a whitespace anymore.
+     *
+     * @param {ParserState} parserState
+     */
+    function skipWhitespace(parserState) {
+        while (parserState.pos < parserState.userQuery.length) {
+            const c = parserState.userQuery[parserState.pos];
+            if (!isWhitespace(c)) {
+                break;
+            }
+            parserState.pos += 1;
+        }
     }
 
     /**
@@ -409,11 +460,14 @@ function initSearch(rawSearchIndex) {
      * @return {QueryElement}                - The newly created `QueryElement`.
      */
     function createQueryElement(query, parserState, name, generics, isInGenerics) {
-        if (name === "*" || (name.length === 0 && generics.length === 0)) {
-            return;
+        const path = name.trim();
+        if (path.length === 0 && generics.length === 0) {
+            throw ["Unexpected ", parserState.userQuery[parserState.pos]];
+        } else if (path === "*") {
+            throw ["Unexpected ", "*"];
         }
         if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) {
-            throw ["You cannot have more than one element if you use quotes"];
+            throw ["Cannot have more than one element if you use quotes"];
         }
         const typeFilter = parserState.typeFilter;
         parserState.typeFilter = null;
@@ -444,38 +498,40 @@ function initSearch(rawSearchIndex) {
                 typeFilter: "primitive",
             };
         }
-        const pathSegments = name.split("::");
-        if (pathSegments.length > 1) {
-            for (let i = 0, len = pathSegments.length; i < len; ++i) {
-                const pathSegment = pathSegments[i];
-
-                if (pathSegment.length === 0) {
-                    if (i === 0) {
-                        throw ["Paths cannot start with ", "::"];
-                    } else if (i + 1 === len) {
-                        throw ["Paths cannot end with ", "::"];
-                    }
-                    throw ["Unexpected ", "::::"];
-                }
-
-                if (pathSegment === "!") {
-                    pathSegments[i] = "never";
-                    if (i !== 0) {
-                        throw ["Never type ", "!", " is not associated item"];
-                    }
-                }
-            }
-        }
+        if (path.startsWith("::")) {
+            throw ["Paths cannot start with ", "::"];
+        } else if (path.endsWith("::")) {
+            throw ["Paths cannot end with ", "::"];
+        } else if (path.includes("::::")) {
+            throw ["Unexpected ", "::::"];
+        } else if (path.includes(" ::")) {
+            throw ["Unexpected ", " ::"];
+        } else if (path.includes(":: ")) {
+            throw ["Unexpected ", ":: "];
+        }
+        const pathSegments = path.split(/::|\s+/);
         // In case we only have something like `<p>`, there is no name.
         if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) {
-            throw ["Found generics without a path"];
+            if (generics.length > 0 || prevIs(parserState, ">")) {
+                throw ["Found generics without a path"];
+            } else {
+                throw ["Unexpected ", parserState.userQuery[parserState.pos]];
+            }
+        }
+        for (const [i, pathSegment] of pathSegments.entries()) {
+            if (pathSegment === "!") {
+                if (i !== 0) {
+                    throw ["Never type ", "!", " is not associated item"];
+                }
+                pathSegments[i] = "never";
+            }
         }
         parserState.totalElems += 1;
         if (isInGenerics) {
             parserState.genericsElems += 1;
         }
         return {
-            name: name,
+            name: name.trim(),
             id: -1,
             fullPath: pathSegments,
             pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1),
@@ -511,15 +567,21 @@ function initSearch(rawSearchIndex) {
                     foundExclamation = parserState.pos;
                 } else if (isErrorCharacter(c)) {
                     throw ["Unexpected ", c];
-                } else if (
-                    isStopCharacter(c) ||
-                    isSpecialStartCharacter(c) ||
-                    isSeparatorCharacter(c)
-                ) {
-                    break;
-                } else if (c === ":") { // If we allow paths ("str::string" for example).
-                    if (!isPathStart(parserState)) {
-                        break;
+                } else if (isPathSeparator(c)) {
+                    if (c === ":") {
+                        if (!isPathStart(parserState)) {
+                            break;
+                        }
+                        // Skip current ":".
+                        parserState.pos += 1;
+                    } else {
+                        while (parserState.pos + 1 < parserState.length) {
+                            const next_c = parserState.userQuery[parserState.pos + 1];
+                            if (!isWhitespace(next_c)) {
+                                break;
+                            }
+                            parserState.pos += 1;
+                        }
                     }
                     if (foundExclamation !== -1) {
                         if (foundExclamation !== start &&
@@ -532,8 +594,13 @@ function initSearch(rawSearchIndex) {
                             foundExclamation = -1;
                         }
                     }
-                    // Skip current ":".
-                    parserState.pos += 1;
+                } else if (
+                    c === "[" ||
+                    isStopCharacter(c) ||
+                    isSpecialStartCharacter(c) ||
+                    isSeparatorCharacter(c)
+                ) {
+                    break;
                 } else {
                     throw ["Unexpected ", c];
                 }
@@ -571,6 +638,7 @@ function initSearch(rawSearchIndex) {
     function getNextElem(query, parserState, elems, isInGenerics) {
         const generics = [];
 
+        skipWhitespace(parserState);
         let start = parserState.pos;
         let end;
         if (parserState.userQuery[parserState.pos] === "[") {
@@ -601,8 +669,9 @@ function initSearch(rawSearchIndex) {
                 typeFilter: "primitive",
             });
         } else {
+            const isStringElem = parserState.userQuery[start] === "\"";
             // We handle the strings on their own mostly to make code easier to follow.
-            if (parserState.userQuery[parserState.pos] === "\"") {
+            if (isStringElem) {
                 start += 1;
                 getStringElem(query, parserState, isInGenerics);
                 end = parserState.pos - 1;
@@ -618,6 +687,9 @@ function initSearch(rawSearchIndex) {
                 parserState.pos += 1;
                 getItemsBefore(query, parserState, generics, ">");
             }
+            if (isStringElem) {
+                skipWhitespace(parserState);
+            }
             if (start >= end && generics.length === 0) {
                 return;
             }
@@ -682,7 +754,7 @@ function initSearch(rawSearchIndex) {
                 if (elems.length === 0) {
                     throw ["Expected type filter before ", ":"];
                 } else if (query.literalSearch) {
-                    throw ["You cannot use quotes on type filter"];
+                    throw ["Cannot use quotes on type filter"];
                 }
                 // The type filter doesn't count as an element since it's a modifier.
                 const typeFilterElem = elems.pop();
@@ -697,23 +769,27 @@ function initSearch(rawSearchIndex) {
                 throw ["Unexpected ", c, " after ", extra];
             }
             if (!foundStopChar) {
+                let extra = [];
+                if (isLastElemGeneric(query.elems, parserState)) {
+                    extra = [" after ", ">"];
+                } else if (prevIs(parserState, "\"")) {
+                    throw ["Cannot have more than one element if you use quotes"];
+                }
                 if (endChar !== "") {
                     throw [
                         "Expected ",
-                        ",", // comma
-                        ", ",
-                        "&nbsp;", // whitespace
+                        ",",
                         " or ",
                         endChar,
+                        ...extra,
                         ", found ",
                         c,
                     ];
                 }
                 throw [
                     "Expected ",
-                    ",", // comma
-                    " or ",
-                    "&nbsp;", // whitespace
+                    ",",
+                    ...extra,
                     ", found ",
                     c,
                 ];
@@ -749,11 +825,17 @@ function initSearch(rawSearchIndex) {
      * @param {ParserState} parserState
      */
     function checkExtraTypeFilterCharacters(start, parserState) {
-        const query = parserState.userQuery;
+        const query = parserState.userQuery.slice(start, parserState.pos).trim();
 
-        for (let pos = start; pos < parserState.pos; ++pos) {
-            if (!isIdentCharacter(query[pos]) && !isWhitespaceCharacter(query[pos])) {
-                throw ["Unexpected ", query[pos], " in type filter"];
+        for (const c in query) {
+            if (!isIdentCharacter(query[c])) {
+                throw [
+                    "Unexpected ",
+                    query[c],
+                    " in type filter (before ",
+                    ":",
+                    ")",
+                ];
             }
         }
     }
@@ -785,12 +867,17 @@ function initSearch(rawSearchIndex) {
                 throw ["Unexpected ", c];
             } else if (c === ":" && !isPathStart(parserState)) {
                 if (parserState.typeFilter !== null) {
-                    throw ["Unexpected ", ":"];
-                }
-                if (query.elems.length === 0) {
+                    throw [
+                        "Unexpected ",
+                        ":",
+                        " (expected path after type filter ",
+                        parserState.typeFilter + ":",
+                        ")",
+                    ];
+                } else if (query.elems.length === 0) {
                     throw ["Expected type filter before ", ":"];
                 } else if (query.literalSearch) {
-                    throw ["You cannot use quotes on type filter"];
+                    throw ["Cannot use quotes on type filter"];
                 }
                 // The type filter doesn't count as an element since it's a modifier.
                 const typeFilterElem = query.elems.pop();
@@ -801,29 +888,36 @@ function initSearch(rawSearchIndex) {
                 query.literalSearch = false;
                 foundStopChar = true;
                 continue;
+            } else if (isWhitespace(c)) {
+                skipWhitespace(parserState);
+                continue;
             }
             if (!foundStopChar) {
+                let extra = "";
+                if (isLastElemGeneric(query.elems, parserState)) {
+                    extra = [" after ", ">"];
+                } else if (prevIs(parserState, "\"")) {
+                    throw ["Cannot have more than one element if you use quotes"];
+                }
                 if (parserState.typeFilter !== null) {
                     throw [
                         "Expected ",
-                        ",", // comma
-                        ", ",
-                        "&nbsp;", // whitespace
+                        ",",
                         " or ",
-                        "->", // arrow
+                        "->",
+                        ...extra,
                         ", found ",
                         c,
                     ];
                 }
                 throw [
                     "Expected ",
-                    ",", // comma
-                    ", ",
-                    "&nbsp;", // whitespace
+                    ",",
                     ", ",
-                    ":", // colon
+                    ":",
                     " or ",
-                    "->", // arrow
+                    "->",
+                    ...extra,
                     ", found ",
                     c,
                 ];
@@ -838,11 +932,18 @@ function initSearch(rawSearchIndex) {
             foundStopChar = false;
         }
         if (parserState.typeFilter !== null) {
-            throw ["Unexpected ", ":", " (expected path after type filter)"];
+            throw [
+                "Unexpected ",
+                ":",
+                " (expected path after type filter ",
+                parserState.typeFilter + ":",
+                ")",
+            ];
         }
         while (parserState.pos < parserState.length) {
             if (isReturnArrow(parserState)) {
                 parserState.pos += 2;
+                skipWhitespace(parserState);
                 // Get returned elements.
                 getItemsBefore(query, parserState, query.returned, "");
                 // Nothing can come afterward!
@@ -917,10 +1018,10 @@ function initSearch(rawSearchIndex) {
      * The supported syntax by this parser is as follow:
      *
      * ident = *(ALPHA / DIGIT / "_")
-     * path = ident *(DOUBLE-COLON ident) [!]
+     * path = ident *(DOUBLE-COLON/{WS} ident) [!]
      * slice = OPEN-SQUARE-BRACKET [ nonempty-arg-list ] CLOSE-SQUARE-BRACKET
      * arg = [type-filter *WS COLON *WS] (path [generics] / slice)
-     * type-sep = COMMA/WS *(COMMA/WS)
+     * type-sep = *WS COMMA *(COMMA)
      * nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep)
      * generics = OPEN-ANGLE-BRACKET [ nonempty-arg-list ] *(type-sep)
      *            CLOSE-ANGLE-BRACKET
@@ -2140,7 +2241,7 @@ function initSearch(rawSearchIndex) {
             error.forEach((value, index) => {
                 value = value.split("<").join("&lt;").split(">").join("&gt;");
                 if (index % 2 !== 0) {
-                    error[index] = `<code>${value}</code>`;
+                    error[index] = `<code>${value.replaceAll(" ", "&nbsp;")}</code>`;
                 } else {
                     error[index] = value;
                 }
diff --git a/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml b/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml
index b3f9ae9283f..156d8d03ca2 100644
--- a/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml
+++ b/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml
@@ -55,7 +55,7 @@ assert-text: ("#search-tabs > button:nth-of-type(1)", "In Function Return Types"
 
 // Try with a search-by-parameter
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-write: (".search-input", "usize pattern")
+write: (".search-input", "usize,pattern")
 // To be SURE that the search will be run.
 press-key: 'Enter'
 // Waiting for the search results to appear...
diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js
index af7f63f99cb..b32bfea5439 100644
--- a/tests/rustdoc-js-std/parser-errors.js
+++ b/tests/rustdoc-js-std/parser-errors.js
@@ -33,15 +33,24 @@ const PARSED = [
         original: "\"P\" \"P\"",
         returned: [],
         userQuery: "\"p\" \"p\"",
+        error: "Cannot have more than one element if you use quotes",
+    },
+    {
+        query: '"P","P"',
+        elems: [],
+        foundElems: 0,
+        original: "\"P\",\"P\"",
+        returned: [],
+        userQuery: "\"p\",\"p\"",
         error: "Cannot have more than one literal search element",
     },
     {
-        query: 'P "P"',
+        query: "P,\"P\"",
         elems: [],
         foundElems: 0,
-        original: "P \"P\"",
+        original: "P,\"P\"",
         returned: [],
-        userQuery: "p \"p\"",
+        userQuery: "p,\"p\"",
         error: "Cannot use literal search when there is more than one element",
     },
     {
@@ -51,7 +60,16 @@ const PARSED = [
         original: "\"p\" p",
         returned: [],
         userQuery: "\"p\" p",
-        error: "You cannot have more than one element if you use quotes",
+        error: "Cannot have more than one element if you use quotes",
+    },
+    {
+        query: '"p",p',
+        elems: [],
+        foundElems: 0,
+        original: "\"p\",p",
+        returned: [],
+        userQuery: "\"p\",p",
+        error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"const": p',
@@ -60,7 +78,7 @@ const PARSED = [
         original: "\"const\": p",
         returned: [],
         userQuery: "\"const\": p",
-        error: "You cannot use quotes on type filter",
+        error: "Cannot use quotes on type filter",
     },
     {
         query: "a<:a>",
@@ -108,6 +126,15 @@ const PARSED = [
         error: "Paths cannot start with `::`",
     },
     {
+        query: " ::a::b",
+        elems: [],
+        foundElems: 0,
+        original: "::a::b",
+        returned: [],
+        userQuery: "::a::b",
+        error: "Paths cannot start with `::`",
+    },
+    {
         query: "a::::b",
         elems: [],
         foundElems: 0,
@@ -135,13 +162,13 @@ const PARSED = [
         error: "Expected type filter before `:`",
     },
     {
-        query: "a b:",
+        query: "a,b:",
         elems: [],
         foundElems: 0,
-        original: "a b:",
+        original: "a,b:",
         returned: [],
-        userQuery: "a b:",
-        error: "Unexpected `:` (expected path after type filter)",
+        userQuery: "a,b:",
+        error: "Unexpected `:` (expected path after type filter `b:`)",
     },
     {
         query: "a (b:",
@@ -159,7 +186,7 @@ const PARSED = [
         original: "_:",
         returned: [],
         userQuery: "_:",
-        error: "Unexpected `:` (expected path after type filter)",
+        error: "Unexpected `:` (expected path after type filter `_:`)",
     },
     {
         query: "_:a",
@@ -213,6 +240,15 @@ const PARSED = [
         original: '"p" <a>',
         returned: [],
         userQuery: '"p" <a>',
+        error: "Cannot have more than one element if you use quotes",
+    },
+    {
+        query: '"p",<a>',
+        elems: [],
+        foundElems: 0,
+        original: '"p",<a>',
+        returned: [],
+        userQuery: '"p",<a>',
         error: "Found generics without a path",
     },
     {
@@ -222,7 +258,16 @@ const PARSED = [
         original: '"p" a<a>',
         returned: [],
         userQuery: '"p" a<a>',
-        error: "You cannot have more than one element if you use quotes",
+        error: "Cannot have more than one element if you use quotes",
+    },
+    {
+        query: '"p",a<a>',
+        elems: [],
+        foundElems: 0,
+        original: '"p",a<a>',
+        returned: [],
+        userQuery: '"p",a<a>',
+        error: "Cannot have more than one element if you use quotes",
     },
     {
         query: "a,<",
@@ -240,7 +285,7 @@ const PARSED = [
         original: 'aaaaa<>b',
         returned: [],
         userQuery: 'aaaaa<>b',
-        error: 'Expected `,`, ` `, `:` or `->`, found `b`',
+        error: 'Expected `,`, `:` or `->` after `>`, found `b`',
     },
     {
         query: "fn:aaaaa<>b",
@@ -249,7 +294,7 @@ const PARSED = [
         original: 'fn:aaaaa<>b',
         returned: [],
         userQuery: 'fn:aaaaa<>b',
-        error: 'Expected `,`, ` `, `:` or `->`, found `b`',
+        error: 'Expected `,`, `:` or `->` after `>`, found `b`',
     },
     {
         query: "->a<>b",
@@ -258,7 +303,7 @@ const PARSED = [
         original: '->a<>b',
         returned: [],
         userQuery: '->a<>b',
-        error: 'Expected `,` or ` `, found `b`',
+        error: 'Expected `,` after `>`, found `b`',
     },
     {
         query: "a<->",
@@ -276,7 +321,7 @@ const PARSED = [
         original: 'a:: a',
         returned: [],
         userQuery: 'a:: a',
-        error: 'Paths cannot end with `::`',
+        error: 'Unexpected `:: `',
     },
     {
         query: "a ::a",
@@ -285,7 +330,7 @@ const PARSED = [
         original: 'a ::a',
         returned: [],
         userQuery: 'a ::a',
-        error: 'Paths cannot start with `::`',
+        error: 'Unexpected ` ::`',
     },
     {
         query: "a<a>:",
@@ -294,7 +339,7 @@ const PARSED = [
         original: "a<a>:",
         returned: [],
         userQuery: "a<a>:",
-        error: 'Unexpected `<` in type filter',
+        error: 'Unexpected `<` in type filter (before `:`)',
     },
     {
         query: "a<>:",
@@ -303,7 +348,7 @@ const PARSED = [
         original: "a<>:",
         returned: [],
         userQuery: "a<>:",
-        error: 'Unexpected `<` in type filter',
+        error: 'Unexpected `<` in type filter (before `:`)',
     },
     {
         query: "a,:",
@@ -312,7 +357,7 @@ const PARSED = [
         original: "a,:",
         returned: [],
         userQuery: "a,:",
-        error: 'Unexpected `,` in type filter',
+        error: 'Unexpected `,` in type filter (before `:`)',
     },
     {
         query: "  a<>  :",
@@ -321,7 +366,7 @@ const PARSED = [
         original: "a<>  :",
         returned: [],
         userQuery: "a<>  :",
-        error: 'Unexpected `<` in type filter',
+        error: 'Unexpected `<` in type filter (before `:`)',
     },
     {
         query: "mod : :",
@@ -330,7 +375,16 @@ const PARSED = [
         original: "mod : :",
         returned: [],
         userQuery: "mod : :",
-        error: 'Unexpected `:`',
+        error: 'Unexpected `:` (expected path after type filter `mod:`)',
+    },
+    {
+        query: "mod: :",
+        elems: [],
+        foundElems: 0,
+        original: "mod: :",
+        returned: [],
+        userQuery: "mod: :",
+        error: 'Unexpected `:` (expected path after type filter `mod:`)',
     },
     {
         query: "a!a",
@@ -386,4 +440,108 @@ const PARSED = [
         userQuery: "a<",
         error: "Unclosed `<`",
     },
+    {
+        query: "p<x> , y",
+        elems: [
+            {
+                name: "p",
+                fullPath: ["p"],
+                pathWithoutLast: [],
+                pathLast: "p",
+                generics: [
+                    {
+                        name: "x",
+                        fullPath: ["x"],
+                        pathWithoutLast: [],
+                        pathLast: "x",
+                        generics: [],
+                        typeFilter: -1,
+                    },
+                ],
+                typeFilter: -1,
+            },
+            {
+                name: "y",
+                fullPath: ["y"],
+                pathWithoutLast: [],
+                pathLast: "y",
+                generics: [],
+                typeFilter: -1,
+            },
+        ],
+        foundElems: 2,
+        original: "p<x> , y",
+        returned: [],
+        userQuery: "p<x> , y",
+        error: null,
+    },
+    {
+        query: "p<x , y>",
+        elems: [
+            {
+                name: "p",
+                fullPath: ["p"],
+                pathWithoutLast: [],
+                pathLast: "p",
+                generics: [
+                    {
+                        name: "x",
+                        fullPath: ["x"],
+                        pathWithoutLast: [],
+                        pathLast: "x",
+                        generics: [],
+                        typeFilter: -1,
+                    },
+                    {
+                        name: "y",
+                        fullPath: ["y"],
+                        pathWithoutLast: [],
+                        pathLast: "y",
+                        generics: [],
+                        typeFilter: -1,
+                    },
+                ],
+                typeFilter: -1,
+            },
+        ],
+        foundElems: 1,
+        original: "p<x , y>",
+        returned: [],
+        userQuery: "p<x , y>",
+        error: null,
+    },
+    {
+        query: "p ,x , y",
+        elems: [
+            {
+                name: "p",
+                fullPath: ["p"],
+                pathWithoutLast: [],
+                pathLast: "p",
+                generics: [],
+                typeFilter: -1,
+            },
+            {
+                name: "x",
+                fullPath: ["x"],
+                pathWithoutLast: [],
+                pathLast: "x",
+                generics: [],
+                typeFilter: -1,
+            },
+            {
+                name: "y",
+                fullPath: ["y"],
+                pathWithoutLast: [],
+                pathLast: "y",
+                generics: [],
+                typeFilter: -1,
+            },
+        ],
+        foundElems: 3,
+        original: "p ,x , y",
+        returned: [],
+        userQuery: "p ,x , y",
+        error: null,
+    },
 ];
diff --git a/tests/rustdoc-js-std/parser-filter.js b/tests/rustdoc-js-std/parser-filter.js
index 6f5d66e57ba..3b9cc5b1bf0 100644
--- a/tests/rustdoc-js-std/parser-filter.js
+++ b/tests/rustdoc-js-std/parser-filter.js
@@ -38,7 +38,7 @@ const PARSED = [
         original: "macro<f>:foo",
         returned: [],
         userQuery: "macro<f>:foo",
-        error: "Unexpected `<` in type filter",
+        error: "Unexpected `<` in type filter (before `:`)",
     },
     {
         query: 'macro!',
diff --git a/tests/rustdoc-js-std/parser-generics.js b/tests/rustdoc-js-std/parser-generics.js
index eb3cf455155..726ee56c2c1 100644
--- a/tests/rustdoc-js-std/parser-generics.js
+++ b/tests/rustdoc-js-std/parser-generics.js
@@ -9,7 +9,7 @@ const PARSED = [
         error: 'Unclosed `<`',
     },
     {
-        query: 'p<> u8',
+        query: 'p<>,u8',
         elems: [
             {
                 name: "p",
@@ -29,9 +29,9 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "p<> u8",
+        original: "p<>,u8",
         returned: [],
-        userQuery: "p<> u8",
+        userQuery: "p<>,u8",
         error: null,
     },
     {
diff --git a/tests/rustdoc-js-std/parser-quote.js b/tests/rustdoc-js-std/parser-quote.js
index 9d2a3620ed7..731673cf463 100644
--- a/tests/rustdoc-js-std/parser-quote.js
+++ b/tests/rustdoc-js-std/parser-quote.js
@@ -38,7 +38,7 @@ const PARSED = [
         original: '"p" -> a',
         returned: [],
         userQuery: '"p" -> a',
-        error: "You cannot have more than one element if you use quotes",
+        error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"a" -> "p"',
diff --git a/tests/rustdoc-js-std/parser-separators.js b/tests/rustdoc-js-std/parser-separators.js
index 69f9ac29ad3..00c489b51a6 100644
--- a/tests/rustdoc-js-std/parser-separators.js
+++ b/tests/rustdoc-js-std/parser-separators.js
@@ -5,6 +5,24 @@ const PARSED = [
         query: 'aaaaaa	b',
         elems: [
             {
+                name: 'aaaaaa\tb',
+                fullPath: ['aaaaaa', 'b'],
+                pathWithoutLast: ['aaaaaa'],
+                pathLast: 'b',
+                generics: [],
+                typeFilter: -1,
+            },
+        ],
+        foundElems: 1,
+        original: "aaaaaa	b",
+        returned: [],
+        userQuery: "aaaaaa	b",
+        error: null,
+    },
+    {
+        query: "aaaaaa,	b",
+        elems: [
+            {
                 name: 'aaaaaa',
                 fullPath: ['aaaaaa'],
                 pathWithoutLast: [],
@@ -22,32 +40,24 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "aaaaaa	b",
+        original: "aaaaaa,	b",
         returned: [],
-        userQuery: "aaaaaa	b",
+        userQuery: "aaaaaa,	b",
         error: null,
     },
     {
         query: 'a b',
         elems: [
             {
-                name: 'a',
-                fullPath: ['a'],
-                pathWithoutLast: [],
-                pathLast: 'a',
-                generics: [],
-                typeFilter: -1,
-            },
-            {
-                name: 'b',
-                fullPath: ['b'],
-                pathWithoutLast: [],
+                name: 'a b',
+                fullPath: ['a', 'b'],
+                pathWithoutLast: ['a'],
                 pathLast: 'b',
                 generics: [],
                 typeFilter: -1,
             },
         ],
-        foundElems: 2,
+        foundElems: 1,
         original: "a b",
         returned: [],
         userQuery: "a b",
@@ -83,23 +93,15 @@ const PARSED = [
         query: 'a\tb',
         elems: [
             {
-                name: 'a',
-                fullPath: ['a'],
-                pathWithoutLast: [],
-                pathLast: 'a',
-                generics: [],
-                typeFilter: -1,
-            },
-            {
-                name: 'b',
-                fullPath: ['b'],
-                pathWithoutLast: [],
+                name: 'a\tb',
+                fullPath: ['a', 'b'],
+                pathWithoutLast: ['a'],
                 pathLast: 'b',
                 generics: [],
                 typeFilter: -1,
             },
         ],
-        foundElems: 2,
+        foundElems: 1,
         original: "a\tb",
         returned: [],
         userQuery: "a\tb",
@@ -115,16 +117,9 @@ const PARSED = [
                 pathLast: 'a',
                 generics: [
                     {
-                        name: 'b',
-                        fullPath: ['b'],
-                        pathWithoutLast: [],
-                        pathLast: 'b',
-                        generics: [],
-                    },
-                    {
-                        name: 'c',
-                        fullPath: ['c'],
-                        pathWithoutLast: [],
+                        name: 'b c',
+                        fullPath: ['b', 'c'],
+                        pathWithoutLast: ['b'],
                         pathLast: 'c',
                         generics: [],
                     },
@@ -181,16 +176,9 @@ const PARSED = [
                 pathLast: 'a',
                 generics: [
                     {
-                        name: 'b',
-                        fullPath: ['b'],
-                        pathWithoutLast: [],
-                        pathLast: 'b',
-                        generics: [],
-                    },
-                    {
-                        name: 'c',
-                        fullPath: ['c'],
-                        pathWithoutLast: [],
+                        name: 'b\tc',
+                        fullPath: ['b', 'c'],
+                        pathWithoutLast: ['b'],
                         pathLast: 'c',
                         generics: [],
                     },
diff --git a/tests/rustdoc-js-std/parser-slice-array.js b/tests/rustdoc-js-std/parser-slice-array.js
index f85dd199741..c22b7870dbf 100644
--- a/tests/rustdoc-js-std/parser-slice-array.js
+++ b/tests/rustdoc-js-std/parser-slice-array.js
@@ -62,7 +62,7 @@ const PARSED = [
         error: null,
     },
     {
-        query: '[] u8',
+        query: '[],u8',
         elems: [
             {
                 name: "[]",
@@ -82,9 +82,9 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "[] u8",
+        original: "[],u8",
         returned: [],
-        userQuery: "[] u8",
+        userQuery: "[],u8",
         error: null,
     },
     {
diff --git a/tests/rustdoc-js-std/parser-weird-queries.js b/tests/rustdoc-js-std/parser-weird-queries.js
index 0e08eaf73c8..720ef66c165 100644
--- a/tests/rustdoc-js-std/parser-weird-queries.js
+++ b/tests/rustdoc-js-std/parser-weird-queries.js
@@ -7,23 +7,14 @@ const PARSED = [
         query: 'a b',
         elems: [
             {
-                name: "a",
-                fullPath: ["a"],
-                pathWithoutLast: [],
-                pathLast: "a",
-                generics: [],
-                typeFilter: -1,
-            },
-            {
-                name: "b",
-                fullPath: ["b"],
-                pathWithoutLast: [],
+                name: "a b",
+                fullPath: ["a", "b"],
+                pathWithoutLast: ["a"],
                 pathLast: "b",
                 generics: [],
-                typeFilter: -1,
             },
         ],
-        foundElems: 2,
+        foundElems: 1,
         original: "a b",
         returned: [],
         userQuery: "a b",
@@ -33,23 +24,14 @@ const PARSED = [
         query: 'a   b',
         elems: [
             {
-                name: "a",
-                fullPath: ["a"],
-                pathWithoutLast: [],
-                pathLast: "a",
-                generics: [],
-                typeFilter: -1,
-            },
-            {
-                name: "b",
-                fullPath: ["b"],
-                pathWithoutLast: [],
+                name: "a   b",
+                fullPath: ["a", "b"],
+                pathWithoutLast: ["a"],
                 pathLast: "b",
                 generics: [],
-                typeFilter: -1,
             },
         ],
-        foundElems: 2,
+        foundElems: 1,
         original: "a   b",
         returned: [],
         userQuery: "a   b",
@@ -73,7 +55,6 @@ const PARSED = [
                 pathWithoutLast: [],
                 pathLast: "aaa",
                 generics: [],
-                typeFilter: -1,
             },
             {
                 name: "a",
@@ -81,7 +62,6 @@ const PARSED = [
                 pathWithoutLast: [],
                 pathLast: "a",
                 generics: [],
-                typeFilter: -1,
             },
         ],
         foundElems: 2,
@@ -106,7 +86,7 @@ const PARSED = [
         original: 'mod    :',
         returned: [],
         userQuery: 'mod    :',
-        error: "Unexpected `:` (expected path after type filter)",
+        error: "Unexpected `:` (expected path after type filter `mod:`)",
     },
     {
         query: 'mod\t:',
@@ -115,6 +95,6 @@ const PARSED = [
         original: 'mod\t:',
         returned: [],
         userQuery: 'mod\t:',
-        error: "Unexpected `:` (expected path after type filter)",
+        error: "Unexpected `:` (expected path after type filter `mod:`)",
     },
 ];
diff --git a/tests/rustdoc-js-std/vec-new.js b/tests/rustdoc-js-std/vec-new.js
index 309f3543faf..9823a417a5d 100644
--- a/tests/rustdoc-js-std/vec-new.js
+++ b/tests/rustdoc-js-std/vec-new.js
@@ -1,9 +1,20 @@
-const EXPECTED = {
-    'query': 'Vec::new',
-    'others': [
-        { 'path': 'std::vec::Vec', 'name': 'new' },
-        { 'path': 'alloc::vec::Vec', 'name': 'new' },
-        { 'path': 'std::vec::Vec', 'name': 'new_in' },
-        { 'path': 'alloc::vec::Vec', 'name': 'new_in' },
-    ],
-};
+const EXPECTED = [
+    {
+        'query': 'Vec::new',
+        'others': [
+            { 'path': 'std::vec::Vec', 'name': 'new' },
+            { 'path': 'alloc::vec::Vec', 'name': 'new' },
+            { 'path': 'std::vec::Vec', 'name': 'new_in' },
+            { 'path': 'alloc::vec::Vec', 'name': 'new_in' },
+        ],
+    },
+    {
+        'query': 'Vec new',
+        'others': [
+            { 'path': 'std::vec::Vec', 'name': 'new' },
+            { 'path': 'alloc::vec::Vec', 'name': 'new' },
+            { 'path': 'std::vec::Vec', 'name': 'new_in' },
+            { 'path': 'alloc::vec::Vec', 'name': 'new_in' },
+        ],
+    },
+];