mirror of https://github.com/rust-lang/rust.git
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)
This commit is contained in:
parent
074f63648b
commit
10cdbd847f
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
}]
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
Loading…
Reference in New Issue