diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index da792b363f0..23215fd9d47 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -38,7 +38,7 @@ use rustc_trans::back::link; use rustc::middle::cstore::{self, CrateStore}; use rustc::middle::privacy::AccessLevels; use rustc::hir::def::Def; -use rustc::hir::def_id::{DefId, DefIndex}; +use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::ty::subst::{self, ParamSpace, VecPerParamSpace}; use rustc::ty; use rustc::middle::stability; @@ -2388,7 +2388,7 @@ impl Clean for doctree::ExternCrate { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.map.local_def_id(0), + def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX }, visibility: self.vis.clean(cx), stability: None, deprecation: None, diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 2db4b779eed..408782a698a 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -232,6 +232,7 @@ pub struct Macro { pub struct ExternCrate { pub name: Name, + pub cnum: ast::CrateNum, pub path: Option, pub vis: hir::Visibility, pub attrs: hir::HirVec, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 26d82ccea5b..739da1b49d4 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -57,6 +57,11 @@ pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]); pub struct CommaSep<'a, T: 'a>(pub &'a [T]); pub struct AbiSpace(pub Abi); +pub struct HRef<'a> { + pub did: DefId, + pub text: &'a str, +} + impl<'a> VisSpace<'a> { pub fn get(self) -> &'a Option { let VisSpace(v) = self; v @@ -363,15 +368,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, } } } - - match href(did) { - Some((url, shortty, fqp)) => { - write!(w, "{}", - shortty, url, fqp.join("::"), last.name)?; - } - _ => write!(w, "{}", last.name)?, - } - write!(w, "{}", last.params)?; + write!(w, "{}{}", HRef::new(did, &last.name), last.params)?; Ok(()) } @@ -437,6 +434,24 @@ fn tybounds(w: &mut fmt::Formatter, } } +impl<'a> HRef<'a> { + pub fn new(did: DefId, text: &'a str) -> HRef<'a> { + HRef { did: did, text: text } + } +} + +impl<'a> fmt::Display for HRef<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match href(self.did) { + Some((url, shortty, fqp)) => { + write!(f, "{}", + shortty, url, fqp.join("::"), self.text) + } + _ => write!(f, "{}", self.text), + } + } +} + impl fmt::Display for clean::Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 1cede9e6647..a8f1fe7d46f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1739,16 +1739,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, match myitem.inner { clean::ExternCrateItem(ref name, ref src) => { + use html::format::HRef; + match *src { Some(ref src) => { write!(w, "{}extern crate {} as {};", VisSpace(&myitem.visibility), - src, + HRef::new(myitem.def_id, src), name)? } None => { write!(w, "{}extern crate {};", - VisSpace(&myitem.visibility), name)? + VisSpace(&myitem.visibility), + HRef::new(myitem.def_id, name))? } } write!(w, "")?; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 2bce8f4c2a1..d9ea82acbea 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -316,7 +316,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let name = renamed.unwrap_or(item.name); match item.node { hir::ItemExternCrate(ref p) => { + let cstore = &self.cx.sess().cstore; om.extern_crates.push(ExternCrate { + cnum: cstore.extern_mod_stmt_cnum(item.id) + .unwrap_or(ast::CrateNum::max_value()), name: name, path: p.map(|x|x.to_string()), vis: item.vis.clone(), diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index f56f4c306f9..f6d89f7c1dc 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -44,6 +44,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> { pub fn visit_lib(&mut self, cnum: ast::CrateNum) { let did = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + self.update(did, Some(AccessLevel::Public)); self.visit_mod(did); } diff --git a/src/test/rustdoc/issue-33178-1.rs b/src/test/rustdoc/issue-33178-1.rs new file mode 100644 index 00000000000..a368d6b68b9 --- /dev/null +++ b/src/test/rustdoc/issue-33178-1.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:empty.rs +// aux-build:variant-struct.rs +// ignore-cross-compile + +// @has issue_33178_1/index.html +// @!has - //a/@title empty +pub extern crate empty; + +// @!has - //a/@title variant_struct +pub extern crate variant_struct as foo; diff --git a/src/test/rustdoc/issue-33178.rs b/src/test/rustdoc/issue-33178.rs new file mode 100644 index 00000000000..2ecb7d9ec44 --- /dev/null +++ b/src/test/rustdoc/issue-33178.rs @@ -0,0 +1,23 @@ +// 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:empty.rs +// aux-build:variant-struct.rs +// build-aux-docs +// ignore-cross-compile + +// @has issue_33178/index.html +// @has - //a/@title empty +// @has - //a/@href ../empty/index.html +pub extern crate empty; + +// @has - //a/@title variant_struct +// @has - //a/@href ../variant_struct/index.html +pub extern crate variant_struct as foo;