diff options
| author | Wim Looman <git@nemo157.com> | 2020-11-03 19:45:16 +0100 |
|---|---|---|
| committer | Guillaume Gomez <guillaume.gomez@huawei.com> | 2021-10-05 17:25:44 +0200 |
| commit | 10cdbd847fd00d093ce89a4fffde5d90c8bb9817 (patch) | |
| tree | 565637fa1346110af2b1b1aa415cd1d1b2fe025a | |
| parent | 074f63648bd2368d5ca19aed02b5763a144e5d05 (diff) | |
| download | rust-10cdbd847fd00d093ce89a4fffde5d90c8bb9817.tar.gz rust-10cdbd847fd00d093ce89a4fffde5d90c8bb9817.zip | |
Make cfg implicitly imply doc(cfg)
This is only active when the `doc_cfg` feature is active. The implicit cfg can be overridden via #[doc(cfg(...))], so e.g. to hide a #[cfg] you can use something like: ```rust #[cfg(unix)] #[doc(cfg(all()))] pub struct Unix; ``` (since `all()` is always true, it is never shown in the docs)
| -rw-r--r-- | src/librustdoc/clean/inline.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/clean/types.rs | 52 | ||||
| -rw-r--r-- | src/librustdoc/doctest.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/render/print_item.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/lib.rs | 1 | ||||
| -rw-r--r-- | src/test/rustdoc/doc-cfg-implicit-gate.rs | 7 | ||||
| -rw-r--r-- | src/test/rustdoc/doc-cfg-implicit.rs | 31 |
8 files changed, 92 insertions, 9 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 4a888b22332..39493f6edf8 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -318,10 +318,10 @@ fn merge_attrs( } else { Attributes::from_ast(&both, None) }, - both.cfg(cx.sess()), + both.cfg(cx.tcx), ) } else { - (old_attrs.clean(cx), old_attrs.cfg(cx.sess())) + (old_attrs.clean(cx), old_attrs.cfg(cx.tcx)) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a55d85f5841..41bc30fd398 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1973,7 +1973,7 @@ fn clean_extern_crate( def_id: crate_def_id.into(), visibility: krate.vis.clean(cx), kind: box ExternCrateItem { src: orig_name }, - cfg: attrs.cfg(cx.sess()), + cfg: attrs.cfg(cx.tcx), }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0e78fe7aec3..288644ff296 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -421,7 +421,7 @@ impl Item { kind, box ast_attrs.clean(cx), cx, - ast_attrs.cfg(cx.sess()), + ast_attrs.cfg(cx.tcx), ) } @@ -747,7 +747,7 @@ crate trait AttributesExt { fn other_attrs(&self) -> Vec<ast::Attribute>; - fn cfg(&self, sess: &Session) -> Option<Arc<Cfg>>; + fn cfg(&self, tcx: TyCtxt<'_>) -> Option<Arc<Cfg>>; } impl AttributesExt for [ast::Attribute] { @@ -772,8 +772,52 @@ impl AttributesExt for [ast::Attribute] { self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect() } - fn cfg(&self, sess: &Session) -> Option<Arc<Cfg>> { - let mut cfg = Cfg::True; + fn cfg(&self, tcx: TyCtxt<'_>) -> Option<Arc<Cfg>> { + let sess = tcx.sess; + let doc_cfg_active = tcx.features().doc_cfg; + + trait SingleExt { + type Item; + fn single(self) -> Option<Self::Item>; + } + + impl<T: IntoIterator> SingleExt for T { + type Item = T::Item; + fn single(self) -> Option<Self::Item> { + let mut iter = self.into_iter(); + let item = iter.next()?; + iter.next().is_none().then_some(())?; + Some(item) + } + } + + let mut cfg = if doc_cfg_active { + let mut doc_cfg = self + .iter() + .filter(|attr| attr.has_name(sym::doc)) + .filter_map(|attr| Some(attr.meta_item_list()?.single()?)) + .filter(|attr| attr.has_name(sym::cfg)) + .filter_map(|attr| Some(attr.meta_item_list()?.single()?.meta_item()?.clone())) + .peekable(); + if doc_cfg.peek().is_some() { + doc_cfg + .filter_map(|attr| { + Cfg::parse(&attr).map_err(|e| sess.diagnostic().span_err(e.span, e.msg)).ok() + }) + .fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg) + } else { + self + .iter() + .filter(|attr| attr.has_name(sym::cfg)) + .filter_map(|attr| Some(attr.meta_item_list()?.single()?.meta_item()?.clone())) + .filter_map(|attr| { + Cfg::parse(&attr).map_err(|e| sess.diagnostic().span_err(e.span, e.msg)).ok() + }) + .fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg) + } + } else { + Cfg::True + }; for attr in self.iter() { // #[doc] diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 43abcf095d8..8cf7b50fbd9 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1123,7 +1123,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) { + if let Some(ref cfg) = ast_attrs.cfg(self.tcx) { if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) { return; } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 28b2eded7cc..e68e1223171 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -323,7 +323,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl let import_item = clean::Item { def_id: import_def_id.into(), attrs: import_attrs, - cfg: ast_attrs.cfg(cx.sess()), + cfg: ast_attrs.cfg(cx.tcx()), ..myitem.clone() }; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index efc8e31498a..d070ce22890 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -5,6 +5,7 @@ #![feature(rustc_private)] #![feature(array_methods)] #![feature(assert_matches)] +#![feature(bool_to_option)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(box_syntax)] diff --git a/src/test/rustdoc/doc-cfg-implicit-gate.rs b/src/test/rustdoc/doc-cfg-implicit-gate.rs new file mode 100644 index 00000000000..92804d3729b --- /dev/null +++ b/src/test/rustdoc/doc-cfg-implicit-gate.rs @@ -0,0 +1,7 @@ +// compile-flags:--cfg feature="worricow" +#![crate_name = "xenogenous"] + +// @has 'xenogenous/struct.Worricow.html' +// @count - '//*[@class="stab portability"]' 0 +#[cfg(feature = "worricow")] +pub struct Worricow; diff --git a/src/test/rustdoc/doc-cfg-implicit.rs b/src/test/rustdoc/doc-cfg-implicit.rs new file mode 100644 index 00000000000..36c2025785d --- /dev/null +++ b/src/test/rustdoc/doc-cfg-implicit.rs @@ -0,0 +1,31 @@ +#![crate_name = "funambulism"] +#![feature(doc_cfg)] + +// @has 'funambulism/struct.Disorbed.html' +// @count - '//*[@class="stab portability"]' 1 +// @matches - '//*[@class="stab portability"]' 'crate feature disorbed' +// compile-flags:--cfg feature="disorbed" +#[cfg(feature = "disorbed")] +pub struct Disorbed; + +// @has 'funambulism/struct.Aesthesia.html' +// @count - '//*[@class="stab portability"]' 1 +// @matches - '//*[@class="stab portability"]' 'crate feature aesthesia' +// compile-flags:--cfg feature="aesthesia" +#[doc(cfg(feature = "aesthesia"))] +pub struct Aesthesia; + +// @has 'funambulism/struct.Pliothermic.html' +// @count - '//*[@class="stab portability"]' 1 +// @matches - '//*[@class="stab portability"]' 'crate feature pliothermic' +// compile-flags:--cfg feature="epopoeist" +#[cfg(feature = "epopoeist")] +#[doc(cfg(feature = "pliothermic"))] +pub struct Pliothermic; + +// @has 'funambulism/struct.Simillimum.html' +// @count - '//*[@class="stab portability"]' 0 +// compile-flags:--cfg feature="simillimum" +#[cfg(feature = "simillimum")] +#[doc(cfg(all()))] +pub struct Simillimum; |
