From 6eb4735acc50f58e501b42c5d75ae73b3d74b44d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 22 Apr 2021 13:28:43 -0400 Subject: Unify rustc and rustdoc parsing of `cfg()` This extracts a new `parse_cfg` function that's used between both. - Treat `#[doc(cfg(x), cfg(y))]` the same as `#[doc(cfg(x)] #[doc(cfg(y))]`. Previously it would be completely ignored. - Treat `#[doc(inline, cfg(x))]` the same as `#[doc(inline)] #[doc(cfg(x))]`. Previously, the cfg would be ignored. - Pass the cfg predicate through to rustc_expand to be validated Co-authored-by: Vadim Petrochenkov --- src/librustdoc/clean/inline.rs | 4 +-- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/types.rs | 54 +++++++++++++------------------- src/librustdoc/doctest.rs | 2 +- src/librustdoc/html/render/context.rs | 2 +- src/librustdoc/html/render/print_item.rs | 2 +- 6 files changed, 27 insertions(+), 39 deletions(-) (limited to 'src/librustdoc') diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3e89c1ac4c5..4c3b86b2e2b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -307,10 +307,10 @@ fn merge_attrs( } else { Attributes::from_ast(&both, None) }, - both.cfg(cx.sess().diagnostic()), + both.cfg(cx.sess()), ) } else { - (old_attrs.clean(cx), old_attrs.cfg(cx.sess().diagnostic())) + (old_attrs.clean(cx), old_attrs.cfg(cx.sess())) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6563f398edb..a7bc3c20a3d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2006,7 +2006,7 @@ fn clean_extern_crate( def_id: crate_def_id, visibility: krate.vis.clean(cx), kind: box ExternCrateItem { src: orig_name }, - cfg: attrs.cfg(cx.sess().diagnostic()), + cfg: attrs.cfg(cx.sess()), }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5e47144588b..a2a03dfd15b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -320,7 +320,7 @@ impl Item { kind, box ast_attrs.clean(cx), cx, - ast_attrs.cfg(cx.sess().diagnostic()), + ast_attrs.cfg(cx.sess()), ) } @@ -332,7 +332,7 @@ impl Item { cx: &mut DocContext<'_>, cfg: Option>, ) -> Item { - debug!("name={:?}, def_id={:?}", name, def_id); + trace!("name={:?}, def_id={:?}", name, def_id); Item { def_id, @@ -681,7 +681,7 @@ crate trait AttributesExt { fn other_attrs(&self) -> Vec; - fn cfg(&self, diagnostic: &::rustc_errors::Handler) -> Option>; + fn cfg(&self, sess: &Session) -> Option>; } impl AttributesExt for [ast::Attribute] { @@ -706,17 +706,28 @@ impl AttributesExt for [ast::Attribute] { self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect() } - fn cfg(&self, diagnostic: &::rustc_errors::Handler) -> Option> { + fn cfg(&self, sess: &Session) -> Option> { let mut cfg = Cfg::True; for attr in self.iter() { + // #[doc] if attr.doc_str().is_none() && attr.has_name(sym::doc) { - if let Some(mi) = attr.meta() { - if let Some(cfg_mi) = Attributes::extract_cfg(&mi) { - // Extracted #[doc(cfg(...))] - match Cfg::parse(cfg_mi) { - Ok(new_cfg) => cfg &= new_cfg, - Err(e) => diagnostic.span_err(e.span, e.msg), + // #[doc(...)] + if let Some(list) = attr.meta().as_ref().and_then(|mi| mi.meta_item_list()) { + for item in list { + // #[doc(include)] + if !item.has_name(sym::cfg) { + continue; + } + // #[doc(cfg(...))] + if let Some(cfg_mi) = item + .meta_item() + .and_then(|item| rustc_expand::config::parse_cfg(&item, sess)) + { + match Cfg::parse(&cfg_mi) { + Ok(new_cfg) => cfg &= new_cfg, + Err(e) => sess.span_err(e.span, e.msg), + } } } } @@ -883,29 +894,6 @@ impl Attributes { self.other_attrs.lists(name) } - /// Extracts the content from an attribute `#[doc(cfg(content))]`. - crate fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> { - use rustc_ast::NestedMetaItem::MetaItem; - - if let ast::MetaItemKind::List(ref nmis) = mi.kind { - if nmis.len() == 1 { - if let MetaItem(ref cfg_mi) = nmis[0] { - if cfg_mi.has_name(sym::cfg) { - if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind { - if cfg_nmis.len() == 1 { - if let MetaItem(ref content_mi) = cfg_nmis[0] { - return Some(content_mi); - } - } - } - } - } - } - } - - None - } - /// Reads a `MetaItem` from within an attribute, looks for whether it is a /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from /// its expansion. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 466d1b65406..69a47c5b67a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1095,7 +1095,7 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { let ast_attrs = self.tcx.hir().attrs(hir_id); let mut attrs = Attributes::from_ast(ast_attrs, None); - if let Some(ref cfg) = ast_attrs.cfg(self.sess.diagnostic()) { + if let Some(ref cfg) = ast_attrs.cfg(self.sess) { if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) { return; } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 4c8ba0e7b49..268974169ea 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -154,7 +154,7 @@ impl<'tcx> Context<'tcx> { &self.cache } - fn sess(&self) -> &'tcx Session { + pub(super) fn sess(&self) -> &'tcx Session { &self.shared.tcx.sess } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 1bb1db00e88..d33a31ef1ee 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -292,7 +292,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl let import_item = clean::Item { def_id: import_def_id, attrs: import_attrs, - cfg: ast_attrs.cfg(cx.tcx().sess.diagnostic()), + cfg: ast_attrs.cfg(cx.sess()), ..myitem.clone() }; -- cgit 1.4.1-3-g733a5