summaryrefslogtreecommitdiffstats
path: root/src/librustdoc/passes/propagate_doc_cfg.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:03:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:03:36 +0000
commit17d40c6057c88f4c432b0d7bac88e1b84cb7e67f (patch)
tree3f66c4a5918660bb8a758ab6cda5ff8ee4f6cdcd /src/librustdoc/passes/propagate_doc_cfg.rs
parentAdding upstream version 1.64.0+dfsg1. (diff)
downloadrustc-17d40c6057c88f4c432b0d7bac88e1b84cb7e67f.tar.xz
rustc-17d40c6057c88f4c432b0d7bac88e1b84cb7e67f.zip
Adding upstream version 1.65.0+dfsg1.upstream/1.65.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/librustdoc/passes/propagate_doc_cfg.rs')
-rw-r--r--src/librustdoc/passes/propagate_doc_cfg.rs62
1 files changed, 57 insertions, 5 deletions
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<Arc<Cfg>>,
+ parent: Option<LocalDefId>,
+ 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<Item> {
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)
}