diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 8a6abe036dc14..df72bf0b56e61 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -445,12 +445,41 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) // two namespaces, so the target may be listed twice. Make sure we only // visit each node at most once. for &item in cx.tcx.item_children(did).iter() { - let def_id = item.res.def_id(); if item.vis == ty::Visibility::Public { - if did == def_id || !visited.insert(def_id) { - continue; + if let Some(def_id) = item.res.mod_def_id() { + if did == def_id || !visited.insert(def_id) { + continue; + } } - if let Some(i) = try_inline(cx, item.res, item.ident.name, None, visited) { + if let Res::PrimTy(p) = item.res { + // Primitive types can't be inlined so generate an import instead. + items.push(clean::Item { + name: None, + attrs: clean::Attributes::default(), + source: clean::Span::empty(), + def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID), + visibility: clean::Public, + stability: None, + deprecation: None, + inner: clean::ImportItem(clean::Import::Simple( + item.ident.to_string(), + clean::ImportSource { + path: clean::Path { + global: false, + res: item.res, + segments: vec![clean::PathSegment { + name: clean::PrimitiveType::from(p).as_str().to_string(), + args: clean::GenericArgs::AngleBracketed { + args: Vec::new(), + bindings: Vec::new(), + }, + }], + }, + did: None, + }, + )), + }); + } else if let Some(i) = try_inline(cx, item.res, item.ident.name, None, visited) { items.extend(i) } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 79a078ca7a991..8501fee56cfae 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1290,6 +1290,19 @@ impl From for PrimitiveType { } } +impl From for PrimitiveType { + fn from(prim_ty: hir::PrimTy) -> PrimitiveType { + match prim_ty { + hir::PrimTy::Int(int_ty) => int_ty.into(), + hir::PrimTy::Uint(uint_ty) => uint_ty.into(), + hir::PrimTy::Float(float_ty) => float_ty.into(), + hir::PrimTy::Str => PrimitiveType::Str, + hir::PrimTy::Bool => PrimitiveType::Bool, + hir::PrimTy::Char => PrimitiveType::Char, + } + } +} + #[derive(Clone, PartialEq, Eq, Debug)] pub enum Visibility { Public, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8058536d60b31..b6a39c7422fdc 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -570,14 +570,7 @@ pub fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type { } let is_generic = match path.res { - Res::PrimTy(p) => match p { - hir::PrimTy::Str => return Primitive(PrimitiveType::Str), - hir::PrimTy::Bool => return Primitive(PrimitiveType::Bool), - hir::PrimTy::Char => return Primitive(PrimitiveType::Char), - hir::PrimTy::Int(int_ty) => return Primitive(int_ty.into()), - hir::PrimTy::Uint(uint_ty) => return Primitive(uint_ty.into()), - hir::PrimTy::Float(float_ty) => return Primitive(float_ty.into()), - }, + Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)), Res::SelfTy(..) if path.segments.len() == 1 => { return Generic(kw::SelfUpper.to_string()); } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 79923fc3d3689..c3313ba63ef13 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1171,11 +1171,14 @@ impl clean::ImportSource { display_fn(move |f| match self.did { Some(did) => resolved_path(f, did, &self.path, true, false), _ => { - for (i, seg) in self.path.segments.iter().enumerate() { - if i > 0 { - write!(f, "::")? - } - write!(f, "{}", seg.name)?; + for seg in &self.path.segments[..self.path.segments.len() - 1] { + write!(f, "{}::", seg.name)?; + } + let name = self.path.last_name(); + if let hir::def::Res::PrimTy(p) = self.path.res { + primitive_link(f, PrimitiveType::from(p), name)?; + } else { + write!(f, "{}", name)?; } Ok(()) } diff --git a/src/test/rustdoc/auxiliary/primitive-reexport.rs b/src/test/rustdoc/auxiliary/primitive-reexport.rs new file mode 100644 index 0000000000000..b2e9fa43b395a --- /dev/null +++ b/src/test/rustdoc/auxiliary/primitive-reexport.rs @@ -0,0 +1,8 @@ +// compile-flags: --emit metadata --crate-type lib --edition 2018 + +#![crate_name = "foo"] + +pub mod bar { + pub use bool; + pub use char as my_char; +} diff --git a/src/test/rustdoc/primitive-reexport.rs b/src/test/rustdoc/primitive-reexport.rs new file mode 100644 index 0000000000000..de18360d4077c --- /dev/null +++ b/src/test/rustdoc/primitive-reexport.rs @@ -0,0 +1,28 @@ +// aux-build: primitive-reexport.rs +// compile-flags:--extern foo --edition 2018 + +#![crate_name = "bar"] + +// @has bar/p/index.html +// @has - '//code' 'pub use bool;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'bool' +// @has - '//code' 'pub use char as my_char;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char' +pub mod p { + pub use foo::bar::*; +} + +// @has bar/baz/index.html +// @has - '//code' 'pub use bool;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'bool' +// @has - '//code' 'pub use char as my_char;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char' +pub use foo::bar as baz; + +// @has bar/index.html +// @has - '//code' 'pub use str;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html"]' 'str' +// @has - '//code' 'pub use i32 as my_i32;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i32.html"]' 'i32' +pub use str; +pub use i32 as my_i32;