Change:
When re-exporting a primitive type, rustdoc ICEs. This was found when creating . Rustdoc also fails to link the re-export to the primitive docs. Reproduction: commands: Backtrace:
I plan on investigating this issue tomorrow, as it is likely a blocker for
-- this is blocking , and I was unable to come up with a simple patch to fix this. Is this a known-hard problem, or should I try to keep digging? contains my initial patch, but it fails tests (e.g., auto impls for primitives, among other problems).
I'll try to take a look shortly. And no, never heard of it before you opened this issue. Don't hesitate to ping me if I forget.

Discussion:
// 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() { <del> let def_id = item.res.def_id(); </del> if item.vis == ty::Visibility::Public { <del> if did == def_id || !visited.insert(def_id) { continue; </del> <ins> if let Some(def_id) = item.res.mod_def_id() { if did == def_id || !visited.insert(def_id) { continue; } </ins> } <del> if let Some(i) = try_inline(cx, item.res, item.ident.name, None, visited) { </del> <ins> 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) { </ins> items.extend(i) } }

} } <ins> impl From<hir::PrimTy> 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, } } } </ins> #[derive(Clone, PartialEq, Eq, Debug)] pub enum Visibility { Public,

} let is_generic = match path.res { <del> 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()), }, </del> <ins> Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)), </ins> Res::SelfTy(..) if path.segments.len() == 1 => { return Generic(kw::SelfUpper.to_string()); }

display_fn(move |f| match self.did { Some(did) => resolved_path(f, did, &self.path, true, false), _ => { <del> for (i, seg) in self.path.segments.iter().enumerate() { if i > 0 { write!(f, "::")? } write!(f, "{}", seg.name)?; </del> <ins> 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)?; </ins> } Ok(()) }

<ins> // compile-flags: --emit metadata --crate-type lib --edition 2018 #![crate_name = "foo"] pub mod bar { pub use bool; pub use char as my_char; } </ins>

<ins> // 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; </ins>