diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index b43d50b19b2a0..f4b23433c918a 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -13,6 +13,7 @@ use rustc_attr_ir::{ }; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; +use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{DUMMY_SP, Span}; @@ -840,6 +841,7 @@ pub(crate) fn extract_cfg_from_attrs< attrs: I, tcx: TyCtxt<'_>, cfg_info: &mut CfgInfo, + item_def_id: Option, ) -> Option> { fn check_changed_auto_active_status( changed_auto_active_status: &mut Option, @@ -942,6 +944,22 @@ pub(crate) fn extract_cfg_from_attrs< } } } + if let Some(def_id) = item_def_id { + if !def_id.is_local() && tcx.def_kind(def_id).is_fn_like() { + let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); + for feature in &codegen_fn_attrs.target_features { + if feature.kind + == rustc_middle::middle::codegen_fn_attrs::TargetFeatureKind::Enabled + { + cfg_info.current_cfg &= Cfg(CfgEntry::NameValue { + name: sym::target_feature, + value: Some(feature.name), + span: DUMMY_SP, + }); + } + } + } + } // If `doc(auto_cfg)` feature is disabled and `doc(cfg())` wasn't used, there is nothing // to be done here. diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ea29a66c958a3..ce499888e8541 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -437,6 +437,7 @@ pub(crate) fn merge_attrs( old_attrs: &[rustc_attr_ir::Attribute], new_attrs: Option<(&[rustc_attr_ir::Attribute], Option)>, cfg_info: &mut CfgInfo, + item_def_id: Option, ) -> (clean::Attributes, Option>) { // NOTE: If we have additional attributes (from a re-export), // always insert them first. This ensure that re-export @@ -451,10 +452,13 @@ pub(crate) fn merge_attrs( } else { Attributes::from_hir(&both) }, - extract_cfg_from_attrs(both.iter(), tcx, cfg_info), + extract_cfg_from_attrs(both.iter(), tcx, cfg_info, item_def_id), ) } else { - (Attributes::from_hir(old_attrs), extract_cfg_from_attrs(old_attrs.iter(), tcx, cfg_info)) + ( + Attributes::from_hir(old_attrs), + extract_cfg_from_attrs(old_attrs.iter(), tcx, cfg_info, item_def_id), + ) } } @@ -641,7 +645,7 @@ pub(crate) fn build_impl( // // We need to pass this empty `CfgInfo` because `merge_attrs` is used when computing the `cfg`. let (merged_attrs, cfg) = - merge_attrs(cx.tcx, load_attrs(cx.tcx, did), attrs, &mut CfgInfo::default()); + merge_attrs(cx.tcx, load_attrs(cx.tcx, did), attrs, &mut CfgInfo::default(), Some(did)); trace!("merged_attrs={merged_attrs:?}"); trace!( diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 64306c0a6104c..06d150ce73feb 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -101,7 +101,13 @@ impl CfgPropagator<'_, '_> { &mut parent_attrs, load_attrs(self.cx.tcx, parent_def_id.to_def_id()), ); - merge_attrs(self.cx.tcx, &[], Some((&parent_attrs, None)), &mut self.cfg_info); + merge_attrs( + self.cx.tcx, + &[], + Some((&parent_attrs, None)), + &mut self.cfg_info, + None, + ); } } @@ -110,6 +116,7 @@ impl CfgPropagator<'_, '_> { item.attrs.other_attrs.as_slice(), Some((&attrs, None)), &mut self.cfg_info, + item.item_id.as_def_id(), ); item.inner.cfg = cfg; } @@ -157,6 +164,7 @@ impl DocFolder for CfgPropagator<'_, '_> { std::iter::once(&attrs_iter), tcx, &mut self.cfg_info, + None, ); } } diff --git a/tests/rustdoc-html/auxiliary/inline-target-feature.rs b/tests/rustdoc-html/auxiliary/inline-target-feature.rs new file mode 100644 index 0000000000000..03b2d12bf955c --- /dev/null +++ b/tests/rustdoc-html/auxiliary/inline-target-feature.rs @@ -0,0 +1,2 @@ +#[target_feature(enable = "avx")] +pub unsafe fn foo() {} diff --git a/tests/rustdoc-html/inline-target-feature.rs b/tests/rustdoc-html/inline-target-feature.rs new file mode 100644 index 0000000000000..f9ab2937898a0 --- /dev/null +++ b/tests/rustdoc-html/inline-target-feature.rs @@ -0,0 +1,12 @@ +//@ only-x86_64 +//@ aux-build:inline-target-feature.rs +//@ build-aux-docs + +#![feature(doc_cfg)] +#![crate_name = "foo"] + +extern crate inline_target_feature; + +//@ has foo/fn.foo.html +//@ has - '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' 'Available with target feature avx only.' +pub use inline_target_feature::foo;