Skip to content

Commit 18d211e

Browse files
Fix panic when reexporting primitive type in rustdoc
1 parent ee84c30 commit 18d211e

File tree

6 files changed

+92
-46
lines changed

6 files changed

+92
-46
lines changed

src/librustc_hir/def.rs

+7
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,11 @@ impl<Id> Res<Id> {
427427
Res::Err => true,
428428
}
429429
}
430+
431+
pub fn is_primitive(&self) -> bool {
432+
match self {
433+
Res::PrimTy(..) => true,
434+
_ => false,
435+
}
436+
}
430437
}

src/librustdoc/clean/inline.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,20 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>)
428428
// two namespaces, so the target may be listed twice. Make sure we only
429429
// visit each node at most once.
430430
for &item in cx.tcx.item_children(did).iter() {
431-
let def_id = item.res.def_id();
431+
eprintln!("==> {:?}", item.res);
432+
let def_id = match clean::utils::res_to_def_id(cx, &item.res) {
433+
Some(did) => did,
434+
None => continue,
435+
};
436+
eprintln!("TOUDOUM ==> {:?} {:?}", item.res, item.vis);
432437
if item.vis == ty::Visibility::Public {
433438
if did == def_id || !visited.insert(def_id) {
439+
eprintln!("1");
434440
continue;
435441
}
442+
eprintln!("2");
436443
if let Some(i) = try_inline(cx, item.res, item.ident.name, None, visited) {
444+
eprintln!("3");
437445
items.extend(i)
438446
}
439447
}

src/librustdoc/clean/utils.rs

+57
Original file line numberDiff line numberDiff line change
@@ -652,3 +652,60 @@ where
652652
*cx.impl_trait_bounds.borrow_mut() = old_bounds;
653653
r
654654
}
655+
656+
pub const PRIMITIVES: &[(&str, Res)] = &[
657+
("u8", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U8))),
658+
("u16", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U16))),
659+
("u32", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U32))),
660+
("u64", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U64))),
661+
("u128", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U128))),
662+
("usize", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::Usize))),
663+
("i8", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I8))),
664+
("i16", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I16))),
665+
("i32", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I32))),
666+
("i64", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I64))),
667+
("i128", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I128))),
668+
("isize", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::Isize))),
669+
("f32", Res::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F32))),
670+
("f64", Res::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F64))),
671+
("str", Res::PrimTy(hir::PrimTy::Str)),
672+
("bool", Res::PrimTy(hir::PrimTy::Bool)),
673+
("char", Res::PrimTy(hir::PrimTy::Char)),
674+
];
675+
676+
pub fn res_to_def_id(cx: &DocContext<'_>, res: &Res) -> Option<DefId> {
677+
if res.is_primitive() {
678+
for (path, primitive) in PRIMITIVES.iter() {
679+
if primitive == res {
680+
return primitive_path_impl(cx, path);
681+
}
682+
}
683+
None
684+
} else {
685+
Some(res.def_id())
686+
}
687+
}
688+
689+
pub fn primitive_path_impl(cx: &DocContext<'_>, path_str: &str) -> Option<DefId> {
690+
let tcx = cx.tcx;
691+
match path_str {
692+
"u8" => tcx.lang_items().u8_impl(),
693+
"u16" => tcx.lang_items().u16_impl(),
694+
"u32" => tcx.lang_items().u32_impl(),
695+
"u64" => tcx.lang_items().u64_impl(),
696+
"u128" => tcx.lang_items().u128_impl(),
697+
"usize" => tcx.lang_items().usize_impl(),
698+
"i8" => tcx.lang_items().i8_impl(),
699+
"i16" => tcx.lang_items().i16_impl(),
700+
"i32" => tcx.lang_items().i32_impl(),
701+
"i64" => tcx.lang_items().i64_impl(),
702+
"i128" => tcx.lang_items().i128_impl(),
703+
"isize" => tcx.lang_items().isize_impl(),
704+
"f32" => tcx.lang_items().f32_impl(),
705+
"f64" => tcx.lang_items().f64_impl(),
706+
"str" => tcx.lang_items().str_impl(),
707+
"bool" => tcx.lang_items().bool_impl(),
708+
"char" => tcx.lang_items().char_impl(),
709+
_ => None,
710+
}
711+
}

src/librustdoc/passes/collect_intra_doc_links.rs

+6-45
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
203203
.ok_or(ErrorKind::ResolutionFailure)?;
204204

205205
if let Some(prim) = is_primitive(&path, TypeNS) {
206-
let did = primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?;
206+
let did =
207+
utils::primitive_path_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?;
207208
return cx
208209
.tcx
209210
.associated_items(did)
@@ -888,50 +889,10 @@ fn handle_variant(
888889
Ok((parent_def, Some(format!("{}.v", variant.ident.name))))
889890
}
890891

891-
const PRIMITIVES: &[(&str, Res)] = &[
892-
("u8", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U8))),
893-
("u16", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U16))),
894-
("u32", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U32))),
895-
("u64", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U64))),
896-
("u128", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U128))),
897-
("usize", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::Usize))),
898-
("i8", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I8))),
899-
("i16", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I16))),
900-
("i32", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I32))),
901-
("i64", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I64))),
902-
("i128", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I128))),
903-
("isize", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::Isize))),
904-
("f32", Res::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F32))),
905-
("f64", Res::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F64))),
906-
("str", Res::PrimTy(hir::PrimTy::Str)),
907-
("bool", Res::PrimTy(hir::PrimTy::Bool)),
908-
("char", Res::PrimTy(hir::PrimTy::Char)),
909-
];
910-
911892
fn is_primitive(path_str: &str, ns: Namespace) -> Option<Res> {
912-
if ns == TypeNS { PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1) } else { None }
913-
}
914-
915-
fn primitive_impl(cx: &DocContext<'_>, path_str: &str) -> Option<DefId> {
916-
let tcx = cx.tcx;
917-
match path_str {
918-
"u8" => tcx.lang_items().u8_impl(),
919-
"u16" => tcx.lang_items().u16_impl(),
920-
"u32" => tcx.lang_items().u32_impl(),
921-
"u64" => tcx.lang_items().u64_impl(),
922-
"u128" => tcx.lang_items().u128_impl(),
923-
"usize" => tcx.lang_items().usize_impl(),
924-
"i8" => tcx.lang_items().i8_impl(),
925-
"i16" => tcx.lang_items().i16_impl(),
926-
"i32" => tcx.lang_items().i32_impl(),
927-
"i64" => tcx.lang_items().i64_impl(),
928-
"i128" => tcx.lang_items().i128_impl(),
929-
"isize" => tcx.lang_items().isize_impl(),
930-
"f32" => tcx.lang_items().f32_impl(),
931-
"f64" => tcx.lang_items().f64_impl(),
932-
"str" => tcx.lang_items().str_impl(),
933-
"bool" => tcx.lang_items().bool_impl(),
934-
"char" => tcx.lang_items().char_impl(),
935-
_ => None,
893+
if ns == TypeNS {
894+
utils::PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1)
895+
} else {
896+
None
936897
}
937898
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// compile-flags: --emit metadata --crate-type lib --edition 2018
2+
3+
#![crate_name = "foo"]
4+
5+
pub mod bar {
6+
pub use bool;
7+
}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// aux-build: reexport-primitive.rs
2+
// compile-flags:--extern foo --edition 2018
3+
4+
pub mod p {
5+
pub use foo::bar::*;
6+
}

0 commit comments

Comments
 (0)