diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 41a9897de6d..76a6fc9008e 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -786,6 +786,37 @@ function initSearch(rawSearchIndex) {
}
elems.push(makePrimitiveElement(name, { bindingName, generics }));
}
+ } else if (parserState.userQuery[parserState.pos] === "&") {
+ if (parserState.typeFilter !== null && parserState.typeFilter !== "primitive") {
+ throw [
+ "Invalid search type: primitive ",
+ "&",
+ " and ",
+ parserState.typeFilter,
+ " both specified",
+ ];
+ }
+ parserState.typeFilter = null;
+ parserState.pos += 1;
+ let c = parserState.userQuery[parserState.pos];
+ while (c === " " && parserState.pos < parserState.length) {
+ parserState.pos += 1;
+ c = parserState.userQuery[parserState.pos];
+ }
+ const generics = [];
+ if (parserState.userQuery.slice(parserState.pos, parserState.pos + 3) === "mut") {
+ generics.push(makePrimitiveElement("mut", { typeFilter: "keyword"}));
+ parserState.pos += 3;
+ c = parserState.userQuery[parserState.pos];
+ }
+ while (c === " " && parserState.pos < parserState.length) {
+ parserState.pos += 1;
+ c = parserState.userQuery[parserState.pos];
+ }
+ if (!isEndCharacter(c) && parserState.pos < parserState.length) {
+ getFilteredNextElem(query, parserState, generics, isInGenerics);
+ }
+ elems.push(makePrimitiveElement("reference", { generics }));
} else {
const isStringElem = parserState.userQuery[start] === "\"";
// We handle the strings on their own mostly to make code easier to follow.
diff --git a/tests/rustdoc-js-std/parser-reference.js b/tests/rustdoc-js-std/parser-reference.js
new file mode 100644
index 00000000000..6b1250146be
--- /dev/null
+++ b/tests/rustdoc-js-std/parser-reference.js
@@ -0,0 +1,527 @@
+const PARSED = [
+ {
+ query: '&[',
+ elems: [],
+ foundElems: 0,
+ original: '&[',
+ returned: [],
+ userQuery: '&[',
+ error: 'Unclosed `[`',
+ },
+ {
+ query: '[&',
+ elems: [],
+ foundElems: 0,
+ original: '[&',
+ returned: [],
+ userQuery: '[&',
+ error: 'Unclosed `[`',
+ },
+ {
+ query: '&&&D, []',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "d",
+ fullPath: ["d"],
+ pathWithoutLast: [],
+ pathLast: "d",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ {
+ name: "[]",
+ fullPath: ["[]"],
+ pathWithoutLast: [],
+ pathLast: "[]",
+ generics: [],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 2,
+ original: '&&&D, []',
+ returned: [],
+ userQuery: '&&&d, []',
+ error: null,
+ },
+ {
+ query: '&&&[D]',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "[]",
+ fullPath: ["[]"],
+ pathWithoutLast: [],
+ pathLast: "[]",
+ generics: [
+ {
+ name: "d",
+ fullPath: ["d"],
+ pathWithoutLast: [],
+ pathLast: "d",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 1,
+ original: '&&&[D]',
+ returned: [],
+ userQuery: '&&&[d]',
+ error: null,
+ },
+ {
+ query: '&',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 1,
+ original: '&',
+ returned: [],
+ userQuery: '&',
+ error: null,
+ },
+ {
+ query: '&mut',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "mut",
+ fullPath: ["mut"],
+ pathWithoutLast: [],
+ pathLast: "mut",
+ generics: [],
+ typeFilter: 0,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 1,
+ original: '&mut',
+ returned: [],
+ userQuery: '&mut',
+ error: null,
+ },
+ {
+ query: '&,u8',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [],
+ typeFilter: 1,
+ },
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ foundElems: 2,
+ original: "&,u8",
+ returned: [],
+ userQuery: "&,u8",
+ error: null,
+ },
+ {
+ query: '&mut,u8',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "mut",
+ fullPath: ["mut"],
+ pathWithoutLast: [],
+ pathLast: "mut",
+ generics: [],
+ typeFilter: 0,
+ },
+ ],
+ typeFilter: 1,
+ },
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ foundElems: 2,
+ original: "&mut,u8",
+ returned: [],
+ userQuery: "&mut,u8",
+ error: null,
+ },
+ {
+ query: '&u8',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 1,
+ original: "&u8",
+ returned: [],
+ userQuery: "&u8",
+ error: null,
+ },
+ {
+ query: '&u8',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 1,
+ original: "&u8",
+ returned: [],
+ userQuery: "&u8",
+ error: null,
+ },
+ {
+ query: 'u8<&u8>',
+ elems: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ typeFilter: -1,
+ },
+ ],
+ foundElems: 1,
+ original: "u8<&u8>",
+ returned: [],
+ userQuery: "u8<&u8>",
+ error: null,
+ },
+ {
+ query: 'u8<&u8, u8>',
+ elems: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: -1,
+ },
+ ],
+ foundElems: 1,
+ original: "u8<&u8, u8>",
+ returned: [],
+ userQuery: "u8<&u8, u8>",
+ error: null,
+ },
+ {
+ query: 'u8<&u8>',
+ elems: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ typeFilter: -1,
+ },
+ ],
+ foundElems: 1,
+ original: "u8<&u8>",
+ returned: [],
+ userQuery: "u8<&u8>",
+ error: null,
+ },
+ {
+ query: 'u8<&mut u8, u8>',
+ elems: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "mut",
+ fullPath: ["mut"],
+ pathWithoutLast: [],
+ pathLast: "mut",
+ generics: [],
+ typeFilter: 0,
+ },
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: -1,
+ },
+ ],
+ foundElems: 1,
+ original: "u8<&mut u8, u8>",
+ returned: [],
+ userQuery: "u8<&mut u8, u8>",
+ error: null,
+ },
+ {
+ query: 'primitive:&u8',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: -1,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 1,
+ original: "primitive:&u8",
+ returned: [],
+ userQuery: "primitive:&u8",
+ error: null,
+ },
+ {
+ query: 'macro:&u8',
+ elems: [],
+ foundElems: 0,
+ original: "macro:&u8",
+ returned: [],
+ userQuery: "macro:&u8",
+ error: "Invalid search type: primitive `&` and `macro` both specified",
+ },
+ {
+ query: '¯o:u8',
+ elems: [
+ {
+ name: "reference",
+ fullPath: ["reference"],
+ pathWithoutLast: [],
+ pathLast: "reference",
+ generics: [
+ {
+ name: "u8",
+ fullPath: ["u8"],
+ pathWithoutLast: [],
+ pathLast: "u8",
+ generics: [],
+ typeFilter: 16,
+ },
+ ],
+ typeFilter: 1,
+ },
+ ],
+ foundElems: 1,
+ original: "¯o:u8",
+ returned: [],
+ userQuery: "¯o:u8",
+ error: null,
+ },
+];
diff --git a/tests/rustdoc-js/reference.js b/tests/rustdoc-js/reference.js
index dc40eee5687..b4a1fb15d36 100644
--- a/tests/rustdoc-js/reference.js
+++ b/tests/rustdoc-js/reference.js
@@ -132,4 +132,105 @@ const EXPECTED = [
'query': 'reference>, reference> -> ()',
'others': [],
},
+ // pinkie with shorthand
+ {
+ 'query': '&usize, usize -> ()',
+ 'others': [
+ { 'path': 'reference', 'name': 'pinky' },
+ ],
+ },
+ {
+ 'query': '&usize, &usize -> ()',
+ 'others': [],
+ },
+ {
+ 'query': '&mut usize, usize -> ()',
+ 'others': [],
+ },
+ // thumb with shorthand
+ {
+ 'query': '&thumb, thumb -> ()',
+ 'others': [
+ { 'path': 'reference::Thumb', 'name': 'up' },
+ ],
+ },
+ {
+ 'query': '&thumb, &thumb -> ()',
+ 'others': [],
+ },
+ {
+ 'query': '&mut thumb, thumb -> ()',
+ 'others': [],
+ },
+ // index with explicit names
+ {
+ 'query': '&index, index -> ()',
+ 'others': [
+ { 'path': 'reference::Index', 'name': 'point' },
+ ],
+ },
+ {
+ 'query': '&index, &index -> ()',
+ 'others': [],
+ },
+ {
+ 'query': '&mut index, index -> ()',
+ 'others': [],
+ },
+ // ring with shorthand
+ {
+ 'query': '&ring, ring -> ()',
+ 'others': [
+ { 'path': 'reference::Ring', 'name': 'wear' },
+ ],
+ },
+ {
+ 'query': '&ring, ring -> ()',
+ 'others': [
+ { 'path': 'reference::Ring', 'name': 'wear' },
+ ],
+ },
+ {
+ 'query': '&mut ring, &ring -> ()',
+ 'others': [
+ { 'path': 'reference::Ring', 'name': 'wear' },
+ ],
+ },
+ {
+ 'query': '&mut ring, &mut ring -> ()',
+ 'others': [],
+ },
+ // middle with shorthand
+ {
+ 'query': '&middle, &middle -> ()',
+ 'others': [
+ { 'path': 'reference', 'name': 'show' },
+ ],
+ },
+ {
+ 'query': '&mut middle, &mut middle -> ()',
+ 'others': [
+ { 'path': 'reference', 'name': 'show' },
+ ],
+ },
+ {
+ 'query': '&&mut middle, &mut &middle -> ()',
+ 'others': [
+ { 'path': 'reference', 'name': 'show' },
+ ],
+ },
+ {
+ 'query': '&mut &middle, &&mut middle -> ()',
+ 'others': [
+ { 'path': 'reference', 'name': 'show' },
+ ],
+ },
+ {
+ 'query': '&&mut middle, &&mut middle -> ()',
+ 'others': [],
+ },
+ {
+ 'query': '&mut &middle, &mut &middle -> ()',
+ 'others': [],
+ },
];