about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/clean/mod.rs6
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs35
-rw-r--r--src/test/rustdoc/intra-link-prim-methods.rs3
3 files changed, 42 insertions, 2 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2b2a116f8ca..03dff108770 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -976,11 +976,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?!");
                     }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index cf2c3aa4846..42fa3e2006b 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 @@ 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()
@@ -589,3 +601,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,
+    }
+}
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`].