Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -675,6 +675,9 @@ declare_features! (
/// Allows `#[track_caller]` on closures and generators.
(active, closure_track_caller, "1.57.0", Some(87417), None),

/// Allows `#[doc(cfg_hide(...))]`.
(active, doc_cfg_hide, "1.57.0", Some(43781), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
1 change: 1 addition & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
@@ -908,6 +908,7 @@ impl CheckAttrVisitor<'tcx> {
// plugins: removed, but rustdoc warns about it itself
sym::alias
| sym::cfg
| sym::cfg_hide
| sym::hidden
| sym::html_favicon_url
| sym::html_logo_url
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -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,
6 changes: 6 additions & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -67,6 +67,10 @@
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
)]
#![cfg_attr(
not(bootstrap),
doc(cfg_hide(not(test), not(any(test, bootstrap)), target_has_atomic = "ptr"))
)]
#![no_std]
#![needs_allocator]
#![warn(deprecated_in_future)]
@@ -146,6 +150,8 @@
#![feature(associated_type_bounds)]
#![feature(slice_group_by)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
// Allow testing this library

#[cfg(test)]
25 changes: 25 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -60,6 +60,30 @@
test(no_crate_inject, attr(deny(warnings))),
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
)]
#![cfg_attr(
not(bootstrap),
doc(cfg_hide(
not(test),
target_pointer_width = "16",
target_pointer_width = "32",
target_pointer_width = "64",
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr",
target_has_atomic_equal_alignment = "8",
target_has_atomic_equal_alignment = "16",
target_has_atomic_equal_alignment = "32",
target_has_atomic_equal_alignment = "64",
target_has_atomic_equal_alignment = "ptr",
target_has_atomic_load_store = "8",
target_has_atomic_load_store = "16",
target_has_atomic_load_store = "32",
target_has_atomic_load_store = "64",
target_has_atomic_load_store = "ptr",
))
)]
#![no_core]
//
// Lints:
@@ -133,6 +157,7 @@
#![feature(doc_notable_trait)]
#![feature(doc_primitive)]
#![feature(exhaustive_patterns)]
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(if_let_guard)]
2 changes: 2 additions & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -195,6 +195,7 @@
test(no_crate_inject, attr(deny(warnings))),
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
)]
#![cfg_attr(not(bootstrap), doc(cfg_hide(not(test), not(any(test, bootstrap)))))]
// Don't link to std. We are std.
#![no_std]
#![warn(deprecated_in_future)]
@@ -263,6 +264,7 @@
#![feature(custom_test_frameworks)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
#![feature(doc_keyword)]
#![feature(doc_masked)]
#![feature(doc_notable_trait)]
6 changes: 6 additions & 0 deletions library/std/src/os/raw/mod.rs
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ macro_rules! type_alias {
}

type_alias! { "char.md", c_char = u8, NonZero_c_char = NonZeroU8;
#[doc(cfg(all()))]
#[cfg(any(
all(
target_os = "linux",
@@ -88,6 +89,7 @@ type_alias! { "char.md", c_char = u8, NonZero_c_char = NonZeroU8;
all(target_os = "fuchsia", target_arch = "aarch64")
))]}
type_alias! { "char.md", c_char = i8, NonZero_c_char = NonZeroI8;
#[doc(cfg(all()))]
#[cfg(not(any(
all(
target_os = "linux",
@@ -136,12 +138,16 @@ type_alias! { "ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
type_alias! { "int.md", c_int = i32, NonZero_c_int = NonZeroI32; }
type_alias! { "uint.md", c_uint = u32, NonZero_c_uint = NonZeroU32; }
type_alias! { "long.md", c_long = i32, NonZero_c_long = NonZeroI32;
#[doc(cfg(all()))]
#[cfg(any(target_pointer_width = "32", windows))] }
type_alias! { "ulong.md", c_ulong = u32, NonZero_c_ulong = NonZeroU32;
#[doc(cfg(all()))]
#[cfg(any(target_pointer_width = "32", windows))] }
type_alias! { "long.md", c_long = i64, NonZero_c_long = NonZeroI64;
#[doc(cfg(all()))]
#[cfg(all(target_pointer_width = "64", not(windows)))] }
type_alias! { "ulong.md", c_ulong = u64, NonZero_c_ulong = NonZeroU64;
#[doc(cfg(all()))]
#[cfg(all(target_pointer_width = "64", not(windows)))] }
type_alias! { "longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
type_alias! { "ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
2 changes: 2 additions & 0 deletions library/std/src/os/windows/raw.rs
Original file line number Diff line number Diff line change
@@ -7,8 +7,10 @@ use crate::os::raw::c_void;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type HANDLE = *mut c_void;
#[cfg(target_pointer_width = "32")]
#[doc(cfg(all()))]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type SOCKET = u32;
#[cfg(target_pointer_width = "64")]
#[doc(cfg(all()))]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type SOCKET = u64;
4 changes: 2 additions & 2 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
@@ -318,10 +318,10 @@ fn merge_attrs(
} else {
Attributes::from_ast(&both, None)
},
both.cfg(cx.sess()),
both.cfg(cx.tcx, &cx.cache.hidden_cfg),
)
} else {
(old_attrs.clean(cx), old_attrs.cfg(cx.sess()))
(old_attrs.clean(cx), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg))
}
}

2 changes: 1 addition & 1 deletion src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -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, &cx.cache.hidden_cfg),
}]
}

43 changes: 39 additions & 4 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
@@ -421,7 +421,7 @@ impl Item {
kind,
box ast_attrs.clean(cx),
cx,
ast_attrs.cfg(cx.sess()),
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, sess: &Session) -> Option<Arc<Cfg>>;
fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>>;
}

impl AttributesExt for [ast::Attribute] {
@@ -772,8 +772,41 @@ 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<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>> {
let sess = tcx.sess;
let doc_cfg_active = tcx.features().doc_cfg;

fn single<T: IntoIterator>(it: T) -> Option<T::Item> {
let mut iter = it.into_iter();
let item = iter.next()?;
if iter.next().is_some() {
return None;
}
Some(item)
}

let mut cfg = if doc_cfg_active {
let mut doc_cfg = self
.iter()
.filter(|attr| attr.has_name(sym::doc))
.flat_map(|attr| attr.meta_item_list().unwrap_or_else(Vec::new))
.filter(|attr| attr.has_name(sym::cfg))
.peekable();
if doc_cfg.peek().is_some() {
doc_cfg
.filter_map(|attr| Cfg::parse(attr.meta_item()?).ok())
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
} else {
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))
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
}
} else {
Cfg::True
};

for attr in self.iter() {
// #[doc]
@@ -800,6 +833,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() {
2 changes: 1 addition & 1 deletion src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
@@ -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, &FxHashSet::default()) {
if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) {
return;
}
2 changes: 2 additions & 0 deletions src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
@@ -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`.
2 changes: 1 addition & 1 deletion src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
@@ -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(), &cx.cache().hidden_cfg),
..myitem.clone()
};

28 changes: 27 additions & 1 deletion src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::Node;
use rustc_hir::CRATE_HIR_ID;
use rustc_middle::middle::privacy::AccessLevel;
use rustc_middle::ty::TyCtxt;
use rustc_span;
@@ -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,31 @@ 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
}
9 changes: 9 additions & 0 deletions src/test/rustdoc-ui/doc-cfg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(doc_cfg)]

#[doc(cfg(), cfg(foo, bar))]
//~^ ERROR
//~^^ ERROR
#[doc(cfg(foo), cfg(bar))] // ok!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be ignored, right, because you use single()? That doesn't seem right, either they should be ANDed or it should give a hard error.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid and is supposed to work. I added it to ensure that rustdoc was happy with it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to put it into a rustdoc test though. I'll do that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#[doc(cfg())] //~ ERROR
#[doc(cfg(foo, bar))] //~ ERROR
pub fn foo() {}
26 changes: 26 additions & 0 deletions src/test/rustdoc-ui/doc-cfg.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: `cfg` predicate is not specified
--> $DIR/doc-cfg.rs:3:7
|
LL | #[doc(cfg(), cfg(foo, bar))]
| ^^^^^

error: multiple `cfg` predicates are specified
--> $DIR/doc-cfg.rs:3:23
|
LL | #[doc(cfg(), cfg(foo, bar))]
| ^^^

error: `cfg` predicate is not specified
--> $DIR/doc-cfg.rs:7:7
|
LL | #[doc(cfg())]
| ^^^^^

error: multiple `cfg` predicates are specified
--> $DIR/doc-cfg.rs:8:16
|
LL | #[doc(cfg(foo, bar))]
| ^^^

error: aborting due to 4 previous errors

7 changes: 7 additions & 0 deletions src/test/rustdoc-ui/feature-gate-doc_cfg_hide.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![doc(cfg_hide(test))]
//~^ ERROR `#[doc(cfg_hide)]` is experimental

#[cfg(not(test))]
pub fn public_fn() {}
#[cfg(test)]
pub fn internal_use_only() {}
14 changes: 14 additions & 0 deletions src/test/rustdoc-ui/feature-gate-doc_cfg_hide.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0658]: `#[doc(cfg_hide)]` is experimental
--> $DIR/feature-gate-doc_cfg_hide.rs:1:1
|
LL | #![doc(cfg_hide(test))]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
= help: add `#![feature(doc_cfg_hide)]` to the crate attributes to enable

error: Compilation failed, aborting rustdoc

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.
32 changes: 32 additions & 0 deletions src/test/rustdoc/doc-cfg-hide.rs
Original file line number Diff line number Diff line change
@@ -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;
7 changes: 7 additions & 0 deletions src/test/rustdoc/doc-cfg-implicit-gate.rs
Original file line number Diff line number Diff line change
@@ -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;
31 changes: 31 additions & 0 deletions src/test/rustdoc/doc-cfg-implicit.rs
Original file line number Diff line number Diff line change
@@ -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;