diff options
| -rw-r--r-- | src/librustdoc/passes/collect_trait_impls.rs | 73 | ||||
| -rw-r--r-- | src/test/rustdoc/deref-slice-core.rs | 22 |
2 files changed, 60 insertions, 35 deletions
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 6962b5c7ee3..7b6b1ba0d96 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -33,13 +33,42 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate coll.items }; - let mut new_items = Vec::new(); + let mut new_items_external = Vec::new(); + let mut new_items_local = Vec::new(); // External trait impls. cx.with_all_trait_impls(|cx, all_trait_impls| { let _prof_timer = cx.tcx.sess.prof.generic_activity("build_extern_trait_impls"); for &impl_def_id in all_trait_impls.iter().skip_while(|def_id| def_id.is_local()) { - inline::build_impl(cx, None, impl_def_id, None, &mut new_items); + inline::build_impl(cx, None, impl_def_id, None, &mut new_items_external); + } + }); + + // Local trait impls. + cx.with_all_trait_impls(|cx, all_trait_impls| { + let _prof_timer = cx.tcx.sess.prof.generic_activity("build_local_trait_impls"); + let mut attr_buf = Vec::new(); + for &impl_def_id in all_trait_impls.iter().take_while(|def_id| def_id.is_local()) { + let mut parent = cx.tcx.parent(impl_def_id); + while let Some(did) = parent { + attr_buf.extend( + cx.tcx + .get_attrs(did) + .iter() + .filter(|attr| attr.has_name(sym::doc)) + .filter(|attr| { + if let Some([attr]) = attr.meta_item_list().as_deref() { + attr.has_name(sym::cfg) + } else { + false + } + }) + .cloned(), + ); + parent = cx.tcx.parent(did); + } + inline::build_impl(cx, None, impl_def_id, Some(&attr_buf), &mut new_items_local); + attr_buf.clear(); } }); @@ -47,7 +76,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate for def_id in PrimitiveType::all_impls(cx.tcx) { // Try to inline primitive impls from other crates. if !def_id.is_local() { - inline::build_impl(cx, None, def_id, None, &mut new_items); + inline::build_impl(cx, None, def_id, None, &mut new_items_external); } } for (prim, did) in PrimitiveType::primitive_locations(cx.tcx) { @@ -57,7 +86,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate if did.is_local() { for def_id in prim.impls(cx.tcx) { let impls = get_auto_trait_and_blanket_impls(cx, def_id); - new_items.extend(impls.filter(|i| cx.inlined.insert(i.item_id))); + new_items_external.extend(impls.filter(|i| cx.inlined.insert(i.item_id))); } } } @@ -90,7 +119,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate } // scan through included items ahead of time to splice in Deref targets to the "valid" sets - for it in &new_items { + for it in new_items_external.iter().chain(new_items_local.iter()) { 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_, true) @@ -122,7 +151,8 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate } } - new_items.retain(|it| { + // Filter out external items that are not needed + new_items_external.retain(|it| { if let ImplItem(Impl { ref for_, ref trait_, ref kind, .. }) = *it.kind { cleaner.keep_impl( for_, @@ -134,37 +164,10 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate } }); - // Local trait impls. - cx.with_all_trait_impls(|cx, all_trait_impls| { - let _prof_timer = cx.tcx.sess.prof.generic_activity("build_local_trait_impls"); - let mut attr_buf = Vec::new(); - for &impl_def_id in all_trait_impls.iter().take_while(|def_id| def_id.is_local()) { - let mut parent = cx.tcx.parent(impl_def_id); - while let Some(did) = parent { - attr_buf.extend( - cx.tcx - .get_attrs(did) - .iter() - .filter(|attr| attr.has_name(sym::doc)) - .filter(|attr| { - if let Some([attr]) = attr.meta_item_list().as_deref() { - attr.has_name(sym::cfg) - } else { - false - } - }) - .cloned(), - ); - parent = cx.tcx.parent(did); - } - inline::build_impl(cx, None, impl_def_id, Some(&attr_buf), &mut new_items); - attr_buf.clear(); - } - }); - if let ModuleItem(Module { items, .. }) = &mut *krate.module.kind { items.extend(synth_impls); - items.extend(new_items); + items.extend(new_items_external); + items.extend(new_items_local); } else { panic!("collect-trait-impls can't run"); }; diff --git a/src/test/rustdoc/deref-slice-core.rs b/src/test/rustdoc/deref-slice-core.rs new file mode 100644 index 00000000000..cccf273a820 --- /dev/null +++ b/src/test/rustdoc/deref-slice-core.rs @@ -0,0 +1,22 @@ +// https://github.com/rust-lang/rust/issues/95325 +// +// Show methods reachable from Deref of primitive. +#![no_std] + +use core::ops::Deref; + +// @has 'deref_slice_core/struct.MyArray.html' +// @has '-' '//*[@id="deref-methods-%5BT%5D"]' 'Methods from Deref<Target = [T]>' +// @has '-' '//*[@class="impl-items"]//*[@id="method.len"]' 'pub fn len(&self)' + +pub struct MyArray<T> { + array: [T; 10], +} + +impl<T> Deref for MyArray<T> { + type Target = [T]; + + fn deref(&self) -> &Self::Target { + &self.array + } +} |
