From 967ec1f62360c1e9666568aaddfaf4535718d6df Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:03:38 -0400 Subject: [PATCH 1/9] Refactor `impl_for_type` into a separate function --- src/librustdoc/clean/utils.rs | 63 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index a502a27948e..65dfc7b2481 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::mir::interpret::{sign_extend, ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, DefIdTree, Ty}; +use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use std::mem; @@ -350,8 +350,39 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { s } -pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { +pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option { use self::PrimitiveType::*; + + match primitive { + Isize => tcx.lang_items().isize_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(), + Usize => tcx.lang_items().usize_impl(), + 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(), + F32 => tcx.lang_items().f32_impl(), + F64 => tcx.lang_items().f64_impl(), + Char => tcx.lang_items().char_impl(), + Bool => tcx.lang_items().bool_impl(), + Str => tcx.lang_items().str_impl(), + Slice => tcx.lang_items().slice_impl(), + Array => tcx.lang_items().array_impl(), + Tuple => None, + Unit => None, + RawPointer => tcx.lang_items().const_ptr_impl(), + Reference => None, + Fn => None, + Never => None, + } +} + +pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { let tcx = cx.tcx; for item in items { @@ -370,33 +401,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - let did = match primitive { - Isize => tcx.lang_items().isize_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(), - Usize => tcx.lang_items().usize_impl(), - 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(), - F32 => tcx.lang_items().f32_impl(), - F64 => tcx.lang_items().f64_impl(), - Char => tcx.lang_items().char_impl(), - Bool => tcx.lang_items().bool_impl(), - Str => tcx.lang_items().str_impl(), - Slice => tcx.lang_items().slice_impl(), - Array => tcx.lang_items().array_impl(), - Tuple => None, - Unit => None, - RawPointer => tcx.lang_items().const_ptr_impl(), - Reference => None, - Fn => None, - Never => None, - }; + let did = impl_for_type(tcx, primitive); if let Some(did) = did { if !did.is_local() { inline::build_impl(cx, did, None, ret); From 8a0aa7bd9d65dcc9a052fbbcc95ef40100744092 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:06:46 -0400 Subject: [PATCH 2/9] Say `tcx.lang_items()` less --- src/librustdoc/clean/utils.rs | 41 ++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 65dfc7b2481..7ab2196585f 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -353,29 +353,30 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option { use self::PrimitiveType::*; + let lang_items = tcx.lang_items(); match primitive { - Isize => tcx.lang_items().isize_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(), - Usize => tcx.lang_items().usize_impl(), - 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(), - F32 => tcx.lang_items().f32_impl(), - F64 => tcx.lang_items().f64_impl(), - Char => tcx.lang_items().char_impl(), - Bool => tcx.lang_items().bool_impl(), - Str => tcx.lang_items().str_impl(), - Slice => tcx.lang_items().slice_impl(), - Array => tcx.lang_items().array_impl(), + Isize => lang_items.isize_impl(), + I8 => lang_items.i8_impl(), + I16 => lang_items.i16_impl(), + I32 => lang_items.i32_impl(), + I64 => lang_items.i64_impl(), + I128 => lang_items.i128_impl(), + Usize => lang_items.usize_impl(), + U8 => lang_items.u8_impl(), + U16 => lang_items.u16_impl(), + U32 => lang_items.u32_impl(), + U64 => lang_items.u64_impl(), + U128 => lang_items.u128_impl(), + F32 => lang_items.f32_impl(), + F64 => lang_items.f64_impl(), + Char => lang_items.char_impl(), + Bool => lang_items.bool_impl(), + Str => lang_items.str_impl(), + Slice => lang_items.slice_impl(), + Array => lang_items.array_impl(), Tuple => None, Unit => None, - RawPointer => tcx.lang_items().const_ptr_impl(), + RawPointer => lang_items.const_ptr_impl(), Reference => None, Fn => None, Never => None, From 3ddd8b233c95853dd281493f4c646520354461b5 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:21:31 -0400 Subject: [PATCH 3/9] Return all impls, not just the primary one --- Cargo.lock | 1 + src/librustdoc/Cargo.toml | 1 + src/librustdoc/clean/utils.rs | 41 ++++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 985dbb046d0..fc4e72138e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4106,6 +4106,7 @@ dependencies = [ "rustc-rayon", "serde", "serde_json", + "smallvec 1.4.0", "tempfile", ] diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 4af13e4cd58..1354ef5cbde 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -14,5 +14,6 @@ minifier = "0.0.33" rayon = { version = "0.3.0", package = "rustc-rayon" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +smallvec = "1.0" tempfile = "3" itertools = "0.8" diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 7ab2196585f..969098122bf 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -17,6 +17,7 @@ use rustc_middle::mir::interpret::{sign_extend, ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; +use smallvec::SmallVec; use std::mem; pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { @@ -350,11 +351,14 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { s } -pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option { +pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> SmallVec<[DefId; 4]> { use self::PrimitiveType::*; + let both = + |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; + let lang_items = tcx.lang_items(); - match primitive { + let primary_impl = match primitive { Isize => lang_items.isize_impl(), I8 => lang_items.i8_impl(), I16 => lang_items.i16_impl(), @@ -367,20 +371,38 @@ pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option U32 => lang_items.u32_impl(), U64 => lang_items.u64_impl(), U128 => lang_items.u128_impl(), - F32 => lang_items.f32_impl(), - F64 => lang_items.f64_impl(), + F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), + F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), Char => lang_items.char_impl(), Bool => lang_items.bool_impl(), - Str => lang_items.str_impl(), - Slice => lang_items.slice_impl(), + Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), + Slice => { + return lang_items + .slice_impl() + .into_iter() + .chain(lang_items.slice_u8_impl()) + .chain(lang_items.slice_alloc_impl()) + .chain(lang_items.slice_u8_alloc_impl()) + .collect(); + } Array => lang_items.array_impl(), Tuple => None, Unit => None, - RawPointer => lang_items.const_ptr_impl(), + RawPointer => { + return lang_items + .const_ptr_impl() + .into_iter() + .chain(lang_items.mut_ptr_impl()) + .chain(lang_items.const_slice_ptr_impl()) + .chain(lang_items.mut_slice_ptr_impl()) + .collect(); + } Reference => None, Fn => None, Never => None, - } + }; + + primary_impl.into_iter().collect() } pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { @@ -402,8 +424,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - let did = impl_for_type(tcx, primitive); - if let Some(did) = did { + for did in impl_for_type(tcx, primitive) { if !did.is_local() { inline::build_impl(cx, did, None, ret); } From 06d6d3dff5f95c7ef24954cc3c6c1b8010705378 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:26:10 -0400 Subject: [PATCH 4/9] impl_for_type -> PrimitiveType::impls --- src/librustdoc/clean/types.rs | 57 +++++++++++++++++++++++++++++++++ src/librustdoc/clean/utils.rs | 59 ++--------------------------------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 914dc2e1b88..5b9f4830261 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -19,12 +19,14 @@ use rustc_hir::lang_items; use rustc_hir::Mutability; use rustc_index::vec::IndexVec; use rustc_middle::middle::stability; +use rustc_middle::ty::TyCtxt; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, FileName}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; +use smallvec::SmallVec; use crate::clean::cfg::Cfg; use crate::clean::external_path; @@ -1264,6 +1266,61 @@ impl PrimitiveType { } } + pub fn impls(&self, tcx: TyCtxt<'_>) -> SmallVec<[DefId; 4]> { + use self::PrimitiveType::*; + + let both = + |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; + + let lang_items = tcx.lang_items(); + let primary_impl = match self { + Isize => lang_items.isize_impl(), + I8 => lang_items.i8_impl(), + I16 => lang_items.i16_impl(), + I32 => lang_items.i32_impl(), + I64 => lang_items.i64_impl(), + I128 => lang_items.i128_impl(), + Usize => lang_items.usize_impl(), + U8 => lang_items.u8_impl(), + U16 => lang_items.u16_impl(), + U32 => lang_items.u32_impl(), + U64 => lang_items.u64_impl(), + U128 => lang_items.u128_impl(), + F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), + F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), + Char => lang_items.char_impl(), + Bool => lang_items.bool_impl(), + Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), + Slice => { + return lang_items + .slice_impl() + .into_iter() + .chain(lang_items.slice_u8_impl()) + .chain(lang_items.slice_alloc_impl()) + .chain(lang_items.slice_u8_alloc_impl()) + .collect(); + } + Array => lang_items.array_impl(), + Tuple => None, + Unit => None, + RawPointer => { + return lang_items + .const_ptr_impl() + .into_iter() + .chain(lang_items.mut_ptr_impl()) + .chain(lang_items.const_slice_ptr_impl()) + .chain(lang_items.mut_slice_ptr_impl()) + .collect(); + } + Reference => None, + Fn => None, + Never => None, + }; + + primary_impl.into_iter().collect() + } + + pub fn to_url_str(&self) -> &'static str { self.as_str() } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 969098122bf..b80ac0384fd 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -15,9 +15,8 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::mir::interpret::{sign_extend, ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, Ty}; use rustc_span::symbol::{kw, sym, Symbol}; -use smallvec::SmallVec; use std::mem; pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { @@ -351,60 +350,6 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { s } -pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> SmallVec<[DefId; 4]> { - use self::PrimitiveType::*; - - let both = - |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; - - let lang_items = tcx.lang_items(); - let primary_impl = match primitive { - Isize => lang_items.isize_impl(), - I8 => lang_items.i8_impl(), - I16 => lang_items.i16_impl(), - I32 => lang_items.i32_impl(), - I64 => lang_items.i64_impl(), - I128 => lang_items.i128_impl(), - Usize => lang_items.usize_impl(), - U8 => lang_items.u8_impl(), - U16 => lang_items.u16_impl(), - U32 => lang_items.u32_impl(), - U64 => lang_items.u64_impl(), - U128 => lang_items.u128_impl(), - F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), - F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), - Char => lang_items.char_impl(), - Bool => lang_items.bool_impl(), - Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), - Slice => { - return lang_items - .slice_impl() - .into_iter() - .chain(lang_items.slice_u8_impl()) - .chain(lang_items.slice_alloc_impl()) - .chain(lang_items.slice_u8_alloc_impl()) - .collect(); - } - Array => lang_items.array_impl(), - Tuple => None, - Unit => None, - RawPointer => { - return lang_items - .const_ptr_impl() - .into_iter() - .chain(lang_items.mut_ptr_impl()) - .chain(lang_items.const_slice_ptr_impl()) - .chain(lang_items.mut_slice_ptr_impl()) - .collect(); - } - Reference => None, - Fn => None, - Never => None, - }; - - primary_impl.into_iter().collect() -} - pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { let tcx = cx.tcx; @@ -424,7 +369,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - for did in impl_for_type(tcx, primitive) { + for did in primitive.impls(tcx) { if !did.is_local() { inline::build_impl(cx, did, None, ret); } From 9cf2fa84e8dfbbeb01d4d06fabd921300c58ade0 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:45:18 -0400 Subject: [PATCH 5/9] Allow reusing the code in `collect_trait_impls` --- src/librustdoc/clean/types.rs | 131 +++++++++++-------- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/lib.rs | 1 + src/librustdoc/passes/collect_trait_impls.rs | 35 +---- 4 files changed, 81 insertions(+), 88 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5b9f4830261..62f71514fcf 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -7,6 +7,7 @@ use std::num::NonZeroU32; use std::rc::Rc; use std::sync::Arc; use std::{slice, vec}; +use std::lazy::SyncOnceCell as OnceCell; use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; @@ -26,7 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, FileName}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; -use smallvec::SmallVec; +use smallvec::{SmallVec, smallvec}; use crate::clean::cfg::Cfg; use crate::clean::external_path; @@ -1266,60 +1267,84 @@ impl PrimitiveType { } } - pub fn impls(&self, tcx: TyCtxt<'_>) -> SmallVec<[DefId; 4]> { - use self::PrimitiveType::*; - - let both = - |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; - - let lang_items = tcx.lang_items(); - let primary_impl = match self { - Isize => lang_items.isize_impl(), - I8 => lang_items.i8_impl(), - I16 => lang_items.i16_impl(), - I32 => lang_items.i32_impl(), - I64 => lang_items.i64_impl(), - I128 => lang_items.i128_impl(), - Usize => lang_items.usize_impl(), - U8 => lang_items.u8_impl(), - U16 => lang_items.u16_impl(), - U32 => lang_items.u32_impl(), - U64 => lang_items.u64_impl(), - U128 => lang_items.u128_impl(), - F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), - F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), - Char => lang_items.char_impl(), - Bool => lang_items.bool_impl(), - Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), - Slice => { - return lang_items - .slice_impl() - .into_iter() - .chain(lang_items.slice_u8_impl()) - .chain(lang_items.slice_alloc_impl()) - .chain(lang_items.slice_u8_alloc_impl()) - .collect(); - } - Array => lang_items.array_impl(), - Tuple => None, - Unit => None, - RawPointer => { - return lang_items - .const_ptr_impl() - .into_iter() - .chain(lang_items.mut_ptr_impl()) - .chain(lang_items.const_slice_ptr_impl()) - .chain(lang_items.mut_slice_ptr_impl()) - .collect(); - } - Reference => None, - Fn => None, - Never => None, - }; - - primary_impl.into_iter().collect() + pub fn impls(&self, tcx: TyCtxt<'_>) -> &SmallVec<[DefId; 4]> { + Self::all_impls(tcx).get(self).expect("missing impl for primitive type") } + pub fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap> { + static CELL: OnceCell>> = OnceCell::new(); + + CELL.get_or_init(move || { + use self::PrimitiveType::*; + + /// A macro to create a FxHashMap. + /// + /// Example: + /// + /// ``` + /// let letters = map!{"a" => "b", "c" => "d"}; + /// ``` + /// + /// Trailing commas are allowed. + /// Commas between elements are required (even if the expression is a block). + macro_rules! map { + ($( $key: expr => $val: expr ),* $(,)*) => {{ + let mut map = ::rustc_data_structures::fx::FxHashMap::default(); + $( map.insert($key, $val); )* + map + }} + } + + let single = |a: Option| a.into_iter().collect(); + let both = + |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; + + let lang_items = tcx.lang_items(); + map! { + Isize => single(lang_items.isize_impl()), + I8 => single(lang_items.i8_impl()), + I16 => single(lang_items.i16_impl()), + I32 => single(lang_items.i32_impl()), + I64 => single(lang_items.i64_impl()), + I128 => single(lang_items.i128_impl()), + Usize => single(lang_items.usize_impl()), + U8 => single(lang_items.u8_impl()), + U16 => single(lang_items.u16_impl()), + U32 => single(lang_items.u32_impl()), + U64 => single(lang_items.u64_impl()), + U128 => single(lang_items.u128_impl()), + F32 => both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), + F64 => both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), + Char => single(lang_items.char_impl()), + Bool => single(lang_items.bool_impl()), + Str => both(lang_items.str_impl(), lang_items.str_alloc_impl()), + Slice => { + lang_items + .slice_impl() + .into_iter() + .chain(lang_items.slice_u8_impl()) + .chain(lang_items.slice_alloc_impl()) + .chain(lang_items.slice_u8_alloc_impl()) + .collect() + }, + Array => single(lang_items.array_impl()), + Tuple => smallvec![], + Unit => smallvec![], + RawPointer => { + lang_items + .const_ptr_impl() + .into_iter() + .chain(lang_items.mut_ptr_impl()) + .chain(lang_items.const_slice_ptr_impl()) + .chain(lang_items.mut_slice_ptr_impl()) + .collect() + }, + Reference => smallvec![], + Fn => smallvec![], + Never => smallvec![], + } + }) + } pub fn to_url_str(&self) -> &'static str { self.as_str() diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index b80ac0384fd..75fdcd5ec1c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -369,7 +369,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - for did in primitive.impls(tcx) { + for &did in primitive.impls(tcx) { if !did.is_local() { inline::build_impl(cx, did, None, ret); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d5f7ddcbdfb..3dfa7b529e3 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -12,6 +12,7 @@ #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] #![feature(never_type)] +#![feature(once_cell)] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index a40b45f9a7e..24baff46dcf 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -34,40 +34,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { } // Also try to inline primitive impls from other crates. - let lang_items = cx.tcx.lang_items(); - let primitive_impls = [ - lang_items.isize_impl(), - lang_items.i8_impl(), - lang_items.i16_impl(), - lang_items.i32_impl(), - lang_items.i64_impl(), - lang_items.i128_impl(), - lang_items.usize_impl(), - lang_items.u8_impl(), - lang_items.u16_impl(), - lang_items.u32_impl(), - lang_items.u64_impl(), - lang_items.u128_impl(), - lang_items.f32_impl(), - lang_items.f64_impl(), - lang_items.f32_runtime_impl(), - lang_items.f64_runtime_impl(), - lang_items.bool_impl(), - lang_items.char_impl(), - lang_items.str_impl(), - lang_items.array_impl(), - lang_items.slice_impl(), - lang_items.slice_u8_impl(), - lang_items.str_alloc_impl(), - lang_items.slice_alloc_impl(), - lang_items.slice_u8_alloc_impl(), - lang_items.const_ptr_impl(), - lang_items.mut_ptr_impl(), - lang_items.const_slice_ptr_impl(), - lang_items.mut_slice_ptr_impl(), - ]; - - for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) { + for &def_id in PrimitiveType::all_impls(cx.tcx).values().flatten() { if !def_id.is_local() { inline::build_impl(cx, def_id, None, &mut new_items); From 219e93d91e417f76e0071e42c78edc00f7f2cd4b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:54:29 -0400 Subject: [PATCH 6/9] Use `impls` for intra doc links as well --- Cargo.lock | 2 +- src/librustdoc/clean/types.rs | 2 +- .../passes/collect_intra_doc_links.rs | 52 +++++++------------ 3 files changed, 20 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc4e72138e7..f8fa2971b49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4106,7 +4106,7 @@ dependencies = [ "rustc-rayon", "serde", "serde_json", - "smallvec 1.4.0", + "smallvec 1.4.2", "tempfile", ] diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 62f71514fcf..344d5603d76 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1267,7 +1267,7 @@ impl PrimitiveType { } } - pub fn impls(&self, tcx: TyCtxt<'_>) -> &SmallVec<[DefId; 4]> { + pub fn impls(&self, tcx: TyCtxt<'_>) -> &'static SmallVec<[DefId; 4]> { Self::all_impls(tcx).get(self).expect("missing impl for primitive type") } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index edfe8c05c6d..60b212c0243 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -16,6 +16,7 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::Ident; use rustc_span::symbol::Symbol; use rustc_span::DUMMY_SP; +use smallvec::SmallVec; use std::cell::Cell; use std::ops::Range; @@ -270,18 +271,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .ok_or(ErrorKind::ResolutionFailure)?; if let Some((path, prim)) = is_primitive(&path, TypeNS) { - let did = primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?; - return cx - .tcx - .associated_items(did) - .filter_by_name_unhygienic(item_name) - .next() - .and_then(|item| match item.kind { - ty::AssocKind::Fn => Some("method"), - _ => None, - }) - .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name)))) - .ok_or(ErrorKind::ResolutionFailure); + for &impl_ in primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)? { + let link = cx + .tcx + .associated_items(impl_) + .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, impl_) + .and_then(|item| match item.kind { + ty::AssocKind::Fn => Some("method"), + _ => None, + }) + .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name)))); + if let Some(link) = link { + return Ok(link); + } + } + return Err(ErrorKind::ResolutionFailure); } let (_, ty_res) = cx @@ -1238,26 +1242,6 @@ fn is_primitive(path_str: &str, ns: Namespace) -> Option<(&'static str, Res)> { } } -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(), - "bool" => tcx.lang_items().bool_impl(), - "char" => tcx.lang_items().char_impl(), - _ => None, - } +fn primitive_impl(cx: &DocContext<'_>, path_str: &str) -> Option<&'static SmallVec<[DefId; 4]>> { + Some(PrimitiveType::from_symbol(Symbol::intern(path_str))?.impls(cx.tcx)) } From 121974e37df723d86ea4fe94dacf5300b83c49ab Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 19:36:29 -0400 Subject: [PATCH 7/9] xpy fmt --- src/librustdoc/clean/types.rs | 9 +++++---- src/librustdoc/passes/collect_intra_doc_links.rs | 7 ++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 344d5603d76..3eac5bbda00 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -3,11 +3,11 @@ use std::default::Default; use std::fmt; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; +use std::lazy::SyncOnceCell as OnceCell; use std::num::NonZeroU32; use std::rc::Rc; use std::sync::Arc; use std::{slice, vec}; -use std::lazy::SyncOnceCell as OnceCell; use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; @@ -27,7 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, FileName}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; -use smallvec::{SmallVec, smallvec}; +use smallvec::{smallvec, SmallVec}; use crate::clean::cfg::Cfg; use crate::clean::external_path; @@ -1296,8 +1296,9 @@ impl PrimitiveType { } let single = |a: Option| a.into_iter().collect(); - let both = - |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; + let both = |a: Option, b: Option| -> SmallVec<_> { + a.into_iter().chain(b).collect() + }; let lang_items = tcx.lang_items(); map! { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 60b212c0243..97b9fcce05b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -275,7 +275,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let link = cx .tcx .associated_items(impl_) - .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, impl_) + .find_by_name_and_namespace( + cx.tcx, + Ident::with_dummy_span(item_name), + ns, + impl_, + ) .and_then(|item| match item.kind { ty::AssocKind::Fn => Some("method"), _ => None, From 570b0d9eceaa630b0fc2399ae9975aeaca777b9b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 19:42:39 -0400 Subject: [PATCH 8/9] Add a test --- .../intra-link-primitive-non-default-impl.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/rustdoc/intra-link-primitive-non-default-impl.rs diff --git a/src/test/rustdoc/intra-link-primitive-non-default-impl.rs b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs new file mode 100644 index 00000000000..427cd2124a9 --- /dev/null +++ b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs @@ -0,0 +1,14 @@ +#![deny(broken_intra_doc_links)] + +// ignore-tidy-linelength + +// @has intra_link_primitive_non_default_impl/fn.f.html +/// [`str::trim`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.trim"]' 'str::trim' +/// [`str::to_lowercase`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.to_lowercase"]' 'str::to_lowercase' +/// [`str::into_boxed_bytes`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.into_boxed_bytes"]' 'str::into_boxed_bytes' +/// [`str::replace`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.replace"]' 'str::replace' +pub fn f() {} From aff01f8de915d201b588a0dcff502f7adde7194d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 19 Aug 2020 10:35:56 -0400 Subject: [PATCH 9/9] Add test for f32 and f64 methods --- .../intra-link-primitive-non-default-impl.rs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/test/rustdoc/intra-link-primitive-non-default-impl.rs b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs index 427cd2124a9..160b18a967b 100644 --- a/src/test/rustdoc/intra-link-primitive-non-default-impl.rs +++ b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs @@ -2,7 +2,7 @@ // ignore-tidy-linelength -// @has intra_link_primitive_non_default_impl/fn.f.html +// @has intra_link_primitive_non_default_impl/fn.str_methods.html /// [`str::trim`] // @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.trim"]' 'str::trim' /// [`str::to_lowercase`] @@ -11,4 +11,22 @@ // @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.into_boxed_bytes"]' 'str::into_boxed_bytes' /// [`str::replace`] // @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.replace"]' 'str::replace' -pub fn f() {} +pub fn str_methods() {} + +// @has intra_link_primitive_non_default_impl/fn.f32_methods.html +/// [f32::powi] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.powi"]' 'f32::powi' +/// [f32::sqrt] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.sqrt"]' 'f32::sqrt' +/// [f32::mul_add] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.mul_add"]' 'f32::mul_add' +pub fn f32_methods() {} + +// @has intra_link_primitive_non_default_impl/fn.f64_methods.html +/// [`f64::powi`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.powi"]' 'f64::powi' +/// [`f64::sqrt`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.sqrt"]' 'f64::sqrt' +/// [`f64::mul_add`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.mul_add"]' 'f64::mul_add' +pub fn f64_methods() {}