diff options
| author | bors <bors@rust-lang.org> | 2021-05-03 20:56:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-03 20:56:34 +0000 |
| commit | 88f19c6dab716c6281af7602e30f413e809c5974 (patch) | |
| tree | f7af4b32537043e9dfbdd884f811ee8fe0122d90 /src/librustdoc/passes | |
| parent | 9a1dfd2dc5c42a2ee84b4606aa08cdadf8c0ee87 (diff) | |
| parent | 47c7b9c5788055ddbbb59d0d1fc909af7b48668d (diff) | |
| download | rust-1.52.0.tar.gz rust-1.52.0.zip | |
Auto merge of #84864 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum 1.52.0
[stable] 1.52.0 release This includes the release notes (#84183) as well as cherry-picked commits from: * [beta] revert PR #77885 #84710 * [beta] remove assert_matches #84759 * Revert PR 81473 to resolve (on beta) issues 81626 and 81658. #83171 * [beta] rustdoc revert deref recur #84868 * Fix ICE of for-loop mut borrowck where no suggestions are available #83401 Additionally in "fresh work" we're also: * reverting: directly expose copy and copy_nonoverlapping intrinsics #81238 to avoid https://github.com/rust-lang/rust/issues/84297 on 1.52
Diffstat (limited to 'src/librustdoc/passes')
| -rw-r--r-- | src/librustdoc/passes/collect_trait_impls.rs | 101 |
1 files changed, 36 insertions, 65 deletions
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 685451b87ed..492cc9118fe 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -3,7 +3,7 @@ use crate::clean::*; use crate::core::DocContext; use crate::fold::DocFolder; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashSet}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::ty::DefIdTree; use rustc_span::symbol::sym; @@ -53,6 +53,39 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { } } + let mut cleaner = BadImplStripper { prims, items: crate_items }; + + // scan through included items ahead of time to splice in Deref targets to the "valid" sets + for it in &new_items { + if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { + if cleaner.keep_impl(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() { + let target = items + .iter() + .find_map(|item| match *item.kind { + TypedefItem(ref t, true) => Some(&t.type_), + _ => None, + }) + .expect("Deref impl without Target type"); + + if let Some(prim) = target.primitive_type() { + cleaner.prims.insert(prim); + } else if let Some(did) = target.def_id() { + cleaner.items.insert(did); + } + } + } + } + + 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(t)) + || blanket_impl.is_some() + } else { + true + } + }); + // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations` // doesn't work with it anyway, so pull them from the HIR map instead let mut extra_attrs = Vec::new(); @@ -84,53 +117,6 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { } } - let mut cleaner = BadImplStripper { prims, items: crate_items }; - - let mut type_did_to_deref_target: FxHashMap<DefId, &Type> = FxHashMap::default(); - // Gather all type to `Deref` target edges. - for it in &new_items { - if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { - if trait_.def_id() == cx.tcx.lang_items().deref_trait() { - let target = items.iter().find_map(|item| match *item.kind { - TypedefItem(ref t, true) => Some(&t.type_), - _ => None, - }); - if let (Some(for_did), Some(target)) = (for_.def_id(), target) { - type_did_to_deref_target.insert(for_did, target); - } - } - } - } - // Follow all `Deref` targets of included items and recursively add them as valid - fn add_deref_target( - map: &FxHashMap<DefId, &Type>, - cleaner: &mut BadImplStripper, - type_did: &DefId, - ) { - if let Some(target) = map.get(type_did) { - 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() { - // `impl Deref<Target = S> for S` - if target_did == *type_did { - // Avoid infinite cycles - return; - } - cleaner.items.insert(target_did); - add_deref_target(map, cleaner, &target_did); - } - } - } - for type_did in type_did_to_deref_target.keys() { - // 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 - // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. - if cleaner.keep_impl_with_def_id(type_did) { - add_deref_target(&type_did_to_deref_target, &mut cleaner, type_did); - } - } - let items = if let Some(ref mut it) = krate.module { if let ModuleItem(Module { ref mut items, .. }) = *it.kind { items @@ -142,18 +128,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { }; items.extend(synth_impls); - for it in new_items.drain(..) { - if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind { - if !(cleaner.keep_impl(for_) - || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t)) - || blanket_impl.is_some()) - { - continue; - } - } - - items.push(it); - } + items.extend(new_items); krate } @@ -208,13 +183,9 @@ impl BadImplStripper { } else if let Some(prim) = ty.primitive_type() { self.prims.contains(&prim) } else if let Some(did) = ty.def_id() { - self.keep_impl_with_def_id(&did) + self.items.contains(&did) } else { false } } - - fn keep_impl_with_def_id(&self, did: &DefId) -> bool { - self.items.contains(did) - } } |
