diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 1e6c94d29ba47..6a8e93a243681 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -300,20 +300,21 @@ function initSearch(rawSearchIndex) {
* @return {integer}
*/
function getIdentEndPosition(parserState) {
+ const start = parserState.pos;
let end = parserState.pos;
- let foundExclamation = false;
+ let foundExclamation = -1;
while (parserState.pos < parserState.length) {
const c = parserState.userQuery[parserState.pos];
if (!isIdentCharacter(c)) {
if (c === "!") {
- if (foundExclamation) {
+ if (foundExclamation !== -1) {
throw new Error("Cannot have more than one `!` in an ident");
} else if (parserState.pos + 1 < parserState.length &&
isIdentCharacter(parserState.userQuery[parserState.pos + 1])
) {
throw new Error("`!` can only be at the end of an ident");
}
- foundExclamation = true;
+ foundExclamation = parserState.pos;
} else if (isErrorCharacter(c)) {
throw new Error(`Unexpected \`${c}\``);
} else if (
@@ -326,9 +327,18 @@ function initSearch(rawSearchIndex) {
if (!isPathStart(parserState)) {
break;
}
+ if (foundExclamation !== -1) {
+ if (start <= (end - 2)) {
+ throw new Error("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;
+ }
+ }
// Skip current ":".
parserState.pos += 1;
- foundExclamation = false;
} else {
throw new Error(`Unexpected \`${c}\``);
}
@@ -336,6 +346,16 @@ function initSearch(rawSearchIndex) {
parserState.pos += 1;
end = parserState.pos;
}
+ // if start == end - 1, we got the never type
+ if (foundExclamation !== -1 && start <= (end - 2)) {
+ if (parserState.typeFilter === null) {
+ parserState.typeFilter = "macro";
+ } else if (parserState.typeFilter !== "macro") {
+ throw new Error(`Invalid search type: macro \`!\` and ` +
+ `\`${parserState.typeFilter}\` both specified`);
+ }
+ end = foundExclamation;
+ }
return end;
}
diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js
index dc42031e05f2f..f82a2472063ce 100644
--- a/tests/rustdoc-js-std/parser-errors.js
+++ b/tests/rustdoc-js-std/parser-errors.js
@@ -37,6 +37,8 @@ const QUERY = [
"mod : :",
"a!a",
"a!!",
+ "mod:a!",
+ "a!::a",
];
const PARSED = [
@@ -382,4 +384,22 @@ const PARSED = [
userQuery: "a!!",
error: 'Cannot have more than one `!` in an ident',
},
+ {
+ elems: [],
+ foundElems: 0,
+ original: "mod:a!",
+ returned: [],
+ typeFilter: -1,
+ userQuery: "mod:a!",
+ error: 'Invalid search type: macro `!` and `mod` both specified',
+ },
+ {
+ elems: [],
+ foundElems: 0,
+ original: "a!::a",
+ returned: [],
+ typeFilter: -1,
+ userQuery: "a!::a",
+ error: 'Cannot have associated items in macros',
+ },
];
diff --git a/tests/rustdoc-js-std/parser-filter.js b/tests/rustdoc-js-std/parser-filter.js
index e5a87a415ac47..01f65b478f8e9 100644
--- a/tests/rustdoc-js-std/parser-filter.js
+++ b/tests/rustdoc-js-std/parser-filter.js
@@ -1,4 +1,4 @@
-const QUERY = ['fn:foo', 'enum : foo', 'macro:foo'];
+const QUERY = ['fn:foo', 'enum : foo', 'macro:foo', 'macro!', 'macro:mac!', 'a::mac!'];
const PARSED = [
{
@@ -40,4 +40,49 @@ const PARSED = [
userQuery: "macro:foo",
error: "Unexpected `:`",
},
+ {
+ elems: [{
+ name: "macro",
+ fullPath: ["macro"],
+ pathWithoutLast: [],
+ pathLast: "macro",
+ generics: [],
+ }],
+ foundElems: 1,
+ original: "macro!",
+ returned: [],
+ typeFilter: 14,
+ userQuery: "macro!",
+ error: null,
+ },
+ {
+ elems: [{
+ name: "mac",
+ fullPath: ["mac"],
+ pathWithoutLast: [],
+ pathLast: "mac",
+ generics: [],
+ }],
+ foundElems: 1,
+ original: "macro:mac!",
+ returned: [],
+ typeFilter: 14,
+ userQuery: "macro:mac!",
+ error: null,
+ },
+ {
+ elems: [{
+ name: "a::mac",
+ fullPath: ["a", "mac"],
+ pathWithoutLast: ["a"],
+ pathLast: "mac",
+ generics: [],
+ }],
+ foundElems: 1,
+ original: "a::mac!",
+ returned: [],
+ typeFilter: 14,
+ userQuery: "a::mac!",
+ error: null,
+ },
];
diff --git a/tests/rustdoc-js-std/parser-ident.js b/tests/rustdoc-js-std/parser-ident.js
index 4b5ab01ac761b..6c17d00f16edc 100644
--- a/tests/rustdoc-js-std/parser-ident.js
+++ b/tests/rustdoc-js-std/parser-ident.js
@@ -3,6 +3,7 @@ const QUERY = [
"!",
"a!",
"a!::b",
+ "!::b",
"a!::b!",
];
@@ -47,47 +48,50 @@ const PARSED = [
},
{
elems: [{
- name: "a!",
- fullPath: ["a!"],
+ name: "a",
+ fullPath: ["a"],
pathWithoutLast: [],
- pathLast: "a!",
+ pathLast: "a",
generics: [],
}],
foundElems: 1,
original: "a!",
returned: [],
- typeFilter: -1,
+ typeFilter: 14,
userQuery: "a!",
error: null,
},
{
- elems: [{
- name: "a!::b",
- fullPath: ["a!", "b"],
- pathWithoutLast: ["a!"],
- pathLast: "b",
- generics: [],
- }],
- foundElems: 1,
+ elems: [],
+ foundElems: 0,
original: "a!::b",
returned: [],
typeFilter: -1,
userQuery: "a!::b",
- error: null,
+ error: "Cannot have associated items in macros",
},
{
elems: [{
- name: "a!::b!",
- fullPath: ["a!", "b!"],
- pathWithoutLast: ["a!"],
- pathLast: "b!",
+ name: "!::b",
+ fullPath: ["!", "b"],
+ pathWithoutLast: ["!"],
+ pathLast: "b",
generics: [],
}],
foundElems: 1,
+ original: "!::b",
+ returned: [],
+ typeFilter: -1,
+ userQuery: "!::b",
+ error: null,
+ },
+ {
+ elems: [],
+ foundElems: 0,
original: "a!::b!",
returned: [],
typeFilter: -1,
userQuery: "a!::b!",
- error: null,
+ error: "Cannot have associated items in macros",
},
];
diff --git a/tests/rustdoc-js/macro-search.js b/tests/rustdoc-js/macro-search.js
new file mode 100644
index 0000000000000..2b179ce146bf0
--- /dev/null
+++ b/tests/rustdoc-js/macro-search.js
@@ -0,0 +1,10 @@
+// exact-check
+
+const QUERY = 'abracadabra!';
+
+const EXPECTED = {
+ 'others': [
+ { 'path': 'macro_search', 'name': 'abracadabra' },
+ { 'path': 'macro_search', 'name': 'abracadabra_b' },
+ ],
+};
diff --git a/tests/rustdoc-js/macro-search.rs b/tests/rustdoc-js/macro-search.rs
new file mode 100644
index 0000000000000..dc397490cf583
--- /dev/null
+++ b/tests/rustdoc-js/macro-search.rs
@@ -0,0 +1,10 @@
+#[macro_export]
+macro_rules! abracadabra {
+ () => {}
+}
+#[macro_export]
+macro_rules! abracadabra_b {
+ () => {}
+}
+pub fn abracadabra() {}
+pub fn abracadabra_c() {}