diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index f1f83acdda59e..3acfb82fe7840 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -43,7 +43,7 @@ crate struct Cache {
/// found on that implementation.
pub impls: FxHashMap>,
- /// Maintains a mapping of local crate `NodeId`s to the fully qualified name
+ /// Maintains a mapping of local crate `DefId`s to the fully qualified name
/// and "short type description" of that node. This is used when generating
/// URLs when a type is being linked to. External paths are not located in
/// this map because the `External` type itself has all the information
@@ -358,6 +358,7 @@ impl DocFolder for Cache {
| clean::ForeignTypeItem
| clean::MacroItem(..)
| clean::ProcMacroItem(..)
+ | clean::VariantItem(..)
if !self.stripped_mod =>
{
// Re-exported items mean that the same id can show up twice
@@ -373,13 +374,6 @@ impl DocFolder for Cache {
}
self.add_aliases(&item);
}
- // Link variants to their parent enum because pages aren't emitted
- // for each variant.
- clean::VariantItem(..) if !self.stripped_mod => {
- let mut stack = self.stack.clone();
- stack.pop();
- self.paths.insert(item.def_id, (stack, ItemType::Enum));
- }
clean::PrimitiveItem(..) => {
self.add_aliases(&item);
@@ -396,7 +390,8 @@ impl DocFolder for Cache {
| clean::EnumItem(..)
| clean::ForeignTypeItem
| clean::StructItem(..)
- | clean::UnionItem(..) => {
+ | clean::UnionItem(..)
+ | clean::VariantItem(..) => {
self.parent_stack.push(item.def_id);
self.parent_is_trait_impl = false;
true
@@ -564,7 +559,7 @@ fn extern_location(
/// Builds the search index from the collected metadata
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
- let mut nodeid_to_pathid = FxHashMap::default();
+ let mut defid_to_pathid = FxHashMap::default();
let mut crate_items = Vec::with_capacity(cache.search_index.len());
let mut crate_paths = vec![];
@@ -586,21 +581,21 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
}
}
- // Reduce `NodeId` in paths into smaller sequential numbers,
+ // Reduce `DefId` in paths into smaller sequential numbers,
// and prune the paths that do not appear in the index.
let mut lastpath = String::new();
let mut lastpathid = 0usize;
for item in search_index {
- item.parent_idx = item.parent.map(|nodeid| {
- if nodeid_to_pathid.contains_key(&nodeid) {
- *nodeid_to_pathid.get(&nodeid).expect("no pathid")
+ item.parent_idx = item.parent.map(|defid| {
+ if defid_to_pathid.contains_key(&defid) {
+ *defid_to_pathid.get(&defid).expect("no pathid")
} else {
let pathid = lastpathid;
- nodeid_to_pathid.insert(nodeid, pathid);
+ defid_to_pathid.insert(defid, pathid);
lastpathid += 1;
- let &(ref fqp, short) = paths.get(&nodeid).unwrap();
+ let &(ref fqp, short) = paths.get(&defid).unwrap();
crate_paths.push((short, fqp.last().unwrap().clone()));
pathid
}
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 44fd8b929f3a3..2870c6e0a6147 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -1364,14 +1364,15 @@ function getSearchElement() {
var href;
var type = itemTypes[item.ty];
var name = item.name;
+ var path = item.path;
if (type === "mod") {
- displayPath = item.path + "::";
- href = rootPath + item.path.replace(/::/g, "/") + "/" +
+ displayPath = path + "::";
+ href = rootPath + path.replace(/::/g, "/") + "/" +
name + "/index.html";
} else if (type === "primitive" || type === "keyword") {
displayPath = "";
- href = rootPath + item.path.replace(/::/g, "/") +
+ href = rootPath + path.replace(/::/g, "/") +
"/" + type + "." + name + ".html";
} else if (type === "externcrate") {
displayPath = "";
@@ -1380,14 +1381,27 @@ function getSearchElement() {
var myparent = item.parent;
var anchor = "#" + type + "." + name;
var parentType = itemTypes[myparent.ty];
+ var pageType = parentType;
+ var pageName = myparent.name;
+
if (parentType === "primitive") {
displayPath = myparent.name + "::";
+ } else if (type === "structfield" && parentType === "variant") {
+ // Structfields belonging to variants are special: the
+ // final path element is the enum name.
+ var splitPath = item.path.split("::");
+ var enumName = splitPath.pop();
+ path = splitPath.join("::");
+ displayPath = path + "::" + enumName + "::" + myparent.name + "::";
+ anchor = "#variant." + myparent.name + ".field." + name;
+ pageType = "enum";
+ pageName = enumName;
} else {
- displayPath = item.path + "::" + myparent.name + "::";
+ displayPath = path + "::" + myparent.name + "::";
}
- href = rootPath + item.path.replace(/::/g, "/") +
- "/" + parentType +
- "." + myparent.name +
+ href = rootPath + path.replace(/::/g, "/") +
+ "/" + pageType +
+ "." + pageName +
".html" + anchor;
} else {
displayPath = item.path + "::";
@@ -1668,7 +1682,7 @@ function getSearchElement() {
// (String) name]
var paths = rawSearchIndex[crate].p;
- // convert `paths` into an object form
+ // convert `rawPaths` entries into object form
var len = paths.length;
for (i = 0; i < len; ++i) {
paths[i] = {ty: paths[i][0], name: paths[i][1]};
diff --git a/src/test/rustdoc-js/struct-like-variant.js b/src/test/rustdoc-js/struct-like-variant.js
new file mode 100644
index 0000000000000..a698b1d4013fe
--- /dev/null
+++ b/src/test/rustdoc-js/struct-like-variant.js
@@ -0,0 +1,7 @@
+const QUERY = 'name';
+
+const EXPECTED = {
+ 'others': [
+ { 'path': 'struct_like_variant::Enum::Bar::name', 'name': 'l' },
+ ],
+};
diff --git a/src/test/rustdoc-js/struct-like-variant.rs b/src/test/rustdoc-js/struct-like-variant.rs
new file mode 100644
index 0000000000000..9c000a44ab10d
--- /dev/null
+++ b/src/test/rustdoc-js/struct-like-variant.rs
@@ -0,0 +1,5 @@
+#![crate_name = "struct_like_variant"]
+
+pub enum Enum {
+ Bar { name: String }
+}