Skip to content

Commit

Permalink
rustdoc: support methods on primitives in intra-doc links
Browse files Browse the repository at this point in the history
  • Loading branch information
tspiteri committed Feb 22, 2019
1 parent 1005f3b commit bba0ea2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,11 +974,13 @@ impl Attributes {
"https://doc.rust-lang.org/nightly",
};
// This is a primitive so the url is done "by hand".
let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
Some((s.clone(),
format!("{}{}std/primitive.{}.html",
format!("{}{}std/primitive.{}.html{}",
url,
if !url.ends_with('/') { "/" } else { "" },
fragment)))
&fragment[..tail],
&fragment[tail..])))
} else {
panic!("This isn't a primitive?!");
}
Expand Down
35 changes: 35 additions & 0 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc::lint as lint;
use rustc::hir;
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::ty;
use syntax;
use syntax::ast::{self, Ident, NodeId};
Expand Down Expand Up @@ -126,6 +127,17 @@ impl<'a, 'tcx, 'rcx> LinkCollector<'a, 'tcx, 'rcx> {
path = name.clone();
}
}
if let Some(prim) = is_primitive(&path, false) {
let did = primitive_impl(cx, &path).ok_or(())?;
return cx.tcx.associated_items(did)
.find(|item| item.ident.name == item_name)
.and_then(|item| match item.kind {
ty::AssociatedKind::Method => Some("method"),
_ => None,
})
.map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name))))
.ok_or(());
}

// FIXME: `with_scope` requires the `NodeId` of a module.
let ty = cx.resolver.borrow_mut()
Expand Down Expand Up @@ -603,3 +615,26 @@ fn is_primitive(path_str: &str, is_val: bool) -> Option<Def> {
PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1)
}
}

fn primitive_impl(cx: &DocContext, path_str: &str) -> Option<DefId> {
let tcx = cx.tcx;
match path_str {
"u8" => tcx.lang_items().u8_impl(),
"u16" => tcx.lang_items().u16_impl(),
"u32" => tcx.lang_items().u32_impl(),
"u64" => tcx.lang_items().u64_impl(),
"u128" => tcx.lang_items().u128_impl(),
"usize" => tcx.lang_items().usize_impl(),
"i8" => tcx.lang_items().i8_impl(),
"i16" => tcx.lang_items().i16_impl(),
"i32" => tcx.lang_items().i32_impl(),
"i64" => tcx.lang_items().i64_impl(),
"i128" => tcx.lang_items().i128_impl(),
"isize" => tcx.lang_items().isize_impl(),
"f32" => tcx.lang_items().f32_impl(),
"f64" => tcx.lang_items().f64_impl(),
"str" => tcx.lang_items().str_impl(),
"char" => tcx.lang_items().char_impl(),
_ => None,
}
}
3 changes: 3 additions & 0 deletions src/test/rustdoc/intra-link-prim-methods.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#![deny(intra_doc_link_resolution_failure)]

//! A [`char`] and its [`char::len_utf8`].

0 comments on commit bba0ea2

Please sign in to comment.