Skip to content

Commit 40feadb

Browse files
committedMar 31, 2017
Auto merge of #40950 - frewsxcv:rollup, r=frewsxcv
Rollup of 10 pull requests - Successful merges: #40694, #40842, #40869, #40888, #40898, #40904, #40925, #40928, #40929, #40934 - Failed merges:
2 parents a9329d3 + c34f533 commit 40feadb

File tree

21 files changed

+330
-129
lines changed

21 files changed

+330
-129
lines changed
 

‎src/Cargo.lock

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/doc/unstable-book/src/SUMMARY.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@
146146
- [proc_macro](proc-macro.md)
147147
- [proc_macro_internals](proc-macro-internals.md)
148148
- [process_try_wait](process-try-wait.md)
149-
- [pub_restricted](pub-restricted.md)
150149
- [question_mark_carrier](question-mark-carrier.md)
151150
- [quote](quote.md)
152151
- [rand](rand.md)
@@ -156,11 +155,11 @@
156155
- [relaxed_adts](relaxed-adts.md)
157156
- [repr_simd](repr-simd.md)
158157
- [retain_hash_collection](retain-hash-collection.md)
158+
- [reverse_cmp_key](reverse-cmp-key.md)
159159
- [rt](rt.md)
160160
- [rustc_attrs](rustc-attrs.md)
161161
- [rustc_diagnostic_macros](rustc-diagnostic-macros.md)
162162
- [rustc_private](rustc-private.md)
163-
- [rustdoc](rustdoc.md)
164163
- [rvalue_static_promotion](rvalue-static-promotion.md)
165164
- [sanitizer_runtime](sanitizer-runtime.md)
166165
- [sanitizer_runtime_lib](sanitizer-runtime-lib.md)
@@ -181,6 +180,7 @@
181180
- [step_by](step-by.md)
182181
- [step_trait](step-trait.md)
183182
- [stmt_expr_attributes](stmt-expr-attributes.md)
183+
- [str_checked_slicing](str-checked-slicing.md)
184184
- [str_escape](str-escape.md)
185185
- [str_internals](str-internals.md)
186186
- [struct_field_attributes](struct-field-attributes.md)

‎src/doc/unstable-book/src/pub-restricted.md

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# `reverse_cmp_key`
2+
3+
The tracking issue for this feature is: [#40893]
4+
5+
[#40893]: https://github.com/rust-lang/rust/issues/40893
6+
7+
------------------------

‎src/doc/unstable-book/src/rustdoc.md

-7
This file was deleted.

‎src/doc/unstable-book/src/specialization.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
The tracking issue for this feature is: [#31844]
44

5+
[#31844]: https://github.com/rust-lang/rust/issues/31844
6+
57
------------------------
68

79

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# `str_checked_slicing`
2+
3+
The tracking issue for this feature is: [#39932]
4+
5+
[#39932]: https://github.com/rust-lang/rust/issues/39932
6+
7+
------------------------

‎src/libcore/cmp.rs

+9
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,15 @@ impl<T: PartialOrd> PartialOrd for Reverse<T> {
347347
fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
348348
other.0.partial_cmp(&self.0)
349349
}
350+
351+
#[inline]
352+
fn lt(&self, other: &Self) -> bool { other.0 < self.0 }
353+
#[inline]
354+
fn le(&self, other: &Self) -> bool { other.0 <= self.0 }
355+
#[inline]
356+
fn ge(&self, other: &Self) -> bool { other.0 >= self.0 }
357+
#[inline]
358+
fn gt(&self, other: &Self) -> bool { other.0 > self.0 }
350359
}
351360

352361
#[unstable(feature = "reverse_cmp_key", issue = "40893")]

‎src/libcore/macros.rs

+16-38
Original file line numberDiff line numberDiff line change
@@ -337,27 +337,20 @@ macro_rules! try {
337337

338338
/// Write formatted data into a buffer
339339
///
340-
/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
341-
/// list of arguments to format.
340+
/// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
341+
/// formatted according to the specified format string and the result will be passed to the writer.
342+
/// The writer may be any value with a `write_fmt` method; generally this comes from an
343+
/// implementation of either the [`std::fmt::Write`] or the [`std::io::Write`] trait. The macro
344+
/// returns whatever the 'write_fmt' method returns; commonly a [`std::fmt::Result`], or an
345+
/// [`io::Result`].
342346
///
343-
/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
344-
/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
345-
/// these two traits.
347+
/// See [`std::fmt`] for more information on the format string syntax.
346348
///
347-
/// Passed arguments will be formatted according to the specified format string and the resulting
348-
/// string will be passed to the writer.
349-
///
350-
/// See [`std::fmt`][fmt] for more information on format syntax.
351-
///
352-
/// `write!` returns whatever the 'write_fmt' method returns.
353-
///
354-
/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
355-
///
356-
/// [fmt]: ../std/fmt/index.html
357-
/// [fmt_write]: ../std/fmt/trait.Write.html
358-
/// [io_write]: ../std/io/trait.Write.html
359-
/// [fmt_result]: ../std/fmt/type.Result.html
360-
/// [io_result]: ../std/io/type.Result.html
349+
/// [`std::fmt`]: ../std/fmt/index.html
350+
/// [`std::fmt::Write`]: ../std/fmt/trait.Write.html
351+
/// [`std::io::Write`]: ../std/io/trait.Write.html
352+
/// [`std::fmt::Result`]: ../std/fmt/type.Result.html
353+
/// [`io::Result`]: ../std/io/type.Result.html
361354
///
362355
/// # Examples
363356
///
@@ -396,27 +389,12 @@ macro_rules! write {
396389
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
397390
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
398391
///
399-
/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
400-
/// list of arguments to format.
401-
///
402-
/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
403-
/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
404-
/// these two traits.
405-
///
406-
/// Passed arguments will be formatted according to the specified format string and the resulting
407-
/// string will be passed to the writer, along with the appended newline.
408-
///
409-
/// See [`std::fmt`][fmt] for more information on format syntax.
410-
///
411-
/// `write!` returns whatever the 'write_fmt' method returns.
392+
/// For more information, see [`write!`]. For information on the format string syntax, see
393+
/// [`std::fmt`].
412394
///
413-
/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
395+
/// [`write!`]: macro.write.html
396+
/// [`std::fmt`]: ../std/fmt/index.html
414397
///
415-
/// [fmt]: ../std/fmt/index.html
416-
/// [fmt_write]: ../std/fmt/trait.Write.html
417-
/// [io_write]: ../std/io/trait.Write.html
418-
/// [fmt_result]: ../std/fmt/type.Result.html
419-
/// [io_result]: ../std/io/type.Result.html
420398
///
421399
/// # Examples
422400
///

‎src/librustc/middle/expr_use_visitor.rs

+2
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
288288
}
289289

290290
pub fn consume_body(&mut self, body: &hir::Body) {
291+
debug!("consume_body(body={:?})", body);
292+
291293
for arg in &body.arguments {
292294
let arg_ty = return_if_err!(self.mc.infcx.node_ty(arg.pat.id));
293295

‎src/librustdoc/html/layout.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ r##"<!DOCTYPE html>
5454
{favicon}
5555
{in_header}
5656
</head>
57-
<body class="rustdoc">
57+
<body class="rustdoc {css_class}">
5858
<!--[if lte IE 8]>
5959
<div class="warning">
6060
This old browser is unsupported and will most likely display funky
@@ -80,7 +80,7 @@ r##"<!DOCTYPE html>
8080
</form>
8181
</nav>
8282
83-
<section id='main' class="content {css_class}">{content}</section>
83+
<section id='main' class="content">{content}</section>
8484
<section id='search' class="content hidden"></section>
8585
8686
<section class="footer"></section>

‎src/librustdoc/html/static/rustdoc.css

+3-3
Original file line numberDiff line numberDiff line change
@@ -141,15 +141,15 @@ pre {
141141
padding: 14px;
142142
}
143143

144-
.source pre {
144+
.source .content pre {
145145
padding: 20px;
146146
}
147147

148148
img {
149149
max-width: 100%;
150150
}
151151

152-
.content.source {
152+
.source .content {
153153
margin-top: 50px;
154154
max-width: none;
155155
overflow: visible;
@@ -231,7 +231,7 @@ nav.sub {
231231
padding: 15px 0;
232232
}
233233

234-
.content.source pre.rust {
234+
.source .content pre.rust {
235235
white-space: pre;
236236
overflow: auto;
237237
padding-left: 0;

‎src/librustdoc/html/static/styles/main.css

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ pre {
4545
background-color: #fff;
4646
}
4747

48+
.source .sidebar {
49+
background-color: #fff;
50+
}
51+
4852
.sidebar .location {
4953
border-color: #000;
5054
background-color: #fff;

‎src/libstd/os/linux/fs.rs

+19
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,55 @@ pub trait MetadataExt {
3434
#[allow(deprecated)]
3535
fn as_raw_stat(&self) -> &raw::stat;
3636

37+
/// Returns the device ID on which this file resides.
3738
#[stable(feature = "metadata_ext2", since = "1.8.0")]
3839
fn st_dev(&self) -> u64;
40+
/// Returns the inode number.
3941
#[stable(feature = "metadata_ext2", since = "1.8.0")]
4042
fn st_ino(&self) -> u64;
43+
/// Returns the file type and mode.
4144
#[stable(feature = "metadata_ext2", since = "1.8.0")]
4245
fn st_mode(&self) -> u32;
46+
/// Returns the number of hard links to file.
4347
#[stable(feature = "metadata_ext2", since = "1.8.0")]
4448
fn st_nlink(&self) -> u64;
49+
/// Returns the user ID of the file owner.
4550
#[stable(feature = "metadata_ext2", since = "1.8.0")]
4651
fn st_uid(&self) -> u32;
52+
/// Returns the group ID of the file owner.
4753
#[stable(feature = "metadata_ext2", since = "1.8.0")]
4854
fn st_gid(&self) -> u32;
55+
/// Returns the device ID that this file represents. Only relevant for special file.
4956
#[stable(feature = "metadata_ext2", since = "1.8.0")]
5057
fn st_rdev(&self) -> u64;
58+
/// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
59+
///
60+
/// The size of a symbolic link is the length of the pathname it contains,
61+
/// without a terminating null byte.
5162
#[stable(feature = "metadata_ext2", since = "1.8.0")]
5263
fn st_size(&self) -> u64;
64+
/// Returns the last access time.
5365
#[stable(feature = "metadata_ext2", since = "1.8.0")]
5466
fn st_atime(&self) -> i64;
67+
/// Returns the last access time, nano seconds part.
5568
#[stable(feature = "metadata_ext2", since = "1.8.0")]
5669
fn st_atime_nsec(&self) -> i64;
70+
/// Returns the last modification time.
5771
#[stable(feature = "metadata_ext2", since = "1.8.0")]
5872
fn st_mtime(&self) -> i64;
73+
/// Returns the last modification time, nano seconds part.
5974
#[stable(feature = "metadata_ext2", since = "1.8.0")]
6075
fn st_mtime_nsec(&self) -> i64;
76+
/// Returns the last status change time.
6177
#[stable(feature = "metadata_ext2", since = "1.8.0")]
6278
fn st_ctime(&self) -> i64;
79+
/// Returns the last status change time, nano seconds part.
6380
#[stable(feature = "metadata_ext2", since = "1.8.0")]
6481
fn st_ctime_nsec(&self) -> i64;
82+
/// Returns the "preferred" blocksize for efficient filesystem I/O.
6583
#[stable(feature = "metadata_ext2", since = "1.8.0")]
6684
fn st_blksize(&self) -> u64;
85+
/// Returns the number of blocks allocated to the file, 512-byte units.
6786
#[stable(feature = "metadata_ext2", since = "1.8.0")]
6887
fn st_blocks(&self) -> u64;
6988
}

‎src/libstd/process.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,20 @@ pub fn exit(code: i32) -> ! {
10561056
/// will be run. If a clean shutdown is needed it is recommended to only call
10571057
/// this function at a known point where there are no more destructors left
10581058
/// to run.
1059+
///
1060+
/// # Examples
1061+
///
1062+
/// ```no_run
1063+
/// use std::process;
1064+
///
1065+
/// fn main() {
1066+
/// println!("aborting");
1067+
///
1068+
/// process::abort();
1069+
///
1070+
/// // execution never gets here
1071+
/// }
1072+
/// ```
10591073
#[stable(feature = "process_abort", since = "1.17.0")]
10601074
pub fn abort() -> ! {
10611075
unsafe { ::sys::abort_internal() };

‎src/libstd/sys/unix/ext/io.rs

+15
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ pub trait IntoRawFd {
7272
fn into_raw_fd(self) -> RawFd;
7373
}
7474

75+
#[stable(feature = "rust1", since = "1.0.0")]
76+
impl AsRawFd for RawFd {
77+
fn as_raw_fd(&self) -> RawFd {
78+
*self
79+
}
80+
}
81+
7582
#[stable(feature = "rust1", since = "1.0.0")]
7683
impl AsRawFd for fs::File {
7784
fn as_raw_fd(&self) -> RawFd {
@@ -84,6 +91,14 @@ impl FromRawFd for fs::File {
8491
fs::File::from_inner(sys::fs::File::from_inner(fd))
8592
}
8693
}
94+
95+
#[stable(feature = "into_raw_os", since = "1.4.0")]
96+
impl IntoRawFd for RawFd {
97+
fn into_raw_fd(self) -> RawFd {
98+
self
99+
}
100+
}
101+
87102
#[stable(feature = "into_raw_os", since = "1.4.0")]
88103
impl IntoRawFd for fs::File {
89104
fn into_raw_fd(self) -> RawFd {

‎src/tools/error_index_generator/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(rustc_private, rustdoc)]
11+
#![feature(rustc_private)]
1212

1313
extern crate syntax;
1414
extern crate rustdoc;

‎src/tools/tidy/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ version = "0.1.0"
44
authors = ["Alex Crichton <alex@alexcrichton.com>"]
55

66
[dependencies]
7+
regex = "0.2"

‎src/tools/tidy/src/features.rs

+81-69
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use std::fs::File;
2424
use std::io::prelude::*;
2525
use std::path::Path;
2626

27-
#[derive(PartialEq)]
28-
enum Status {
27+
#[derive(Debug, PartialEq)]
28+
pub enum Status {
2929
Stable,
3030
Removed,
3131
Unstable,
@@ -42,78 +42,21 @@ impl fmt::Display for Status {
4242
}
4343
}
4444

45-
struct Feature {
46-
level: Status,
47-
since: String,
48-
has_gate_test: bool,
45+
#[derive(Debug)]
46+
pub struct Feature {
47+
pub level: Status,
48+
pub since: String,
49+
pub has_gate_test: bool,
4950
}
5051

5152
pub fn check(path: &Path, bad: &mut bool) {
52-
let mut features = collect_lang_features(&path.join("libsyntax/feature_gate.rs"));
53+
let mut features = collect_lang_features(path);
5354
assert!(!features.is_empty());
54-
let mut lib_features = HashMap::<String, Feature>::new();
55-
56-
let mut contents = String::new();
57-
super::walk(path,
58-
&mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
59-
&mut |file| {
60-
let filename = file.file_name().unwrap().to_string_lossy();
61-
if !filename.ends_with(".rs") || filename == "features.rs" ||
62-
filename == "diagnostic_list.rs" {
63-
return;
64-
}
65-
66-
contents.truncate(0);
67-
t!(t!(File::open(&file), &file).read_to_string(&mut contents));
6855

69-
for (i, line) in contents.lines().enumerate() {
70-
let mut err = |msg: &str| {
71-
println!("{}:{}: {}", file.display(), i + 1, msg);
72-
*bad = true;
73-
};
74-
let level = if line.contains("[unstable(") {
75-
Status::Unstable
76-
} else if line.contains("[stable(") {
77-
Status::Stable
78-
} else {
79-
continue;
80-
};
81-
let feature_name = match find_attr_val(line, "feature") {
82-
Some(name) => name,
83-
None => {
84-
err("malformed stability attribute");
85-
continue;
86-
}
87-
};
88-
let since = match find_attr_val(line, "since") {
89-
Some(name) => name,
90-
None if level == Status::Stable => {
91-
err("malformed stability attribute");
92-
continue;
93-
}
94-
None => "None",
95-
};
56+
let lib_features = collect_lib_features(path, bad, &features);
57+
assert!(!lib_features.is_empty());
9658

97-
if features.contains_key(feature_name) {
98-
err("duplicating a lang feature");
99-
}
100-
if let Some(ref s) = lib_features.get(feature_name) {
101-
if s.level != level {
102-
err("different stability level than before");
103-
}
104-
if s.since != since {
105-
err("different `since` than before");
106-
}
107-
continue;
108-
}
109-
lib_features.insert(feature_name.to_owned(),
110-
Feature {
111-
level: level,
112-
since: since.to_owned(),
113-
has_gate_test: false,
114-
});
115-
}
116-
});
59+
let mut contents = String::new();
11760

11861
super::walk_many(&[&path.join("test/compile-fail"),
11962
&path.join("test/compile-fail-fulldeps"),
@@ -233,8 +176,9 @@ fn test_filen_gate(filen_underscore: &str,
233176
return false;
234177
}
235178

236-
fn collect_lang_features(path: &Path) -> HashMap<String, Feature> {
179+
pub fn collect_lang_features(base_src_path: &Path) -> HashMap<String, Feature> {
237180
let mut contents = String::new();
181+
let path = base_src_path.join("libsyntax/feature_gate.rs");
238182
t!(t!(File::open(path)).read_to_string(&mut contents));
239183

240184
contents.lines()
@@ -257,3 +201,71 @@ fn collect_lang_features(path: &Path) -> HashMap<String, Feature> {
257201
})
258202
.collect()
259203
}
204+
205+
pub fn collect_lib_features(base_src_path: &Path,
206+
bad: &mut bool,
207+
features: &HashMap<String, Feature>) -> HashMap<String, Feature> {
208+
let mut lib_features = HashMap::<String, Feature>::new();
209+
let mut contents = String::new();
210+
super::walk(base_src_path,
211+
&mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
212+
&mut |file| {
213+
let filename = file.file_name().unwrap().to_string_lossy();
214+
if !filename.ends_with(".rs") || filename == "features.rs" ||
215+
filename == "diagnostic_list.rs" {
216+
return;
217+
}
218+
219+
contents.truncate(0);
220+
t!(t!(File::open(&file), &file).read_to_string(&mut contents));
221+
222+
for (i, line) in contents.lines().enumerate() {
223+
let mut err = |msg: &str| {
224+
println!("{}:{}: {}", file.display(), i + 1, msg);
225+
*bad = true;
226+
};
227+
let level = if line.contains("[unstable(") {
228+
Status::Unstable
229+
} else if line.contains("[stable(") {
230+
Status::Stable
231+
} else {
232+
continue;
233+
};
234+
let feature_name = match find_attr_val(line, "feature") {
235+
Some(name) => name,
236+
None => {
237+
err("malformed stability attribute");
238+
continue;
239+
}
240+
};
241+
let since = match find_attr_val(line, "since") {
242+
Some(name) => name,
243+
None if level == Status::Stable => {
244+
err("malformed stability attribute");
245+
continue;
246+
}
247+
None => "None",
248+
};
249+
250+
if features.contains_key(feature_name) {
251+
err("duplicating a lang feature");
252+
}
253+
if let Some(ref s) = lib_features.get(feature_name) {
254+
if s.level != level {
255+
err("different stability level than before");
256+
}
257+
if s.since != since {
258+
err("different `since` than before");
259+
}
260+
continue;
261+
}
262+
lib_features.insert(feature_name.to_owned(),
263+
Feature {
264+
level: level,
265+
since: since.to_owned(),
266+
has_gate_test: false,
267+
});
268+
}
269+
});
270+
lib_features
271+
}

‎src/tools/tidy/src/main.rs

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
//! etc. This is run by default on `make check` and as part of the auto
1515
//! builders.
1616
17+
extern crate regex;
18+
1719
use std::fs;
1820
use std::path::{PathBuf, Path};
1921
use std::env;
@@ -37,6 +39,7 @@ mod features;
3739
mod cargo;
3840
mod pal;
3941
mod deps;
42+
mod unstable_book;
4043

4144
fn main() {
4245
let path = env::args_os().skip(1).next().expect("need an argument");
@@ -51,6 +54,7 @@ fn main() {
5154
cargo::check(&path, &mut bad);
5255
features::check(&path, &mut bad);
5356
pal::check(&path, &mut bad);
57+
unstable_book::check(&path, &mut bad);
5458
if !args.iter().any(|s| *s == "--no-vendor") {
5559
deps::check(&path, &mut bad);
5660
}

‎src/tools/tidy/src/unstable_book.rs

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::collections::HashSet;
12+
use std::fs;
13+
use std::io::{self, BufRead, Write};
14+
use std::path;
15+
use features::{collect_lang_features, collect_lib_features, Status};
16+
17+
const PATH_STR: &'static str = "doc/unstable-book/src";
18+
19+
const SUMMARY_FILE_NAME: &'static str = "SUMMARY.md";
20+
21+
static EXCLUDE: &'static [&'static str; 2] = &[SUMMARY_FILE_NAME, "the-unstable-book.md"];
22+
23+
/// Build the path to the Unstable Book source directory from the Rust 'src' directory
24+
fn unstable_book_path(base_src_path: &path::Path) -> path::PathBuf {
25+
base_src_path.join(PATH_STR)
26+
}
27+
28+
/// Build the path to the Unstable Book SUMMARY file from the Rust 'src' directory
29+
fn unstable_book_summary_path(base_src_path: &path::Path) -> path::PathBuf {
30+
unstable_book_path(base_src_path).join(SUMMARY_FILE_NAME)
31+
}
32+
33+
/// Open the Unstable Book SUMMARY file
34+
fn open_unstable_book_summary_file(base_src_path: &path::Path) -> fs::File {
35+
fs::File::open(unstable_book_summary_path(base_src_path))
36+
.expect("could not open Unstable Book SUMMARY.md")
37+
}
38+
39+
/// Test to determine if DirEntry is a file
40+
fn dir_entry_is_file(dir_entry: &fs::DirEntry) -> bool {
41+
dir_entry.file_type().expect("could not determine file type of directory entry").is_file()
42+
}
43+
44+
/// Retrieve names of all lang-related unstable features
45+
fn collect_unstable_lang_feature_names(base_src_path: &path::Path) -> HashSet<String> {
46+
collect_lang_features(base_src_path)
47+
.into_iter()
48+
.filter(|&(_, ref f)| f.level == Status::Unstable)
49+
.map(|(ref name, _)| name.to_owned())
50+
.collect()
51+
}
52+
53+
/// Retrieve names of all lib-related unstable features
54+
fn collect_unstable_lib_feature_names(base_src_path: &path::Path) -> HashSet<String> {
55+
let mut bad = true;
56+
let lang_features = collect_lang_features(base_src_path);
57+
collect_lib_features(base_src_path, &mut bad, &lang_features)
58+
.into_iter()
59+
.filter(|&(_, ref f)| f.level == Status::Unstable)
60+
.map(|(ref name, _)| name.to_owned())
61+
.collect()
62+
}
63+
64+
/// Retrieve names of all unstable features
65+
fn collect_unstable_feature_names(base_src_path: &path::Path) -> HashSet<String> {
66+
collect_unstable_lib_feature_names(base_src_path)
67+
.union(&collect_unstable_lang_feature_names(base_src_path))
68+
.map(|n| n.to_owned())
69+
.collect::<HashSet<_, _>>()
70+
}
71+
72+
/// Retrieve file names of all sections in the Unstable Book with:
73+
///
74+
/// * hyphens replaced by underscores
75+
/// * the markdown suffix ('.md') removed
76+
fn collect_unstable_book_section_file_names(base_src_path: &path::Path) -> HashSet<String> {
77+
fs::read_dir(unstable_book_path(base_src_path))
78+
.expect("could not read directory")
79+
.into_iter()
80+
.map(|entry| entry.expect("could not read directory entry"))
81+
.filter(dir_entry_is_file)
82+
.map(|entry| entry.file_name().into_string().unwrap())
83+
.filter(|n| EXCLUDE.iter().all(|e| n != e))
84+
.map(|n| n.trim_right_matches(".md").replace('-', "_"))
85+
.collect()
86+
}
87+
88+
/// Retrieve unstable feature names that are in the Unstable Book SUMMARY file
89+
fn collect_unstable_book_summary_links(base_src_path: &path::Path) -> HashSet<String> {
90+
let summary_link_regex =
91+
::regex::Regex::new(r"^- \[(\S+)\]\(\S+\.md\)").expect("invalid regex");
92+
io::BufReader::new(open_unstable_book_summary_file(base_src_path))
93+
.lines()
94+
.map(|l| l.expect("could not read line from file"))
95+
.filter_map(|line| {
96+
summary_link_regex.captures(&line).map(|c| {
97+
c.get(1)
98+
.unwrap()
99+
.as_str()
100+
.to_owned()
101+
})
102+
})
103+
.collect()
104+
}
105+
106+
pub fn check(path: &path::Path, bad: &mut bool) {
107+
let unstable_feature_names = collect_unstable_feature_names(path);
108+
let unstable_book_section_file_names = collect_unstable_book_section_file_names(path);
109+
let unstable_book_links = collect_unstable_book_summary_links(path);
110+
111+
// Check for Unstable Book section names with no corresponding SUMMARY.md link
112+
for feature_name in &unstable_book_section_file_names - &unstable_book_links {
113+
*bad = true;
114+
writeln!(io::stderr(),
115+
"The Unstable Book section '{}' needs to have a link in SUMMARY.md",
116+
feature_name)
117+
.expect("could not write to stderr")
118+
}
119+
120+
// Check for unstable features that don't have Unstable Book sections
121+
for feature_name in &unstable_feature_names - &unstable_book_section_file_names {
122+
*bad = true;
123+
writeln!(io::stderr(),
124+
"Unstable feature '{}' needs to have a section in The Unstable Book",
125+
feature_name)
126+
.expect("could not write to stderr")
127+
}
128+
129+
// Check for Unstable Book sections that don't have a corresponding unstable feature
130+
for feature_name in &unstable_book_section_file_names - &unstable_feature_names {
131+
*bad = true;
132+
writeln!(io::stderr(),
133+
"The Unstable Book has a section '{}' which doesn't correspond \
134+
to an unstable feature",
135+
feature_name)
136+
.expect("could not write to stderr")
137+
}
138+
}

0 commit comments

Comments
 (0)
Please sign in to comment.