From bde4d1945c909883a057f0e1d2a4594f4144a1b7 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Fri, 22 Feb 2019 13:21:42 +0100 Subject: [PATCH] rustdoc: support methods on primitives in intra-doc links --- src/librustdoc/clean/mod.rs | 6 ++-- .../passes/collect_intra_doc_links.rs | 35 +++++++++++++++++++ src/test/rustdoc/intra-link-prim-methods.rs | 3 ++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc/intra-link-prim-methods.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 172bd918062..b094a55a617 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -976,11 +976,13 @@ pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> { "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?!"); } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index cf2c3aa4846..1795f761a82 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -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}; @@ -126,6 +127,17 @@ fn resolve(&self, 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() @@ -589,3 +601,26 @@ fn is_primitive(path_str: &str, is_val: bool) -> Option { PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1) } } + +fn primitive_impl(cx: &DocContext, path_str: &str) -> Option { + 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, + } +} diff --git a/src/test/rustdoc/intra-link-prim-methods.rs b/src/test/rustdoc/intra-link-prim-methods.rs new file mode 100644 index 00000000000..af0426b22c5 --- /dev/null +++ b/src/test/rustdoc/intra-link-prim-methods.rs @@ -0,0 +1,3 @@ +#![deny(intra_doc_link_resolution_failure)] + +//! A [`char`] and its [`char::len_utf8`]. -- GitLab