diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 11c1b8b09d2cc..eed2615175b27 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -19,7 +19,7 @@ use std::fmt;
use std::iter::repeat;
use rustc::middle::cstore::LOCAL_CRATE;
-use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::hir::def_id::DefId;
use syntax::abi::Abi;
use rustc::hir;
@@ -301,18 +301,19 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec)> {
}
let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone());
- let &(ref fqp, shortty) = match cache.paths.get(&did) {
- Some(p) => p,
- None => return None,
- };
-
- let mut url = if did.is_local() || cache.inlined.contains(&did) {
- repeat("../").take(loc.len()).collect::()
- } else {
- match cache.extern_locations[&did.krate] {
- (_, render::Remote(ref s)) => s.to_string(),
- (_, render::Local) => repeat("../").take(loc.len()).collect(),
- (_, render::Unknown) => return None,
+ let (fqp, shortty, mut url) = match cache.paths.get(&did) {
+ Some(&(ref fqp, shortty)) => {
+ (fqp, shortty, repeat("../").take(loc.len()).collect())
+ }
+ None => match cache.external_paths.get(&did) {
+ Some(&(ref fqp, shortty)) => {
+ (fqp, shortty, match cache.extern_locations[&did.krate] {
+ (_, render::Remote(ref s)) => s.to_string(),
+ (_, render::Local) => repeat("../").take(loc.len()).collect(),
+ (_, render::Unknown) => return None,
+ })
+ }
+ None => return None,
}
};
for component in &fqp[..fqp.len() - 1] {
@@ -387,22 +388,18 @@ fn primitive_link(f: &mut fmt::Formatter,
needs_termination = true;
}
Some(&cnum) => {
- let path = &m.paths[&DefId {
- krate: cnum,
- index: CRATE_DEF_INDEX,
- }];
let loc = match m.extern_locations[&cnum] {
- (_, render::Remote(ref s)) => Some(s.to_string()),
- (_, render::Local) => {
+ (ref cname, render::Remote(ref s)) => Some((cname, s.to_string())),
+ (ref cname, render::Local) => {
let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
- Some(repeat("../").take(len).collect::())
+ Some((cname, repeat("../").take(len).collect::()))
}
(_, render::Unknown) => None,
};
- if let Some(root) = loc {
+ if let Some((cname, root)) = loc {
write!(f, "",
root,
- path.0.first().unwrap(),
+ cname,
prim.to_url_str())?;
needs_termination = true;
}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c263bcb04e9b6..2e2fc011ddbe6 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -230,7 +230,7 @@ pub struct Cache {
/// Similar to `paths`, but only holds external paths. This is only used for
/// generating explicit hyperlinks to other crates.
- pub external_paths: HashMap>,
+ pub external_paths: HashMap, ItemType)>,
/// This map contains information about all known traits of this crate.
/// Implementations of a crate should inherit the documentation of the
@@ -249,9 +249,6 @@ pub struct Cache {
/// Cache of where documentation for primitives can be found.
pub primitive_locations: HashMap,
- /// Set of definitions which have been inlined from external crates.
- pub inlined: HashSet,
-
// Note that external items for which `doc(hidden)` applies to are shown as
// non-reachable while local items aren't. This is because we're reusing
// the access levels from crateanalysis.
@@ -505,20 +502,20 @@ pub fn run(mut krate: clean::Crate,
// Crawl the crate to build various caches used for the output
let RenderInfo {
- inlined,
+ inlined: _,
external_paths,
external_typarams,
deref_trait_did,
} = renderinfo;
- let paths = external_paths.into_iter()
- .map(|(k, (v, t))| (k, (v, ItemType::from_type_kind(t))))
- .collect::>();
+ let external_paths = external_paths.into_iter()
+ .map(|(k, (v, t))| (k, (v, ItemType::from_type_kind(t))))
+ .collect();
let mut cache = Cache {
impls: HashMap::new(),
- external_paths: paths.iter().map(|(&k, v)| (k, v.0.clone())).collect(),
- paths: paths,
+ external_paths: external_paths,
+ paths: HashMap::new(),
implementors: HashMap::new(),
stack: Vec::new(),
parent_stack: Vec::new(),
@@ -534,7 +531,6 @@ pub fn run(mut krate: clean::Crate,
traits: mem::replace(&mut krate.external_traits, HashMap::new()),
deref_trait_did: deref_trait_did,
typarams: external_typarams,
- inlined: inlined,
};
// Cache where all our extern crates are located
@@ -542,7 +538,7 @@ pub fn run(mut krate: clean::Crate,
cache.extern_locations.insert(n, (e.name.clone(),
extern_location(e, &cx.dst)));
let did = DefId { krate: n, index: CRATE_DEF_INDEX };
- cache.paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
+ cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
}
// Cache where all known primitives have their documentation located.
@@ -753,7 +749,10 @@ fn write_shared(cx: &Context,
// theory it should be...
let &(ref remote_path, remote_item_type) = match cache.paths.get(&did) {
Some(p) => p,
- None => continue,
+ None => match cache.external_paths.get(&did) {
+ Some(p) => p,
+ None => continue,
+ }
};
let mut mydst = dst.clone();
@@ -1055,12 +1054,11 @@ impl DocFolder for Cache {
let last = self.parent_stack.last().unwrap();
let did = *last;
let path = match self.paths.get(&did) {
- Some(&(_, ItemType::Trait)) =>
- Some(&self.stack[..self.stack.len() - 1]),
// The current stack not necessarily has correlation
// for where the type was defined. On the other
// hand, `paths` always has the right
// information if present.
+ Some(&(ref fqp, ItemType::Trait)) |
Some(&(ref fqp, ItemType::Struct)) |
Some(&(ref fqp, ItemType::Enum)) =>
Some(&fqp[..fqp.len() - 1]),
@@ -1092,12 +1090,10 @@ impl DocFolder for Cache {
});
}
}
- (Some(parent), None) if is_method || (!self.stripped_mod)=> {
- if parent.is_local() {
- // We have a parent, but we don't know where they're
- // defined yet. Wait for later to index this item.
- self.orphan_methods.push((parent, item.clone()))
- }
+ (Some(parent), None) if is_method => {
+ // We have a parent, but we don't know where they're
+ // defined yet. Wait for later to index this item.
+ self.orphan_methods.push((parent, item.clone()));
}
_ => {}
}
@@ -1127,7 +1123,6 @@ impl DocFolder for Cache {
// not a public item.
if
!self.paths.contains_key(&item.def_id) ||
- !item.def_id.is_local() ||
self.access_levels.is_public(item.def_id)
{
self.paths.insert(item.def_id,
@@ -1521,7 +1516,7 @@ impl<'a> Item<'a> {
} else {
let cache = cache();
let external_path = match cache.external_paths.get(&self.item.def_id) {
- Some(path) => path,
+ Some(&(ref path, _)) => path,
None => return None,
};
let mut path = match cache.extern_locations.get(&self.item.def_id.krate) {
@@ -2106,7 +2101,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
path = if it.def_id.is_local() {
cx.current.join("/")
} else {
- let path = &cache.external_paths[&it.def_id];
+ let (ref path, _) = cache.external_paths[&it.def_id];
path[..path.len() - 1].join("/")
},
ty = shortty(it).to_static_str(),
diff --git a/src/test/rustdoc/auxiliary/extern-links.rs b/src/test/rustdoc/auxiliary/extern-links.rs
new file mode 100644
index 0000000000000..94b7278e9904b
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/extern-links.rs
@@ -0,0 +1,11 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Foo;
diff --git a/src/test/rustdoc/extern-links.rs b/src/test/rustdoc/extern-links.rs
new file mode 100644
index 0000000000000..c35a5668dced7
--- /dev/null
+++ b/src/test/rustdoc/extern-links.rs
@@ -0,0 +1,31 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:extern-links.rs
+// ignore-cross-compile
+
+#![crate_name = "foo"]
+
+extern crate extern_links;
+
+// @!has foo/index.html '//a' 'extern_links'
+#[doc(no_inline)]
+pub use extern_links as extern_links2;
+
+// @!has foo/index.html '//a' 'Foo'
+#[doc(no_inline)]
+pub use extern_links::Foo;
+
+#[doc(hidden)]
+pub mod hidden {
+ // @!has foo/hidden/extern_links/index.html
+ // @!has foo/hidden/extern_links/struct.Foo.html
+ pub use extern_links;
+}