diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index d34c2dba0b0d..026336982736 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -338,6 +338,7 @@ impl ExternalCrate { } /// Indicates where an external crate can be found. +#[derive(Debug)] crate enum ExternalLocation { /// Remote URL root of the external crate Remote(String), @@ -1539,23 +1540,10 @@ impl Type { /// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s. /// - /// See [`Self::def_id_no_primitives`] for more. - /// /// [clean]: crate::clean crate fn def_id(&self, cache: &Cache) -> Option { self.inner_def_id(Some(cache)) } - - /// Use this method to get the [`DefId`] of a [`clean`] AST node. - /// This will return [`None`] when called on a primitive [`clean::Type`]. - /// Use [`Self::def_id`] if you want to include primitives. - /// - /// [`clean`]: crate::clean - /// [`clean::Type`]: crate::clean::Type - // FIXME: get rid of this function and always use `def_id` - crate fn def_id_no_primitives(&self) -> Option { - self.inner_def_id(None) - } } /// A primitive (aka, builtin) type. diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index a8fef4a31780..53159709586c 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -303,7 +303,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { desc, parent, parent_idx: None, - search_type: get_function_type_for_search(&item, self.tcx), + search_type: get_function_type_for_search(&item, self.tcx, self.cache), aliases: item.attrs.get_doc_aliases(), }); } diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 87138b9571c2..0ee67467c383 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{kw, Symbol}; use serde::ser::{Serialize, SerializeStruct, Serializer}; use crate::clean; @@ -33,7 +33,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< desc, parent: Some(did), parent_idx: None, - search_type: get_function_type_for_search(item, tcx), + search_type: get_function_type_for_search(item, tcx, &cache), aliases: item.attrs.get_doc_aliases(), }); } @@ -188,11 +188,12 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< crate fn get_function_type_for_search<'tcx>( item: &clean::Item, tcx: TyCtxt<'tcx>, + cache: &Cache, ) -> Option { let (mut inputs, mut output) = match *item.kind { - clean::FunctionItem(ref f) => get_fn_inputs_and_outputs(f, tcx), - clean::MethodItem(ref m, _) => get_fn_inputs_and_outputs(m, tcx), - clean::TyMethodItem(ref m) => get_fn_inputs_and_outputs(m, tcx), + clean::FunctionItem(ref f) => get_fn_inputs_and_outputs(f, tcx, cache), + clean::MethodItem(ref m, _) => get_fn_inputs_and_outputs(m, tcx, cache), + clean::TyMethodItem(ref m) => get_fn_inputs_and_outputs(m, tcx, cache), _ => return None, }; @@ -219,7 +220,8 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option { let path = &bounds[0].trait_; Some(path.segments.last().unwrap().name) } - clean::Generic(s) => Some(s), + // We return an empty name because we don't care about the generic name itself. + clean::Generic(_) => Some(kw::Empty), clean::Primitive(ref p) => Some(p.as_sym()), clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_), clean::BareFunction(_) @@ -240,24 +242,27 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option { /// /// Important note: It goes through generics recursively. So if you have /// `T: Option>`, it'll go into `Option` and then into `Result`. -#[instrument(level = "trace", skip(tcx, res))] +#[instrument(level = "trace", skip(tcx, res, cache))] fn add_generics_and_bounds_as_types<'tcx>( generics: &Generics, arg: &Type, tcx: TyCtxt<'tcx>, recurse: usize, res: &mut Vec, + cache: &Cache, ) { fn insert_ty( res: &mut Vec, tcx: TyCtxt<'_>, ty: Type, mut generics: Vec, + cache: &Cache, ) { let is_full_generic = ty.is_full_generic(); + let generics_empty = generics.is_empty(); if is_full_generic { - if generics.is_empty() { + if generics_empty { // This is a type parameter with no trait bounds (for example: `T` in // `fn f(p: T)`, so not useful for the rustdoc search because we would end up // with an empty type with an empty name. Let's just discard it. @@ -304,14 +309,14 @@ fn add_generics_and_bounds_as_types<'tcx>( } } let mut index_ty = get_index_type(&ty, generics); - if index_ty.name.as_ref().map(|s| s.is_empty()).unwrap_or(true) { + if index_ty.name.as_ref().map(|s| s.is_empty() && generics_empty).unwrap_or(true) { return; } if is_full_generic { // We remove the name of the full generic because we have no use for it. index_ty.name = Some(String::new()); res.push(TypeWithKind::from((index_ty, ItemType::Generic))); - } else if let Some(kind) = ty.def_id_no_primitives().map(|did| tcx.def_kind(did).into()) { + } else if let Some(kind) = ty.def_id(cache).map(|did| tcx.def_kind(did).into()) { res.push(TypeWithKind::from((index_ty, kind))); } else if ty.is_primitive() { // This is a primitive, let's store it as such. @@ -330,9 +335,7 @@ fn add_generics_and_bounds_as_types<'tcx>( if let Type::Generic(arg_s) = *arg { // First we check if the bounds are in a `where` predicate... if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g { - WherePredicate::BoundPredicate { ty, .. } => { - ty.def_id_no_primitives() == arg.def_id_no_primitives() - } + WherePredicate::BoundPredicate { ty, .. } => ty.def_id(cache) == arg.def_id(cache), _ => false, }) { let mut ty_generics = Vec::new(); @@ -348,6 +351,7 @@ fn add_generics_and_bounds_as_types<'tcx>( tcx, recurse + 1, &mut ty_generics, + cache, ) } _ => {} @@ -355,7 +359,7 @@ fn add_generics_and_bounds_as_types<'tcx>( } } } - insert_ty(res, tcx, arg.clone(), ty_generics); + insert_ty(res, tcx, arg.clone(), ty_generics, cache); } // Otherwise we check if the trait bounds are "inlined" like `T: Option`... if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) { @@ -369,10 +373,11 @@ fn add_generics_and_bounds_as_types<'tcx>( tcx, recurse + 1, &mut ty_generics, + cache, ); } } - insert_ty(res, tcx, arg.clone(), ty_generics); + insert_ty(res, tcx, arg.clone(), ty_generics, cache); } } else { // This is not a type parameter. So for example if we have `T, U: Option`, and we're @@ -383,10 +388,17 @@ fn add_generics_and_bounds_as_types<'tcx>( let mut ty_generics = Vec::new(); if let Some(arg_generics) = arg.generics() { for gen in arg_generics.iter() { - add_generics_and_bounds_as_types(generics, gen, tcx, recurse + 1, &mut ty_generics); + add_generics_and_bounds_as_types( + generics, + gen, + tcx, + recurse + 1, + &mut ty_generics, + cache, + ); } } - insert_ty(res, tcx, arg.clone(), ty_generics); + insert_ty(res, tcx, arg.clone(), ty_generics, cache); } } @@ -397,6 +409,7 @@ fn add_generics_and_bounds_as_types<'tcx>( fn get_fn_inputs_and_outputs<'tcx>( func: &Function, tcx: TyCtxt<'tcx>, + cache: &Cache, ) -> (Vec, Vec) { let decl = &func.decl; let generics = &func.generics; @@ -407,12 +420,11 @@ fn get_fn_inputs_and_outputs<'tcx>( continue; } let mut args = Vec::new(); - add_generics_and_bounds_as_types(generics, &arg.type_, tcx, 0, &mut args); + add_generics_and_bounds_as_types(generics, &arg.type_, tcx, 0, &mut args, cache); if !args.is_empty() { all_types.extend(args); } else { - if let Some(kind) = arg.type_.def_id_no_primitives().map(|did| tcx.def_kind(did).into()) - { + if let Some(kind) = arg.type_.def_id(cache).map(|did| tcx.def_kind(did).into()) { all_types.push(TypeWithKind::from((get_index_type(&arg.type_, vec![]), kind))); } } @@ -421,11 +433,9 @@ fn get_fn_inputs_and_outputs<'tcx>( let mut ret_types = Vec::new(); match decl.output { FnRetTy::Return(ref return_type) => { - add_generics_and_bounds_as_types(generics, return_type, tcx, 0, &mut ret_types); + add_generics_and_bounds_as_types(generics, return_type, tcx, 0, &mut ret_types, cache); if ret_types.is_empty() { - if let Some(kind) = - return_type.def_id_no_primitives().map(|did| tcx.def_kind(did).into()) - { + if let Some(kind) = return_type.def_id(cache).map(|did| tcx.def_kind(did).into()) { ret_types.push(TypeWithKind::from((get_index_type(return_type, vec![]), kind))); } } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 66ac612ea37c..53280b3df138 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -4,6 +4,7 @@ use super::Pass; use crate::clean::*; use crate::core::DocContext; +use crate::formats::cache::Cache; use crate::visit::DocVisitor; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -57,14 +58,14 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate } }); - let mut cleaner = BadImplStripper { prims, items: crate_items }; + let mut cleaner = BadImplStripper { prims, items: crate_items, cache: &cx.cache }; let mut type_did_to_deref_target: FxHashMap = FxHashMap::default(); // Follow all `Deref` targets of included items and recursively add them as valid fn add_deref_target( cx: &DocContext<'_>, map: &FxHashMap, - cleaner: &mut BadImplStripper, + cleaner: &mut BadImplStripper<'_>, type_did: DefId, ) { if let Some(target) = map.get(&type_did) { @@ -102,7 +103,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate } else if let Some(did) = target.def_id(&cx.cache) { cleaner.items.insert(did.into()); } - if let Some(for_did) = for_.def_id_no_primitives() { + if let Some(for_did) = for_.def_id(&cx.cache) { if type_did_to_deref_target.insert(for_did, target).is_none() { // Since only the `DefId` portion of the `Type` instances is known to be same for both the // `Deref` target type and the impl for type positions, this map of types is keyed by @@ -204,19 +205,20 @@ impl DocVisitor for ItemCollector { } } -struct BadImplStripper { +struct BadImplStripper<'a> { prims: FxHashSet, items: FxHashSet, + cache: &'a Cache, } -impl BadImplStripper { +impl<'a> BadImplStripper<'a> { fn keep_impl(&self, ty: &Type, is_deref: bool) -> bool { if let Generic(_) = ty { // keep impls made on generics true } else if let Some(prim) = ty.primitive_type() { self.prims.contains(&prim) - } else if let Some(did) = ty.def_id_no_primitives() { + } else if let Some(did) = ty.def_id(self.cache) { is_deref || self.keep_impl_with_def_id(did.into()) } else { false diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index e63534659add..e7a99ee7bfd8 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -15,7 +15,7 @@ crate const STRIP_HIDDEN: Pass = Pass { }; /// Strip items marked `#[doc(hidden)]` -crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate { +crate fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { let mut retained = ItemIdSet::default(); // strip all #[doc(hidden)] items @@ -25,7 +25,7 @@ crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Cra }; // strip all impls referencing stripped items - let mut stripper = ImplStripper { retained: &retained }; + let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache }; stripper.fold_crate(krate) } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index c6b5bec4692d..ef7e768a5114 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -29,6 +29,6 @@ crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clea } // strip all impls referencing private items - let mut stripper = ImplStripper { retained: &retained }; + let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache }; stripper.fold_crate(krate) } diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 7b07974ae01c..717dc078b343 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -5,6 +5,7 @@ use std::mem; use crate::clean::{self, Item, ItemIdSet}; use crate::fold::{strip_item, DocFolder}; +use crate::formats::cache::Cache; crate struct Stripper<'a> { crate retained: &'a mut ItemIdSet, @@ -118,6 +119,7 @@ impl<'a> DocFolder for Stripper<'a> { /// This stripper discards all impls which reference stripped items crate struct ImplStripper<'a> { crate retained: &'a ItemIdSet, + crate cache: &'a Cache, } impl<'a> DocFolder for ImplStripper<'a> { @@ -127,7 +129,7 @@ impl<'a> DocFolder for ImplStripper<'a> { if imp.trait_.is_none() && imp.items.is_empty() { return None; } - if let Some(did) = imp.for_.def_id_no_primitives() { + if let Some(did) = imp.for_.def_id(self.cache) { if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into()) { debug!("ImplStripper: impl item for stripped type; removing"); @@ -142,7 +144,7 @@ impl<'a> DocFolder for ImplStripper<'a> { } if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) { for typaram in generics { - if let Some(did) = typaram.def_id_no_primitives() { + if let Some(did) = typaram.def_id(self.cache) { if did.is_local() && !self.retained.contains(&did.into()) { debug!( "ImplStripper: stripped item in trait's generics; removing impl"