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

Show all Deref implementations recursively #90183

Merged
merged 6 commits into from
Oct 30, 2021
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix panic when documenting libproc-macro
  • Loading branch information
GuillaumeGomez committed Oct 29, 2021
commit f09b67a696aac41bb2a8f5146b4017ffd141e232
23 changes: 10 additions & 13 deletions src/librustdoc/passes/collect_trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
debug!("add_deref_target: type {:?}, target {:?}", type_did, target);
if let Some(target_prim) = target.primitive_type() {
cleaner.prims.insert(target_prim);
} else if let Some(target_did) = target.def_id() {
} else if let Some(target_did) = target.def_id_no_primitives() {
// `impl Deref<Target = S> for S`
if target_did == type_did {
// Avoid infinite cycles
Expand All @@ -82,7 +82,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
for it in &new_items {
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
if trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait()
&& cleaner.keep_impl(for_)
&& cleaner.keep_impl(for_, true)
{
let target = items
.iter()
Expand All @@ -97,7 +97,7 @@ crate fn collect_trait_impls(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() {
if let Some(for_did) = for_.def_id_no_primitives() {
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 All @@ -113,10 +113,10 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {

new_items.retain(|it| {
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
cleaner.keep_impl(for_)
|| trait_
.as_ref()
.map_or(false, |t| cleaner.keep_impl_with_def_id(t.def_id().into()))
cleaner.keep_impl(
for_,
trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait(),
) || trait_.as_ref().map_or(false, |t| cleaner.keep_impl_with_def_id(t.def_id().into()))
|| blanket_impl.is_some()
} else {
true
Expand Down Expand Up @@ -215,17 +215,14 @@ struct BadImplStripper {
}

impl BadImplStripper {
fn keep_impl(&self, ty: &Type) -> bool {
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 ty.def_id_no_primitives().is_some() {
// We want to keep *ALL* deref implementations in case some of them are used in
// the current crate.
// FIXME: Try to filter the one actually used...
true
} else if let Some(did) = ty.def_id_no_primitives() {
is_deref || self.keep_impl_with_def_id(did.into())
} else {
false
}
Expand Down