Skip to content

Commit

Permalink
Rollup merge of #92856 - GuillaumeGomez:exclude-test-doc_auto_cfg, r=…
Browse files Browse the repository at this point in the history
…Nemo157

Exclude "test" from doc_auto_cfg

Fixes #91740.

cc `@Nemo157` (you were the one suggesting this iirc)
r? `@camelid`
  • Loading branch information
matthiaskrgr committed Jan 20, 2022
2 parents 3d10c64 + b0df765 commit 10a7204
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 20 deletions.
53 changes: 38 additions & 15 deletions src/librustdoc/clean/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::mem;
use std::ops;

use rustc_ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem};
use rustc_data_structures::fx::FxHashSet;
use rustc_feature::Features;
use rustc_session::parse::ParseSess;
use rustc_span::symbol::{sym, Symbol};
Expand Down Expand Up @@ -43,23 +44,22 @@ crate struct InvalidCfgError {

impl 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 {
NestedMetaItem::MetaItem(ref cfg) => Cfg::parse(cfg),
NestedMetaItem::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude),
NestedMetaItem::Literal(ref lit) => {
Err(InvalidCfgError { msg: "unexpected literal", span: lit.span })
}
}
}

/// Parses a `MetaItem` into a `Cfg`.
///
/// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or
/// `target_os = "redox"`.
///
/// If the content is not properly formatted, it will return an error indicating what and where
/// the error is.
crate fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
crate fn parse_without(
cfg: &MetaItem,
exclude: &FxHashSet<Cfg>,
) -> Result<Option<Cfg>, InvalidCfgError> {
let name = match cfg.ident() {
Some(ident) => ident.name,
None => {
Expand All @@ -70,9 +70,15 @@ impl Cfg {
}
};
match cfg.kind {
MetaItemKind::Word => Ok(Cfg::Cfg(name, None)),
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, _) => Ok(Cfg::Cfg(name, Some(value))),
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.
Expand All @@ -81,23 +87,40 @@ impl Cfg {
}),
},
MetaItemKind::List(ref items) => {
let mut sub_cfgs = items.iter().map(Cfg::parse_nested);
match name {
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.next().unwrap()?)
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`.
///
/// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or
/// `target_os = "redox"`.
///
/// If the content is not properly formatted, it will return an error indicating what and where
/// the error is.
crate fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
Self::parse_without(cfg, &FxHashSet::default()).map(|ret| ret.unwrap())
}

/// Checks whether the given configuration can be matched in the current session.
///
/// Equivalent to `attr::cfg_matches`.
Expand Down
5 changes: 3 additions & 2 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -831,8 +831,9 @@ impl AttributesExt for [ast::Attribute] {
self.iter()
.filter(|attr| attr.has_name(sym::cfg))
.filter_map(|attr| single(attr.meta_item_list()?))
.filter_map(|attr| Cfg::parse(attr.meta_item()?).ok())
.filter(|cfg| !hidden_cfg.contains(cfg))
.filter_map(|attr| {
Cfg::parse_without(attr.meta_item()?, hidden_cfg).ok().flatten()
})
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
} else {
Cfg::True
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
})
.collect::<Vec<_>>()
})
.chain([Cfg::Cfg(sym::test, None)].into_iter())
.collect();

self.cx.cache.exact_paths = self.exact_paths;
Expand Down
10 changes: 8 additions & 2 deletions src/test/rustdoc/doc-auto-cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
#![crate_name = "foo"]

// @has foo/fn.foo.html
// @has - '//*[@class="item-info"]/*[@class="stab portability"]' 'non-test'
#[cfg(not(test))]
// @has - '//*[@class="item-info"]/*[@class="stab portability"]' 'non-doctest'
#[cfg(not(doctest))]
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() {}
2 changes: 1 addition & 1 deletion src/test/rustdoc/doc-cfg-hide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct Hyperdulia;

// @has 'oud/struct.Oystercatcher.html'
// @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"
#[cfg(all(feature = "solecism", feature = "oystercatcher"))]
pub struct Oystercatcher;

0 comments on commit 10a7204

Please sign in to comment.