mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Allow adding a set of cfg's to hide from being implicitly doc(cfg)'d
By adding #![doc(cfg_hide(foobar))] to the crate attributes the cfg #[cfg(foobar)] (and _only_ that _exact_ cfg) will not be implicitly treated as a doc(cfg) to render a message in the documentation.
This commit is contained in:
parent
10cdbd847f
commit
18fdd816b7
@ -279,6 +279,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
|
||||
gate_doc!(
|
||||
cfg => doc_cfg
|
||||
cfg_hide => doc_cfg_hide
|
||||
masked => doc_masked
|
||||
notable_trait => doc_notable_trait
|
||||
keyword => doc_keyword
|
||||
|
@ -380,6 +380,9 @@ declare_features! (
|
||||
/// Allows `#[doc(cfg(...))]`.
|
||||
(active, doc_cfg, "1.21.0", Some(43781), None),
|
||||
|
||||
/// Allows `#[doc(cfg_hide(...))]`.
|
||||
(active, doc_cfg_hide, "1.49.0", Some(43781), None),
|
||||
|
||||
/// Allows `#[doc(masked)]`.
|
||||
(active, doc_masked, "1.21.0", Some(44027), None),
|
||||
|
||||
|
@ -399,6 +399,7 @@ symbols! {
|
||||
cfg_attr_multi,
|
||||
cfg_doctest,
|
||||
cfg_eval,
|
||||
cfg_hide,
|
||||
cfg_panic,
|
||||
cfg_sanitize,
|
||||
cfg_target_abi,
|
||||
@ -547,6 +548,7 @@ symbols! {
|
||||
doc,
|
||||
doc_alias,
|
||||
doc_cfg,
|
||||
doc_cfg_hide,
|
||||
doc_keyword,
|
||||
doc_masked,
|
||||
doc_notable_trait,
|
||||
|
@ -318,10 +318,10 @@ fn merge_attrs(
|
||||
} else {
|
||||
Attributes::from_ast(&both, None)
|
||||
},
|
||||
both.cfg(cx.tcx),
|
||||
both.cfg(cx.tcx, &cx.cache.hidden_cfg),
|
||||
)
|
||||
} else {
|
||||
(old_attrs.clean(cx), old_attrs.cfg(cx.tcx))
|
||||
(old_attrs.clean(cx), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.tcx),
|
||||
cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
|
||||
}]
|
||||
}
|
||||
|
||||
|
@ -421,7 +421,7 @@ impl Item {
|
||||
kind,
|
||||
box ast_attrs.clean(cx),
|
||||
cx,
|
||||
ast_attrs.cfg(cx.tcx),
|
||||
ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
|
||||
)
|
||||
}
|
||||
|
||||
@ -747,7 +747,7 @@ crate trait AttributesExt {
|
||||
|
||||
fn other_attrs(&self) -> Vec<ast::Attribute>;
|
||||
|
||||
fn cfg(&self, tcx: TyCtxt<'_>) -> Option<Arc<Cfg>>;
|
||||
fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>>;
|
||||
}
|
||||
|
||||
impl AttributesExt for [ast::Attribute] {
|
||||
@ -772,7 +772,7 @@ impl AttributesExt for [ast::Attribute] {
|
||||
self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect()
|
||||
}
|
||||
|
||||
fn cfg(&self, tcx: TyCtxt<'_>) -> Option<Arc<Cfg>> {
|
||||
fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>> {
|
||||
let sess = tcx.sess;
|
||||
let doc_cfg_active = tcx.features().doc_cfg;
|
||||
|
||||
@ -813,6 +813,7 @@ impl AttributesExt for [ast::Attribute] {
|
||||
.filter_map(|attr| {
|
||||
Cfg::parse(&attr).map_err(|e| sess.diagnostic().span_err(e.span, e.msg)).ok()
|
||||
})
|
||||
.filter(|cfg| !hidden_cfg.contains(cfg))
|
||||
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
|
||||
}
|
||||
} else {
|
||||
@ -844,6 +845,8 @@ impl AttributesExt for [ast::Attribute] {
|
||||
}
|
||||
}
|
||||
|
||||
// treat #[target_feature(enable = "feat")] attributes as if they were
|
||||
// #[doc(cfg(target_feature = "feat"))] attributes as well
|
||||
for attr in self.lists(sym::target_feature) {
|
||||
if attr.has_name(sym::enable) {
|
||||
if let Some(feat) = attr.value_str() {
|
||||
|
@ -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.tcx) {
|
||||
if let Some(ref cfg) = ast_attrs.cfg(self.tcx, &FxHashSet::default()) {
|
||||
if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) {
|
||||
return;
|
||||
}
|
||||
|
@ -119,6 +119,8 @@ crate struct Cache {
|
||||
///
|
||||
/// Links are indexed by the DefId of the item they document.
|
||||
crate intra_doc_links: FxHashMap<ItemId, Vec<clean::ItemLink>>,
|
||||
/// Cfg that have been hidden via #![doc(cfg_hide(...))]
|
||||
crate hidden_cfg: FxHashSet<clean::cfg::Cfg>,
|
||||
}
|
||||
|
||||
/// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`.
|
||||
|
@ -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.tcx()),
|
||||
cfg: ast_attrs.cfg(cx.tcx(), &cx.cache().hidden_cfg),
|
||||
..myitem.clone()
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::CRATE_HIR_ID;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::Node;
|
||||
@ -15,7 +16,7 @@ use rustc_span::symbol::{kw, sym, Symbol};
|
||||
|
||||
use std::mem;
|
||||
|
||||
use crate::clean::{self, AttributesExt, NestedAttributesExt};
|
||||
use crate::clean::{self, cfg::Cfg, AttributesExt, NestedAttributesExt};
|
||||
use crate::core;
|
||||
use crate::doctree::*;
|
||||
|
||||
@ -97,6 +98,27 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.cx.cache.hidden_cfg = self.cx.tcx.hir().attrs(CRATE_HIR_ID)
|
||||
.iter()
|
||||
.filter(|attr| attr.has_name(sym::doc))
|
||||
.flat_map(|attr| attr.meta_item_list().into_iter().flatten())
|
||||
.filter(|attr| attr.has_name(sym::cfg_hide))
|
||||
.flat_map(|attr| {
|
||||
attr.meta_item_list()
|
||||
.unwrap_or(&[])
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
Some(
|
||||
Cfg::parse(attr.meta_item()?)
|
||||
.map_err(|e| self.cx.sess().diagnostic().span_err(e.span, e.msg))
|
||||
.ok()?,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.cx.cache.exact_paths = self.exact_paths;
|
||||
top_level_module
|
||||
}
|
||||
|
32
src/test/rustdoc/doc-cfg-hide.rs
Normal file
32
src/test/rustdoc/doc-cfg-hide.rs
Normal file
@ -0,0 +1,32 @@
|
||||
#![crate_name = "oud"]
|
||||
#![feature(doc_cfg, doc_cfg_hide)]
|
||||
|
||||
#![doc(cfg_hide(feature = "solecism"))]
|
||||
|
||||
// @has 'oud/struct.Solecism.html'
|
||||
// @count - '//*[@class="stab portability"]' 0
|
||||
// compile-flags:--cfg feature="solecism"
|
||||
#[cfg(feature = "solecism")]
|
||||
pub struct Solecism;
|
||||
|
||||
// @has 'oud/struct.Scribacious.html'
|
||||
// @count - '//*[@class="stab portability"]' 1
|
||||
// @matches - '//*[@class="stab portability"]' 'crate feature solecism'
|
||||
#[cfg(feature = "solecism")]
|
||||
#[doc(cfg(feature = "solecism"))]
|
||||
pub struct Scribacious;
|
||||
|
||||
// @has 'oud/struct.Hyperdulia.html'
|
||||
// @count - '//*[@class="stab portability"]' 1
|
||||
// @matches - '//*[@class="stab portability"]' 'crate feature hyperdulia'
|
||||
// compile-flags:--cfg feature="hyperdulia"
|
||||
#[cfg(feature = "solecism")]
|
||||
#[cfg(feature = "hyperdulia")]
|
||||
pub struct Hyperdulia;
|
||||
|
||||
// @has 'oud/struct.Oystercatcher.html'
|
||||
// @count - '//*[@class="stab portability"]' 1
|
||||
// @matches - '//*[@class="stab portability"]' 'crate features solecism and oystercatcher'
|
||||
// compile-flags:--cfg feature="oystercatcher"
|
||||
#[cfg(all(feature = "solecism", feature = "oystercatcher"))]
|
||||
pub struct Oystercatcher;
|
Loading…
Reference in New Issue
Block a user