Change:
I tried this code: I expected to see this happen: both impls being highlighted as needing the feature. Instead, this happened: only the impl got the message: ! <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
modify labels: +T-rustdoc
claim

Discussion:
return; } <del> let attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs); debug!("merged_attrs={:?}", attrs); </del> let tcx = cx.tcx; let associated_trait = tcx.impl_trait_ref(did);

debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id()); <del> ret.push(clean::Item::from_def_id_and_parts( </del> <ins> let mut item = clean::Item::from_def_id_and_parts( </ins> did, None, clean::ImplItem(clean::Impl {

blanket_impl: None, }), cx, <del> )); </del> <ins> ); item.attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs); debug!("merged_attrs={:?}", item.attrs); ret.push(item); </ins> } fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>) -> clean::Module {

use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; <ins> use rustc_middle::ty::DefIdTree; </ins> use rustc_span::symbol::sym; crate const COLLECT_TRAIT_IMPLS: Pass = Pass {

for &impl_node in cx.tcx.hir().trait_impls(trait_did) { let impl_did = cx.tcx.hir().local_def_id(impl_node); cx.tcx.sess.time("build_local_trait_impl", || { <del> inline::build_impl(cx, None, impl_did.to_def_id(), None, &mut new_items); </del> <ins> let mut extra_attrs = Vec::new(); let mut parent = cx.tcx.parent(impl_did.to_def_id()); while let Some(did) = parent { extra_attrs.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_did.to_def_id(), Some(&extra_attrs), &mut new_items, ); </ins> }); } }

// @has doc_cfg/unix_only/trait.ArmOnly.html  //  '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]'  //  'This is supported on Unix and ARM only.' <del> // @count - '//*[@class="stab portability"]' 2 </del> <ins> // @count - '//*[@class="stab portability"]' 1 </ins> #[doc(cfg(target_arch = "arm"))] pub trait ArmOnly { fn unix_and_arm_only_function(); } <ins> #[doc(cfg(target_arch = "arm"))] </ins> impl ArmOnly for super::Portable { fn unix_and_arm_only_function() {} }

<ins> #![feature(doc_cfg)] // @has 'issue_79201/trait.Foo.html' // @count   - '//*[@class="stab portability"]' 6 // @matches - '//*[@class="stab portability"]' 'crate feature foo-root' // @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod' // @matches - '//*[@class="stab portability"]' 'crate feature foo-private-mod' // @matches - '//*[@class="stab portability"]' 'crate feature foo-fn' // @matches - '//*[@class="stab portability"]' 'crate feature foo-method' pub trait Foo {} #[doc(cfg(feature = "foo-root"))] impl crate::Foo for usize {} #[doc(cfg(feature = "foo-public-mod"))] pub mod public { impl crate::Foo for u8 {} } #[doc(cfg(feature = "foo-private-mod"))] mod private { impl crate::Foo for u16 {} } #[doc(cfg(feature = "foo-const"))] const _: () = { impl crate::Foo for u32 {} }; #[doc(cfg(feature = "foo-fn"))] fn __() { impl crate::Foo for u64 {} } #[doc(cfg(feature = "foo-method"))] impl dyn Foo { fn __() { impl crate::Foo for u128 {} } } </ins>

}) }; let mut diff = Command::new("diff"); <del> diff.args(&["-u", "-r"]).args(&[out_dir, &compare_dir]); </del> <ins> diff.args(&["-u", "-r"]).args(&[&compare_dir, out_dir]); </ins> let output = if let Some(pager) = pager { let diff_pid = diff.stdout(Stdio::piped()).spawn().expect("failed to run `diff`");