diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e20cae036a375..538737e7fe4d9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3118,6 +3118,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId { Def::Struct(i) => (i, TypeKind::Struct), Def::Union(i) => (i, TypeKind::Union), Def::Mod(i) => (i, TypeKind::Module), + Def::TyForeign(i) => (i, TypeKind::Foreign), Def::Static(i, _) => (i, TypeKind::Static), Def::Variant(i) => (cx.tcx.parent_def_id(i).unwrap(), TypeKind::Enum), Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index b55076a01afe0..fe1dac36be1f9 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -306,6 +306,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { Def::Struct(did) | Def::Union(did) | Def::Enum(did) | + Def::TyForeign(did) | Def::TyAlias(did) if !self_is_hidden => { self.cx.access_levels.borrow_mut().map.insert(did, AccessLevel::Public); }, @@ -348,6 +349,17 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.inlining = prev; true } + hir_map::NodeForeignItem(it) if !glob => { + // generate a fresh `extern {}` block if we want to inline a foreign item. + om.foreigns.push(hir::ForeignMod { + abi: tcx.hir.get_foreign_abi(it.id), + items: vec![hir::ForeignItem { + name: renamed.unwrap_or(it.name), + .. it.clone() + }].into(), + }); + true + } _ => false, }; self.view_item_stack.remove(&def_node_id); diff --git a/src/test/rustdoc/foreigntype-reexport.rs b/src/test/rustdoc/foreigntype-reexport.rs new file mode 100644 index 0000000000000..714222de529ee --- /dev/null +++ b/src/test/rustdoc/foreigntype-reexport.rs @@ -0,0 +1,66 @@ +// Copyright 2017 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. + +#![feature(extern_types)] + +mod sub { + extern { + /// Another extern type. + pub type C2; + pub fn f2(); + pub static K: usize; + } +} + +pub mod sub2 { + extern { + // @has foreigntype_reexport/sub2/foreigntype.C.html + pub type C; + // @has foreigntype_reexport/sub2/fn.f.html + pub fn f(); + // @has foreigntype_reexport/sub2/static.K3.html + pub static K3: usize; + } +} + +mod sub3 { + extern { + pub type C4; + pub fn f4(); + pub static K4: usize; + type X4; + } +} + +// @has foreigntype_reexport/foreigntype.C2.html +// @has foreigntype_reexport/fn.f2.html +// @has foreigntype_reexport/static.K2.html +// @has foreigntype_reexport/index.html '//a[@class="foreigntype"]' 'C2' +// @has foreigntype_reexport/index.html '//a[@class="fn"]' 'f2' +// @has foreigntype_reexport/index.html '//a[@class="static"]' 'K2' +pub use self::sub::{C2, f2, K as K2}; + +// @has foreigntype_reexport/index.html '//a[@class="foreigntype"]' 'C' +// @has foreigntype_reexport/index.html '//a[@class="fn"]' 'f' +// @has foreigntype_reexport/index.html '//a[@class="static"]' 'K3' +// @has foreigntype_reexport/index.html '//code' 'pub use self::sub2::C as C3;' +// @has foreigntype_reexport/index.html '//code' 'pub use self::sub2::f as f3;' +// @has foreigntype_reexport/index.html '//code' 'pub use self::sub2::K3;' +pub use self::sub2::{C as C3, f as f3, K3}; + +// @has foreigntype_reexport/foreigntype.C4.html +// @has foreigntype_reexport/fn.f4.html +// @has foreigntype_reexport/static.K4.html +// @!has foreigntype_reexport/foreigntype.X4.html +// @has foreigntype_reexport/index.html '//a[@class="foreigntype"]' 'C4' +// @has foreigntype_reexport/index.html '//a[@class="fn"]' 'f4' +// @has foreigntype_reexport/index.html '//a[@class="static"]' 'K4' +// @!has foreigntype_reexport/index.html '//a[@class="foreigntype"]' 'X4' +pub use self::sub3::*;