Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make cfg imply doc(cfg) #79341

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
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
Expand Up @@ -320,6 +320,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_doc!(
include => external_doc
cfg => doc_cfg
cfg_hide => doc_cfg_hide
masked => doc_masked
notable_trait => doc_notable_trait
keyword => doc_keyword
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,9 @@ declare_features! (
/// Allows unsizing coercions in `const fn`.
(active, const_fn_unsize, "1.53.0", Some(64992), None),

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

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,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
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ symbols! {
cfg_attr_multi,
cfg_doctest,
cfg_eval,
cfg_hide,
cfg_panic,
cfg_sanitize,
cfg_target_feature,
Expand Down Expand Up @@ -477,6 +478,7 @@ symbols! {
doc,
doc_alias,
doc_cfg,
doc_cfg_hide,
doc_keyword,
doc_masked,
doc_notable_trait,
Expand Down
7 changes: 6 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
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]
Expand Down Expand Up @@ -146,6 +149,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)]
Expand Down
26 changes: 25 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,30 @@
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(deny(warnings))),
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
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",
Comment on lines +63 to +80
Copy link
Member

Choose a reason for hiding this comment

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

Why hide these?

Copy link
Member Author

Choose a reason for hiding this comment

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

These, along with target_has_atomic_ptr, are unstable cfg. While I think it would be really nice to have this all documented on the items, I don't think the doc(cfg) presentation of them is good enough. I'll attach a screenshot of what it looks like with them unhidden.

I also think it might make sense to enhance doc(cfg_hide) to support specifying just the key of key-value cfg expressions so that these aren't duplicated for each size.

))
)]
#![no_core]
#![warn(deprecated_in_future)]
Expand Down Expand Up @@ -109,6 +132,7 @@
#![feature(custom_inner_attributes)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
#![cfg_attr(bootstrap, feature(doc_spotlight))]
#![cfg_attr(not(bootstrap), feature(doc_notable_trait))]
#![feature(duration_consts_2)]
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(deny(warnings))),
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
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]
Expand Down Expand Up @@ -259,6 +262,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)]
#![cfg_attr(bootstrap, feature(doc_spotlight))]
Expand Down
6 changes: 6 additions & 0 deletions library/std/src/os/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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; }
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/windows/ext/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
9 changes: 8 additions & 1 deletion src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,14 @@ fn merge_attrs(
if let Some(inner) = new_attrs {
if let Some(new_id) = parent_module {
let diag = cx.sess().diagnostic();
Attributes::from_ast(diag, old_attrs, Some((inner, new_id)))
let doc_cfg_active = cx.tcx.features().doc_cfg;
Attributes::from_ast(
diag,
old_attrs,
Some((inner, new_id)),
doc_cfg_active,
&cx.hidden_cfg,
)
} else {
let mut both = inner.to_vec();
both.extend_from_slice(old_attrs);
Expand Down
3 changes: 2 additions & 1 deletion src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ impl Clean<Item> for doctree::Module<'_> {

impl Clean<Attributes> for [ast::Attribute] {
fn clean(&self, cx: &mut DocContext<'_>) -> Attributes {
Attributes::from_ast(cx.sess().diagnostic(), self, None)
let doc_cfg_active = cx.tcx.features().doc_cfg;
Attributes::from_ast(cx.sess().diagnostic(), self, None, doc_cfg_active, &cx.hidden_cfg)
Copy link
Member

Choose a reason for hiding this comment

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

Why put this on Attributes instead of calling tcx.features() on demand?

Copy link
Member

Choose a reason for hiding this comment

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

I found why - you use it directly in from_ast, not after Attributes is constructed. It's either this or pass a tcx; this seems fine.

}
}

Expand Down
115 changes: 64 additions & 51 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,29 +811,6 @@ pub struct RenderedLink {
}

impl Attributes {
/// Extracts the content from an attribute `#[doc(cfg(content))]`.
crate fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
use rustc_ast::NestedMetaItem::MetaItem;

if let ast::MetaItemKind::List(ref nmis) = mi.kind {
if nmis.len() == 1 {
if let MetaItem(ref cfg_mi) = nmis[0] {
if cfg_mi.has_name(sym::cfg) {
if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind {
if cfg_nmis.len() == 1 {
if let MetaItem(ref content_mi) = cfg_nmis[0] {
return Some(content_mi);
}
}
}
}
}
}
}

None
}

/// Reads a `MetaItem` from within an attribute, looks for whether it is a
/// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
/// its expansion.
Expand Down Expand Up @@ -893,10 +870,11 @@ impl Attributes {
diagnostic: &::rustc_errors::Handler,
attrs: &[ast::Attribute],
additional_attrs: Option<(&[ast::Attribute], DefId)>,
doc_cfg_active: bool,
hidden_cfg: &FxHashSet<Cfg>,
) -> Attributes {
let mut doc_strings: Vec<DocFragment> = vec![];
let mut sp = None;
let mut cfg = Cfg::True;
let mut doc_line = 0;

fn update_need_backline(doc_strings: &mut Vec<DocFragment>, frag: &DocFragment) {
Expand Down Expand Up @@ -943,36 +921,27 @@ impl Attributes {
if sp.is_none() {
sp = Some(attr.span);
}
None
} else {
if attr.has_name(sym::doc) {
if let Some(mi) = attr.meta() {
if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
// Extracted #[doc(cfg(...))]
match Cfg::parse(cfg_mi) {
Ok(new_cfg) => cfg &= new_cfg,
Err(e) => diagnostic.span_err(e.span, e.msg),
}
} else if let Some((filename, contents)) = Attributes::extract_include(&mi)
{
let line = doc_line;
doc_line += contents.as_str().lines().count();
let frag = DocFragment {
line,
span: attr.span,
doc: contents,
kind: DocFragmentKind::Include { filename },
parent_module,
need_backline: false,
indent: 0,
};
update_need_backline(&mut doc_strings, &frag);
doc_strings.push(frag);
}
return None;
} else if attr.has_name(sym::doc) {
if let Some(mi) = attr.meta() {
if let Some((filename, contents)) = Attributes::extract_include(&mi) {
let line = doc_line;
doc_line += contents.as_str().lines().count();
let frag = DocFragment {
line,
span: attr.span,
doc: contents,
kind: DocFragmentKind::Include { filename },
parent_module,
need_backline: false,
indent: 0,
};
update_need_backline(&mut doc_strings, &frag);
doc_strings.push(frag);
}
}
Some(attr.clone())
}
Some(attr.clone())
};

// Additional documentation should be shown before the original documentation
Expand All @@ -984,6 +953,50 @@ impl Attributes {
.filter_map(clean_attr)
.collect();

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(())?;
Copy link
Member

Choose a reason for hiding this comment

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

I think this is a little too cute :P

Suggested change
iter.next().is_none().then_some(())?;
if iter.next().is_some() {
return None;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I'll likely scrap the whole SingleExt extension trait as the diagnostics for 0 and >1 items should be different.

Some(item)
}
}

let mut cfg = if doc_cfg_active {
let mut doc_cfg = attrs
.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| diagnostic.span_err(e.span, e.msg)).ok()
})
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
} else {
attrs
.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| diagnostic.span_err(e.span, e.msg)).ok()
})
.filter(|cfg| !hidden_cfg.contains(cfg))
.fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
}
} else {
Cfg::True
};

// treat #[target_feature(enable = "feat")] attributes as if they were
// #[doc(cfg(target_feature = "feat"))] attributes as well
for attr in attrs.lists(sym::target_feature) {
Expand Down
5 changes: 4 additions & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use std::rc::Rc;

use crate::clean;
use crate::clean::inline::build_external_trait;
use crate::clean::{AttributesExt, TraitWithExtraInfo, MAX_DEF_IDX};
use crate::clean::{cfg::Cfg, AttributesExt, TraitWithExtraInfo, MAX_DEF_IDX};
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
use crate::formats::cache::Cache;
use crate::passes::{self, Condition::*, ConditionalPass};
Expand Down Expand Up @@ -84,6 +84,8 @@ crate struct DocContext<'tcx> {
crate inlined: FxHashSet<DefId>,
/// Used by `calculate_doc_coverage`.
crate output_format: OutputFormat,
/// Cfg that have been hidden via #![doc(cfg_hide(...))]
crate hidden_cfg: FxHashSet<Cfg>,
}

impl<'tcx> DocContext<'tcx> {
Expand Down Expand Up @@ -432,6 +434,7 @@ crate fn run_global_ctxt(
inlined: FxHashSet::default(),
output_format,
render_options,
hidden_cfg: FxHashSet::default(),
};

// Small hack to force the Sized trait to be present.
Expand Down
9 changes: 8 additions & 1 deletion src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,8 +1092,15 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> {
sp: Span,
nested: F,
) {
let doc_cfg_active = self.tcx.features().doc_cfg;
let attrs = self.tcx.hir().attrs(hir_id);
let mut attrs = Attributes::from_ast(self.sess.diagnostic(), attrs, None);
let mut attrs = Attributes::from_ast(
self.sess.diagnostic(),
attrs,
None,
doc_cfg_active,
&FxHashSet::default(),
);
if let Some(ref cfg) = attrs.cfg {
if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) {
return;
Expand Down
3 changes: 3 additions & 0 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,13 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl

clean::ImportItem(ref import) => {
let (stab, stab_tags) = if let Some(import_def_id) = import.source.did {
let doc_cfg_active = cx.tcx().features().doc_cfg;
let import_attrs = Box::new(clean::Attributes::from_ast(
cx.tcx().sess().diagnostic(),
cx.tcx().get_attrs(import_def_id),
None,
doc_cfg_active,
&Default::default(), // TODO: this looks wrong
));

// Just need an item with the correct def_id and attrs
Expand Down
Loading