From 2ff14448863ac1a1dd9533461708e29aae170c2d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:06:31 +0200 Subject: Adding debian version 1.65.0+dfsg1-2. Signed-off-by: Daniel Baumann --- src/librustdoc/passes/propagate_doc_cfg.rs | 62 +++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) (limited to 'src/librustdoc/passes/propagate_doc_cfg.rs') diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 0c5d83655..765f7c61b 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -2,29 +2,74 @@ use std::sync::Arc; use crate::clean::cfg::Cfg; -use crate::clean::{Crate, Item}; +use crate::clean::inline::{load_attrs, merge_attrs}; +use crate::clean::{Crate, Item, ItemKind}; use crate::core::DocContext; use crate::fold::DocFolder; use crate::passes::Pass; +use rustc_hir::def_id::LocalDefId; + pub(crate) const PROPAGATE_DOC_CFG: Pass = Pass { name: "propagate-doc-cfg", run: propagate_doc_cfg, description: "propagates `#[doc(cfg(...))]` to child items", }; -pub(crate) fn propagate_doc_cfg(cr: Crate, _: &mut DocContext<'_>) -> Crate { - CfgPropagator { parent_cfg: None }.fold_crate(cr) +pub(crate) fn propagate_doc_cfg(cr: Crate, cx: &mut DocContext<'_>) -> Crate { + CfgPropagator { parent_cfg: None, parent: None, cx }.fold_crate(cr) } -struct CfgPropagator { +struct CfgPropagator<'a, 'tcx> { parent_cfg: Option>, + parent: Option, + cx: &'a mut DocContext<'tcx>, +} + +impl<'a, 'tcx> CfgPropagator<'a, 'tcx> { + // Some items need to merge their attributes with their parents' otherwise a few of them + // (mostly `cfg` ones) will be missing. + fn merge_with_parent_attributes(&mut self, item: &mut Item) { + let check_parent = match &*item.kind { + // impl blocks can be in different modules with different cfg and we need to get them + // as well. + ItemKind::ImplItem(_) => false, + kind if kind.is_non_assoc() => true, + _ => return, + }; + + let Some(def_id) = item.item_id.as_def_id().and_then(|def_id| def_id.as_local()) + else { return }; + + let hir = self.cx.tcx.hir(); + let hir_id = hir.local_def_id_to_hir_id(def_id); + + if check_parent { + let expected_parent = hir.get_parent_item(hir_id); + // If parents are different, it means that `item` is a reexport and we need + // to compute the actual `cfg` by iterating through its "real" parents. + if self.parent == Some(expected_parent) { + return; + } + } + + let mut attrs = Vec::new(); + for (parent_hir_id, _) in hir.parent_iter(hir_id) { + if let Some(def_id) = hir.opt_local_def_id(parent_hir_id) { + attrs.extend_from_slice(load_attrs(self.cx, def_id.to_def_id())); + } + } + let (_, cfg) = merge_attrs(self.cx, None, item.attrs.other_attrs.as_slice(), Some(&attrs)); + item.cfg = cfg; + } } -impl DocFolder for CfgPropagator { +impl<'a, 'tcx> DocFolder for CfgPropagator<'a, 'tcx> { fn fold_item(&mut self, mut item: Item) -> Option { let old_parent_cfg = self.parent_cfg.clone(); + self.merge_with_parent_attributes(&mut item); + let new_cfg = match (self.parent_cfg.take(), item.cfg.take()) { (None, None) => None, (Some(rc), None) | (None, Some(rc)) => Some(rc), @@ -37,8 +82,15 @@ impl DocFolder for CfgPropagator { self.parent_cfg = new_cfg.clone(); item.cfg = new_cfg; + let old_parent = + if let Some(def_id) = item.item_id.as_def_id().and_then(|def_id| def_id.as_local()) { + self.parent.replace(def_id) + } else { + self.parent.take() + }; let result = self.fold_item_recur(item); self.parent_cfg = old_parent_cfg; + self.parent = old_parent; Some(result) } -- cgit v1.2.3