Skip to content

Commit

Permalink
Auto merge of rust-lang#43348 - kennytm:fix-24658-doc-every-platform,…
Browse files Browse the repository at this point in the history
… r=alexcrichton

Expose all OS-specific modules in libstd doc.

1. Uses the special `--cfg dox` configuration passed by rustbuild when running `rustdoc`. Changes the `#[cfg(platform)]` into `#[cfg(any(dox, platform))]` so that platform-specific API are visible to rustdoc.

2. Since platform-specific implementations often won't compile correctly on other platforms, `rustdoc` is changed to apply `everybody_loops` to the functions during documentation and doc-test harness.

3. Since platform-specific code are documented on all platforms now, it could confuse users who found a useful API but is non-portable. Also, their examples will be doc-tested, so must be excluded when not testing on the native platform. An undocumented attribute `#[doc(cfg(...))]` is introduced to serve the above purposed.

Fixes rust-lang#24658 (Does _not_ fully implement rust-lang#1998).
  • Loading branch information
bors committed Aug 13, 2017
2 parents 14fb329 + 3093bb8 commit 0ed03e5
Show file tree
Hide file tree
Showing 23 changed files with 1,261 additions and 75 deletions.
42 changes: 42 additions & 0 deletions src/doc/unstable-book/src/language-features/doc-cfg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# `doc_cfg`

The tracking issue for this feature is: [#43781]

------

The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
This attribute has two effects:

1. In the annotated item's documentation, there will be a message saying "This is supported on
(platform) only".

2. The item's doc-tests will only run on the specific platform.

This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the
standard library be documented.

```rust
#![feature(doc_cfg)]

#[cfg(any(windows, feature = "documentation"))]
#[doc(cfg(windows))]
/// The application's icon in the notification area (a.k.a. system tray).
///
/// # Examples
///
/// ```no_run
/// extern crate my_awesome_ui_library;
/// use my_awesome_ui_library::current_app;
/// use my_awesome_ui_library::windows::notification;
///
/// let icon = current_app().get::<notification::Icon>();
/// icon.show();
/// icon.show_message("Hello");
/// ```
pub struct Icon {
// ...
}
```

[#43781]: https://github.com/rust-lang/rust/issues/43781
[#43348]: https://github.com/rust-lang/rust/issues/43348
62 changes: 32 additions & 30 deletions src/librustc_driver/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use std::io::{self, Write};
use std::option;
use std::path::Path;
use std::str::FromStr;
use std::mem;

use rustc::hir::map as hir_map;
use rustc::hir::map::blocks;
Expand Down Expand Up @@ -618,52 +619,53 @@ impl UserIdentifiedItem {
}
}

struct ReplaceBodyWithLoop {
// Note: Also used by librustdoc, see PR #43348. Consider moving this struct elsewhere.
pub struct ReplaceBodyWithLoop {
within_static_or_const: bool,
}

impl ReplaceBodyWithLoop {
fn new() -> ReplaceBodyWithLoop {
pub fn new() -> ReplaceBodyWithLoop {
ReplaceBodyWithLoop { within_static_or_const: false }
}

fn run<R, F: FnOnce(&mut Self) -> R>(&mut self, is_const: bool, action: F) -> R {
let old_const = mem::replace(&mut self.within_static_or_const, is_const);
let ret = action(self);
self.within_static_or_const = old_const;
ret
}
}

impl fold::Folder for ReplaceBodyWithLoop {
fn fold_item_kind(&mut self, i: ast::ItemKind) -> ast::ItemKind {
match i {
ast::ItemKind::Static(..) |
ast::ItemKind::Const(..) => {
self.within_static_or_const = true;
let ret = fold::noop_fold_item_kind(i, self);
self.within_static_or_const = false;
return ret;
}
_ => fold::noop_fold_item_kind(i, self),
}
let is_const = match i {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
ast::ItemKind::Fn(_, _, ref constness, _, _, _) =>
constness.node == ast::Constness::Const,
_ => false,
};
self.run(is_const, |s| fold::noop_fold_item_kind(i, s))
}

fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem> {
match i.node {
ast::TraitItemKind::Const(..) => {
self.within_static_or_const = true;
let ret = fold::noop_fold_trait_item(i, self);
self.within_static_or_const = false;
return ret;
}
_ => fold::noop_fold_trait_item(i, self),
}
let is_const = match i.node {
ast::TraitItemKind::Const(..) => true,
ast::TraitItemKind::Method(ast::MethodSig { ref constness, .. }, _) =>
constness.node == ast::Constness::Const,
_ => false,
};
self.run(is_const, |s| fold::noop_fold_trait_item(i, s))
}

fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector<ast::ImplItem> {
match i.node {
ast::ImplItemKind::Const(..) => {
self.within_static_or_const = true;
let ret = fold::noop_fold_impl_item(i, self);
self.within_static_or_const = false;
return ret;
}
_ => fold::noop_fold_impl_item(i, self),
}
let is_const = match i.node {
ast::ImplItemKind::Const(..) => true,
ast::ImplItemKind::Method(ast::MethodSig { ref constness, .. }, _) =>
constness.node == ast::Constness::Const,
_ => false,
};
self.run(is_const, |s| fold::noop_fold_impl_item(i, s))
}

fn fold_block(&mut self, b: P<ast::Block>) -> P<ast::Block> {
Expand Down
Loading

0 comments on commit 0ed03e5

Please sign in to comment.