diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e49b96cbfd02e..8ffbd6be41878 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -143,8 +143,14 @@ pub fn load_attrs<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) { if let Some(tcx) = cx.tcx_opt() { let crate_name = tcx.sess.cstore.crate_name(did.krate).to_string(); - let relative = tcx.def_path(did).data.into_iter().map(|elem| { - elem.data.to_string() + let relative = tcx.def_path(did).data.into_iter().filter_map(|elem| { + // extern blocks have an empty name + let s = elem.data.to_string(); + if !s.is_empty() { + Some(s) + } else { + None + } }); let fqn = once(crate_name).chain(relative).collect(); cx.renderinfo.borrow_mut().external_paths.insert(did, (fqn, kind)); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 493d3d6abc9f9..0d390a87d2050 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1519,20 +1519,23 @@ impl<'a> Item<'a> { // located, then we return `None`. } else { let cache = cache(); - let path = match cache.external_paths.get(&self.item.def_id) { + let external_path = match cache.external_paths.get(&self.item.def_id) { Some(path) => path, None => return None, }; - let root = match cache.extern_locations.get(&self.item.def_id.krate) { + let mut path = match cache.extern_locations.get(&self.item.def_id.krate) { Some(&(_, Remote(ref s))) => s.to_string(), Some(&(_, Local)) => self.cx.root_path.clone(), Some(&(_, Unknown)) => return None, None => return None, }; - Some(format!("{root}{path}/{file}?gotosrc={goto}", - root = root, - path = path[..path.len() - 1].join("/"), - file = item_path(shortty(self.item), self.item.name.as_ref().unwrap()), + for item in &external_path[..external_path.len() - 1] { + path.push_str(item); + path.push_str("/"); + } + Some(format!("{path}{file}?gotosrc={goto}", + path = path, + file = item_path(shortty(self.item), external_path.last().unwrap()), goto = self.item.def_id.index.as_usize())) } } diff --git a/src/test/rustdoc/auxiliary/issue-34274.rs b/src/test/rustdoc/auxiliary/issue-34274.rs new file mode 100644 index 0000000000000..72026b6085604 --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-34274.rs @@ -0,0 +1,13 @@ +// 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. + +extern { + pub fn extern_c_fn(); +} diff --git a/src/test/rustdoc/auxiliary/src-links-external.rs b/src/test/rustdoc/auxiliary/src-links-external.rs new file mode 100644 index 0000000000000..94b7278e9904b --- /dev/null +++ b/src/test/rustdoc/auxiliary/src-links-external.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/issue-34274.rs b/src/test/rustdoc/issue-34274.rs new file mode 100644 index 0000000000000..971c89b1619ed --- /dev/null +++ b/src/test/rustdoc/issue-34274.rs @@ -0,0 +1,20 @@ +// 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:issue-34274.rs +// build-aux-docs +// ignore-cross-compile + +#![crate_name = "foo"] + +extern crate issue_34274; + +// @has foo/fn.extern_c_fn.html '//a/@href' '../issue_34274/fn.extern_c_fn.html?gotosrc=' +pub use issue_34274::extern_c_fn; diff --git a/src/test/rustdoc/src-links-external.rs b/src/test/rustdoc/src-links-external.rs new file mode 100644 index 0000000000000..e9db4f519ed97 --- /dev/null +++ b/src/test/rustdoc/src-links-external.rs @@ -0,0 +1,22 @@ +// 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:src-links-external.rs +// build-aux-docs +// ignore-cross-compile + +#![crate_name = "foo"] + +extern crate src_links_external; + +// @has foo/bar/index.html '//a/@href' '../src_links_external/index.html?gotosrc=' +pub use src_links_external as bar; + +// @has foo/bar/struct.Foo.html '//a/@href' '../src_links_external/struct.Foo.html?gotosrc='