Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: Remove def_id_no_primitives #92711

Merged
merged 6 commits into from
Jan 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ impl ExternalCrate {
}

/// Indicates where an external crate can be found.
#[derive(Debug)]
CraftSpider marked this conversation as resolved.
Show resolved Hide resolved
crate enum ExternalLocation {
/// Remote URL root of the external crate
Remote(String),
Expand Down Expand Up @@ -1565,23 +1566,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<DefId> {
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<DefId> {
self.inner_def_id(None)
}
}

/// A primitive (aka, builtin) type.
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
});
}
Expand Down
58 changes: 34 additions & 24 deletions src/librustdoc/html/render/search_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
});
}
Expand Down Expand Up @@ -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<IndexItemFunctionType> {
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,
};

Expand All @@ -219,7 +220,8 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
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(_)
Expand All @@ -240,24 +242,27 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
///
/// Important note: It goes through generics recursively. So if you have
/// `T: Option<Result<(), ()>>`, 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<TypeWithKind>,
cache: &Cache,
notriddle marked this conversation as resolved.
Show resolved Hide resolved
) {
fn insert_ty(
res: &mut Vec<TypeWithKind>,
tcx: TyCtxt<'_>,
ty: Type,
mut generics: Vec<TypeWithKind>,
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<T>(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.
Expand Down Expand Up @@ -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.
Expand All @@ -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();
Expand All @@ -348,14 +351,15 @@ 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);
}
// Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`...
if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
Expand All @@ -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<T>`, and we're
Expand All @@ -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);
}
}

Expand All @@ -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<TypeWithKind>, Vec<TypeWithKind>) {
let decl = &func.decl;
let generics = &func.generics;
Expand All @@ -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)));
}
}
Expand All @@ -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)));
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/librustdoc/passes/collect_trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<DefId, &Type> = FxHashMap::default();

// Follow all `Deref` targets of included items and recursively add them as valid
fn add_deref_target(
cx: &DocContext<'_>,
map: &FxHashMap<DefId, &Type>,
cleaner: &mut BadImplStripper,
cleaner: &mut BadImplStripper<'_>,
type_did: DefId,
) {
if let Some(target) = map.get(&type_did) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -204,19 +205,20 @@ impl DocVisitor for ItemCollector {
}
}

struct BadImplStripper {
struct BadImplStripper<'a> {
prims: FxHashSet<PrimitiveType>,
items: FxHashSet<ItemId>,
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
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/passes/strip_hidden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/passes/strip_private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
6 changes: 4 additions & 2 deletions src/librustdoc/passes/stripper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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> {
Expand All @@ -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");
Expand All @@ -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"
Expand Down