Rollup merge of #92856 - GuillaumeGomez:exclude-test-doc_auto_cfg, r=Nemo157
Exclude "test" from doc_auto_cfg Fixes #91740. cc `@Nemo157` (you were the one suggesting this iirc) r? `@camelid`
This commit is contained in:
commit
10a7204af9
5 changed files with 74 additions and 43 deletions
|
@ -8,6 +8,7 @@ use std::mem;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
use rustc_ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem};
|
use rustc_ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem};
|
||||||
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_feature::Features;
|
use rustc_feature::Features;
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
|
@ -43,15 +44,72 @@ crate struct InvalidCfgError {
|
||||||
|
|
||||||
impl Cfg {
|
impl Cfg {
|
||||||
/// Parses a `NestedMetaItem` into a `Cfg`.
|
/// Parses a `NestedMetaItem` into a `Cfg`.
|
||||||
fn parse_nested(nested_cfg: &NestedMetaItem) -> Result<Cfg, InvalidCfgError> {
|
fn parse_nested(
|
||||||
|
nested_cfg: &NestedMetaItem,
|
||||||
|
exclude: &FxHashSet<Cfg>,
|
||||||
|
) -> Result<Option<Cfg>, InvalidCfgError> {
|
||||||
match nested_cfg {
|
match nested_cfg {
|
||||||
NestedMetaItem::MetaItem(ref cfg) => Cfg::parse(cfg),
|
NestedMetaItem::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude),
|
||||||
NestedMetaItem::Literal(ref lit) => {
|
NestedMetaItem::Literal(ref lit) => {
|
||||||
Err(InvalidCfgError { msg: "unexpected literal", span: lit.span })
|
Err(InvalidCfgError { msg: "unexpected literal", span: lit.span })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate fn parse_without(
|
||||||
|
cfg: &MetaItem,
|
||||||
|
exclude: &FxHashSet<Cfg>,
|
||||||
|
) -> Result<Option<Cfg>, InvalidCfgError> {
|
||||||
|
let name = match cfg.ident() {
|
||||||
|
Some(ident) => ident.name,
|
||||||
|
None => {
|
||||||
|
return Err(InvalidCfgError {
|
||||||
|
msg: "expected a single identifier",
|
||||||
|
span: cfg.span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match cfg.kind {
|
||||||
|
MetaItemKind::Word => {
|
||||||
|
let cfg = Cfg::Cfg(name, None);
|
||||||
|
if exclude.contains(&cfg) { Ok(None) } else { Ok(Some(cfg)) }
|
||||||
|
}
|
||||||
|
MetaItemKind::NameValue(ref lit) => match lit.kind {
|
||||||
|
LitKind::Str(value, _) => {
|
||||||
|
let cfg = Cfg::Cfg(name, Some(value));
|
||||||
|
if exclude.contains(&cfg) { Ok(None) } else { Ok(Some(cfg)) }
|
||||||
|
}
|
||||||
|
_ => Err(InvalidCfgError {
|
||||||
|
// FIXME: if the main #[cfg] syntax decided to support non-string literals,
|
||||||
|
// this should be changed as well.
|
||||||
|
msg: "value of cfg option should be a string literal",
|
||||||
|
span: lit.span,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
MetaItemKind::List(ref items) => {
|
||||||
|
let sub_cfgs =
|
||||||
|
items.iter().filter_map(|i| Cfg::parse_nested(i, exclude).transpose());
|
||||||
|
let ret = match name {
|
||||||
|
sym::all => sub_cfgs.fold(Ok(Cfg::True), |x, y| Ok(x? & y?)),
|
||||||
|
sym::any => sub_cfgs.fold(Ok(Cfg::False), |x, y| Ok(x? | y?)),
|
||||||
|
sym::not => {
|
||||||
|
let mut sub_cfgs = sub_cfgs.collect::<Vec<_>>();
|
||||||
|
if sub_cfgs.len() == 1 {
|
||||||
|
Ok(!sub_cfgs.pop().unwrap()?)
|
||||||
|
} else {
|
||||||
|
Err(InvalidCfgError { msg: "expected 1 cfg-pattern", span: cfg.span })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(InvalidCfgError { msg: "invalid predicate", span: cfg.span }),
|
||||||
|
};
|
||||||
|
match ret {
|
||||||
|
Ok(c) => Ok(Some(c)),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses a `MetaItem` into a `Cfg`.
|
/// Parses a `MetaItem` into a `Cfg`.
|
||||||
///
|
///
|
||||||
/// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or
|
/// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or
|
||||||
|
@ -60,42 +118,7 @@ impl Cfg {
|
||||||
/// If the content is not properly formatted, it will return an error indicating what and where
|
/// If the content is not properly formatted, it will return an error indicating what and where
|
||||||
/// the error is.
|
/// the error is.
|
||||||
crate fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
|
crate fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
|
||||||
let name = match cfg.ident() {
|
Self::parse_without(cfg, &FxHashSet::default()).map(|ret| ret.unwrap())
|
||||||
Some(ident) => ident.name,
|
|
||||||
None => {
|
|
||||||
return Err(InvalidCfgError {
|
|
||||||
msg: "expected a single identifier",
|
|
||||||
span: cfg.span,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
match cfg.kind {
|
|
||||||
MetaItemKind::Word => Ok(Cfg::Cfg(name, None)),
|
|
||||||
MetaItemKind::NameValue(ref lit) => match lit.kind {
|
|
||||||
LitKind::Str(value, _) => Ok(Cfg::Cfg(name, Some(value))),
|
|
||||||
_ => Err(InvalidCfgError {
|
|
||||||
// FIXME: if the main #[cfg] syntax decided to support non-string literals,
|
|
||||||
// this should be changed as well.
|
|
||||||
msg: "value of cfg option should be a string literal",
|
|
||||||
span: lit.span,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
MetaItemKind::List(ref items) => {
|
|
||||||
let mut sub_cfgs = items.iter().map(Cfg::parse_nested);
|
|
||||||
match name {
|
|
||||||
sym::all => sub_cfgs.fold(Ok(Cfg::True), |x, y| Ok(x? & y?)),
|
|
||||||
sym::any => sub_cfgs.fold(Ok(Cfg::False), |x, y| Ok(x? | y?)),
|
|
||||||
sym::not => {
|
|
||||||
if sub_cfgs.len() == 1 {
|
|
||||||
Ok(!sub_cfgs.next().unwrap()?)
|
|
||||||
} else {
|
|
||||||
Err(InvalidCfgError { msg: "expected 1 cfg-pattern", span: cfg.span })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Err(InvalidCfgError { msg: "invalid predicate", span: cfg.span }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether the given configuration can be matched in the current session.
|
/// Checks whether the given configuration can be matched in the current session.
|
||||||
|
|
|
@ -831,8 +831,9 @@ impl AttributesExt for [ast::Attribute] {
|
||||||
self.iter()
|
self.iter()
|
||||||
.filter(|attr| attr.has_name(sym::cfg))
|
.filter(|attr| attr.has_name(sym::cfg))
|
||||||
.filter_map(|attr| single(attr.meta_item_list()?))
|
.filter_map(|attr| single(attr.meta_item_list()?))
|
||||||
.filter_map(|attr| Cfg::parse(attr.meta_item()?).ok())
|
.filter_map(|attr| {
|
||||||
.filter(|cfg| !hidden_cfg.contains(cfg))
|
Cfg::parse_without(attr.meta_item()?, hidden_cfg).ok().flatten()
|
||||||
|
})
|
||||||
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
|
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
|
||||||
} else {
|
} else {
|
||||||
Cfg::True
|
Cfg::True
|
||||||
|
|
|
@ -141,6 +141,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
})
|
})
|
||||||
|
.chain([Cfg::Cfg(sym::test, None)].into_iter())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.cx.cache.exact_paths = self.exact_paths;
|
self.cx.cache.exact_paths = self.exact_paths;
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
// @has foo/fn.foo.html
|
// @has foo/fn.foo.html
|
||||||
// @has - '//*[@class="item-info"]/*[@class="stab portability"]' 'non-test'
|
// @has - '//*[@class="item-info"]/*[@class="stab portability"]' 'non-doctest'
|
||||||
#[cfg(not(test))]
|
#[cfg(not(doctest))]
|
||||||
pub fn foo() {}
|
pub fn foo() {}
|
||||||
|
|
||||||
|
// @has foo/fn.bar.html
|
||||||
|
// @has - '//*[@class="item-info"]/*[@class="stab portability"]' 'doc'
|
||||||
|
// @!has - '//*[@class="item-info"]/*[@class="stab portability"]' 'test'
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
pub fn bar() {}
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub struct Hyperdulia;
|
||||||
|
|
||||||
// @has 'oud/struct.Oystercatcher.html'
|
// @has 'oud/struct.Oystercatcher.html'
|
||||||
// @count - '//*[@class="stab portability"]' 1
|
// @count - '//*[@class="stab portability"]' 1
|
||||||
// @matches - '//*[@class="stab portability"]' 'crate features solecism and oystercatcher'
|
// @matches - '//*[@class="stab portability"]' 'crate feature oystercatcher only'
|
||||||
// compile-flags:--cfg feature="oystercatcher"
|
// compile-flags:--cfg feature="oystercatcher"
|
||||||
#[cfg(all(feature = "solecism", feature = "oystercatcher"))]
|
#[cfg(all(feature = "solecism", feature = "oystercatcher"))]
|
||||||
pub struct Oystercatcher;
|
pub struct Oystercatcher;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue