diff --git a/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md b/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md index 30d22ca8208bf..e8256469b1450 100644 --- a/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#23121] [#23121]: https://github.com/rust-lang/rust/issues/23121 -See also [`slice_patterns`](slice-patterns.html). +See also [`slice_patterns`](language-features/slice-patterns.html). ------------------------ diff --git a/src/doc/unstable-book/src/language-features/asm.md b/src/doc/unstable-book/src/language-features/asm.md index 5e68be633e7ab..8deb8f4625620 100644 --- a/src/doc/unstable-book/src/language-features/asm.md +++ b/src/doc/unstable-book/src/language-features/asm.md @@ -190,4 +190,4 @@ constraints, etc. [llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions If you need more power and don't mind losing some of the niceties of -`asm!`, check out [global_asm](global_asm.html). +`asm!`, check out [global_asm](language-features/global_asm.html). diff --git a/src/doc/unstable-book/src/language-features/box-patterns.md b/src/doc/unstable-book/src/language-features/box-patterns.md index 86346364a7135..0896627acae1b 100644 --- a/src/doc/unstable-book/src/language-features/box-patterns.md +++ b/src/doc/unstable-book/src/language-features/box-patterns.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#29641] [#29641]: https://github.com/rust-lang/rust/issues/29641 -See also [`box_syntax`](box-syntax.html) +See also [`box_syntax`](language-features/box-syntax.html) ------------------------ diff --git a/src/doc/unstable-book/src/language-features/box-syntax.md b/src/doc/unstable-book/src/language-features/box-syntax.md index 47aade0d04563..50e59231a4df2 100644 --- a/src/doc/unstable-book/src/language-features/box-syntax.md +++ b/src/doc/unstable-book/src/language-features/box-syntax.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#27779] [#27779]: https://github.com/rust-lang/rust/issues/27779 -See also [`box_patterns`](box-patterns.html) +See also [`box_patterns`](language-features/box-patterns.html) ------------------------ diff --git a/src/doc/unstable-book/src/language-features/global_asm.md b/src/doc/unstable-book/src/language-features/global_asm.md index 44921aa309f84..f1ef74a63b513 100644 --- a/src/doc/unstable-book/src/language-features/global_asm.md +++ b/src/doc/unstable-book/src/language-features/global_asm.md @@ -74,5 +74,5 @@ usages and placed the larger, single usage in the crate root. If you don't need quite as much power and flexibility as `global_asm!` provides, and you don't mind restricting your inline -assembly to `fn` bodies only, you might try the [asm](asm.html) -feature instead. +assembly to `fn` bodies only, you might try the +[asm](language-features/asm.html) feature instead. diff --git a/src/doc/unstable-book/src/language-features/plugin-registrar.md b/src/doc/unstable-book/src/language-features/plugin-registrar.md index ca3738bd93f83..b16e2ac2d221c 100644 --- a/src/doc/unstable-book/src/language-features/plugin-registrar.md +++ b/src/doc/unstable-book/src/language-features/plugin-registrar.md @@ -8,6 +8,6 @@ This feature is part of "compiler plugins." It will often be used with the [`plugin`] and `rustc_private` features as well. For more details, see their docs. -[`plugin`]: plugin.html +[`plugin`]: language-features/plugin.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 3a1872e18ddb8..4b8603e3c4450 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -8,7 +8,7 @@ The tracking issue for this feature is: [#29597] This feature is part of "compiler plugins." It will often be used with the [`plugin_registrar`] and `rustc_private` features. -[`plugin_registrar`]: plugin-registrar.html +[`plugin_registrar`]: language-features/plugin-registrar.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md index 1e9e1eaafda46..69857297582da 100644 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/slice-patterns.md @@ -4,7 +4,8 @@ The tracking issue for this feature is: [#23121] [#23121]: https://github.com/rust-lang/rust/issues/23121 -See also [`advanced_slice_patterns`](advanced-slice-patterns.html). +See also +[`advanced_slice_patterns`](language-features/advanced-slice-patterns.html). ------------------------ diff --git a/src/doc/unstable-book/src/library-features/alloc-jemalloc.md b/src/doc/unstable-book/src/library-features/alloc-jemalloc.md index 9bffa2ff99bf3..18ff838dd32b9 100644 --- a/src/doc/unstable-book/src/library-features/alloc-jemalloc.md +++ b/src/doc/unstable-book/src/library-features/alloc-jemalloc.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#33082] [#33082]: https://github.com/rust-lang/rust/issues/33082 -See also [`alloc_system`](alloc-system.html). +See also [`alloc_system`](library-features/alloc-system.html). ------------------------ diff --git a/src/doc/unstable-book/src/library-features/alloc-system.md b/src/doc/unstable-book/src/library-features/alloc-system.md index 6fa89179d8e11..1d261db6ba1b3 100644 --- a/src/doc/unstable-book/src/library-features/alloc-system.md +++ b/src/doc/unstable-book/src/library-features/alloc-system.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#33082] [#33082]: https://github.com/rust-lang/rust/issues/33082 -See also [`alloc_jemalloc`](alloc-jemalloc.html). +See also [`alloc_jemalloc`](library-features/alloc-jemalloc.html). ------------------------ diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 87def375b202b..4825c2aa13264 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -21,7 +21,7 @@ fn float_to_decimal_common_exact(fmt: &mut Formatter, num: &T, { unsafe { let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64 - let mut parts: [flt2dec::Part; 5] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 4] = mem::uninitialized(); let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, false, &mut buf, &mut parts); @@ -39,7 +39,7 @@ fn float_to_decimal_common_shortest(fmt: &mut Formatter, unsafe { // enough for f32 and f64 let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized(); - let mut parts: [flt2dec::Part; 5] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 4] = mem::uninitialized(); let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, 0, false, &mut buf, &mut parts); fmt.pad_formatted_parts(&formatted) @@ -75,7 +75,7 @@ fn float_to_exponential_common_exact(fmt: &mut Formatter, num: &T, { unsafe { let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64 - let mut parts: [flt2dec::Part; 7] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 6] = mem::uninitialized(); let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, upper, &mut buf, &mut parts); @@ -94,7 +94,7 @@ fn float_to_exponential_common_shortest(fmt: &mut Formatter, unsafe { // enough for f32 and f64 let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized(); - let mut parts: [flt2dec::Part; 7] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 6] = mem::uninitialized(); let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, &mut buf, &mut parts); diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index 5123e42df61ca..74b9e7bf37d51 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -410,8 +410,8 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static /// it will only print given digits and nothing else. /// /// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. -/// There should be at least 5 parts available, due to the worst case like -/// `[+][0.][0000][45][0000]` with `frac_digits = 10`. +/// There should be at least 4 parts available, due to the worst case like +/// `[+][0.][0000][2][0000]` with `frac_digits = 10`. pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, sign: Sign, frac_digits: usize, _upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> @@ -465,8 +465,8 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, /// cannot be in this range, avoiding any confusion. /// /// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. -/// There should be at least 7 parts available, due to the worst case like -/// `[+][1][.][2345][e][-][67]`. +/// There should be at least 6 parts available, due to the worst case like +/// `[+][1][.][2345][e][-][6]`. pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, sign: Sign, dec_bounds: (i16, i16), upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> @@ -544,8 +544,8 @@ fn estimate_max_buf_len(exp: i16) -> usize { /// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is /// so large that only the fixed number of digits will be ever written. /// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.) -/// There should be at least 7 parts available, due to the worst case like -/// `[+][1][.][2345][e][-][67]`. +/// There should be at least 6 parts available, due to the worst case like +/// `[+][1][.][2345][e][-][6]`. pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, sign: Sign, ndigits: usize, upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> @@ -600,8 +600,8 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, /// The byte buffer should be enough for the output unless `frac_digits` is /// so large that only the fixed number of digits will be ever written. /// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.) -/// There should be at least 5 parts available, due to the worst case like -/// `[+][0.][0000][45][0000]` with `frac_digits = 10`. +/// There should be at least 4 parts available, due to the worst case like +/// `[+][0.][0000][2][0000]` with `frac_digits = 10`. pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, sign: Sign, frac_digits: usize, _upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 200368be275c3..154406a1d8bd7 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -180,8 +180,33 @@ pub use self::local::{LocalKey, LocalKeyState}; // Builder //////////////////////////////////////////////////////////////////////////////// -/// Thread configuration. Provides detailed control over the properties -/// and behavior of new threads. +/// Thread factory, which can be used in order to configure the properties of +/// a new thread. +/// +/// Methods can be chained on it in order to configure it. +/// +/// The two configurations available are: +/// +/// - [`name`]: allows to give a name to the thread which is currently +/// only used in `panic` messages. +/// - [`stack_size`]: specifies the desired stack size. Note that this can +/// be overriden by the OS. +/// +/// If the [`stack_size`] field is not specified, the stack size +/// will be the `RUST_MIN_STACK` environment variable. If it is +/// not specified either, a sensible default will be set. +/// +/// If the [`name`] field is not specified, the thread will not be named. +/// +/// The [`spawn`] method will take ownership of the builder and create an +/// [`io::Result`] to the thread handle with the given configuration. +/// +/// The [`thread::spawn`] free function uses a `Builder` with default +/// configuration and [`unwrap`]s its return value. +/// +/// You may want to use [`spawn`] instead of [`thread::spawn`], when you want +/// to recover from a failure to launch a thread, indeed the free function will +/// panick where the `Builder` method will return a [`io::Result`]. /// /// # Examples /// @@ -196,6 +221,13 @@ pub use self::local::{LocalKey, LocalKeyState}; /// /// handler.join().unwrap(); /// ``` +/// +/// [`thread::spawn`]: ../../std/thread/fn.spawn.html +/// [`stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size +/// [`name`]: ../../std/thread/struct.Builder.html#method.name +/// [`spawn`]: ../../std/thread/struct.Builder.html#method.spawn +/// [`io::Result`]: ../../std/io/type.Result.html +/// [`unwrap`]: ../../std/result/enum.Result.html#method.unwrap #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] pub struct Builder { @@ -209,11 +241,6 @@ impl Builder { /// Generates the base configuration for spawning a thread, from which /// configuration methods can be chained. /// - /// If the [`stack_size`] field is not specified, the stack size - /// will be the `RUST_MIN_STACK` environment variable. If it is - /// not specified either, a sensible default will be set (2MB as - /// of the writting of this doc). - /// /// # Examples /// /// ``` @@ -229,8 +256,6 @@ impl Builder { /// /// handler.join().unwrap(); /// ``` - /// - /// [`stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> Builder { Builder { @@ -280,9 +305,10 @@ impl Builder { self } - /// Spawns a new thread, and returns a join handle for it. + /// Spawns a new thread by taking ownership of the `Builder`, and returns an + /// [`io::Result`] to its [`JoinHandle`]. /// - /// The child thread may outlive the parent (unless the parent thread + /// The spawned thread may outlive the caller (unless the caller thread /// is the main thread; the whole process is terminated when the main /// thread finishes). The join handle can be used to block on /// termination of the child thread, including recovering its panics. @@ -297,6 +323,7 @@ impl Builder { /// /// [`spawn`]: ../../std/thread/fn.spawn.html /// [`io::Result`]: ../../std/io/type.Result.html + /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html /// /// # Examples /// @@ -468,6 +495,23 @@ pub fn current() -> Thread { /// Cooperatively gives up a timeslice to the OS scheduler. /// +/// This is used when the programmer knows that the thread will have nothing +/// to do for some time, and thus avoid wasting computing time. +/// +/// For example when polling on a resource, it is common to check that it is +/// available, and if not to yield in order to avoid busy waiting. +/// +/// Thus the pattern of `yield`ing after a failed poll is rather common when +/// implementing low-level shared resources or synchronization primitives. +/// +/// However programmers will usualy prefer to use, [`channel`]s, [`Condvar`]s, +/// [`Mutex`]es or [`join`] for their synchronisation routines, as they avoid +/// thinking about thread schedulling. +/// +/// Note that [`channel`]s for example are implemented using this primitive. +/// Indeed when you call `send` or `recv`, which are blocking, they will yield +/// if the channel is not available. +/// /// # Examples /// /// ``` @@ -475,6 +519,12 @@ pub fn current() -> Thread { /// /// thread::yield_now(); /// ``` +/// +/// [`channel`]: ../../std/sync/mpsc/index.html +/// [`spawn`]: ../../std/thread/fn.spawn.html +/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join +/// [`Mutex`]: ../../std/sync/struct.Mutex.html +/// [`Condvar`]: ../../std/sync/struct.Condvar.html #[stable(feature = "rust1", since = "1.0.0")] pub fn yield_now() { imp::Thread::yield_now() diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 3d9a4fba6cdee..1b55dc792c2e5 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -41,7 +41,7 @@ macro_rules! t { } fn main() { - let docs = env::args().nth(1).unwrap(); + let docs = env::args_os().nth(1).unwrap(); let docs = env::current_dir().unwrap().join(docs); let mut errors = false; walk(&mut HashMap::new(), &docs, &docs, &mut errors); @@ -65,7 +65,6 @@ enum Redirect { struct FileEntry { source: String, ids: HashSet, - names: HashSet, } type Cache = HashMap; @@ -73,7 +72,7 @@ type Cache = HashMap; impl FileEntry { fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut bool) { if self.ids.is_empty() { - with_attrs_in_source(contents, " id", |fragment, i| { + with_attrs_in_source(contents, " id", |fragment, i, _| { let frag = fragment.trim_left_matches("#").to_owned(); if !self.ids.insert(frag) { *errors = true; @@ -82,15 +81,6 @@ impl FileEntry { }); } } - - fn parse_names(&mut self, contents: &str) { - if self.names.is_empty() { - with_attrs_in_source(contents, " name", |fragment, _| { - let frag = fragment.trim_left_matches("#").to_owned(); - self.names.insert(frag); - }); - } - } } fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) { @@ -116,15 +106,8 @@ fn check(cache: &mut Cache, file: &Path, errors: &mut bool) -> Option { - // ignore js files as they are not prone to errors as the rest of the - // documentation is and they otherwise bring up false positives. - if file.extension().and_then(|s| s.to_str()) == Some("js") { - return None; - } - - // ignore handlebars files as they use {{}} to build links, we only - // want to test the generated files - if file.extension().and_then(|s| s.to_str()) == Some("hbs") { + // Ignore none HTML files. + if file.extension().and_then(|s| s.to_str()) != Some("html") { return None; } @@ -147,13 +130,7 @@ fn check(cache: &mut Cache, return None; } - // mdbook uses the HTML tag to handle links for subdirectories, which - // linkchecker doesn't support - if file.to_str().unwrap().contains("unstable-book") { - return None; - } - - let res = load_file(cache, root, PathBuf::from(file), SkipRedirect); + let res = load_file(cache, root, file, SkipRedirect); let (pretty_file, contents) = match res { Ok(res) => res, Err(_) => return None, @@ -162,13 +139,10 @@ fn check(cache: &mut Cache, cache.get_mut(&pretty_file) .unwrap() .parse_ids(&pretty_file, &contents, errors); - cache.get_mut(&pretty_file) - .unwrap() - .parse_names(&contents); } // Search for anything that's the regex 'href[ ]*=[ ]*".*?"' - with_attrs_in_source(&contents, " href", |url, i| { + with_attrs_in_source(&contents, " href", |url, i, base| { // Ignore external URLs if url.starts_with("http:") || url.starts_with("https:") || url.starts_with("javascript:") || url.starts_with("ftp:") || @@ -184,9 +158,9 @@ fn check(cache: &mut Cache, // Once we've plucked out the URL, parse it using our base url and // then try to extract a file path. let mut path = file.to_path_buf(); - if !url.is_empty() { + if !base.is_empty() || !url.is_empty() { path.pop(); - for part in Path::new(url).components() { + for part in Path::new(base).join(url).components() { match part { Component::Prefix(_) | Component::RootDir => panic!(), @@ -197,13 +171,6 @@ fn check(cache: &mut Cache, } } - if let Some(extension) = path.extension() { - // don't check these files - if extension == "png" { - return; - } - } - // Alright, if we've found a file name then this file had better // exist! If it doesn't then we register and print an error. if path.exists() { @@ -218,11 +185,17 @@ fn check(cache: &mut Cache, pretty_path.display()); return; } - let res = load_file(cache, root, path.clone(), FromRedirect(false)); + if let Some(extension) = path.extension() { + // Ignore none HTML files. + if extension != "html" { + return; + } + } + let res = load_file(cache, root, &path, FromRedirect(false)); let (pretty_path, contents) = match res { Ok(res) => res, Err(LoadError::IOError(err)) => { - panic!(format!("error loading {}: {}", path.display(), err)); + panic!("error loading {}: {}", path.display(), err); } Err(LoadError::BrokenRedirect(target, _)) => { *errors = true; @@ -245,11 +218,10 @@ fn check(cache: &mut Cache, let entry = &mut cache.get_mut(&pretty_path).unwrap(); entry.parse_ids(&pretty_path, &contents, errors); - entry.parse_names(&contents); - if !(entry.ids.contains(*fragment) || entry.names.contains(*fragment)) { + if !entry.ids.contains(*fragment) { *errors = true; - print!("{}:{}: broken link fragment ", + print!("{}:{}: broken link fragment ", pretty_file.display(), i + 1); println!("`#{}` pointing to `{}`", fragment, pretty_path.display()); @@ -267,7 +239,7 @@ fn check(cache: &mut Cache, fn load_file(cache: &mut Cache, root: &Path, - mut file: PathBuf, + file: &Path, redirect: Redirect) -> Result<(PathBuf, String), LoadError> { let mut contents = String::new(); @@ -279,9 +251,9 @@ fn load_file(cache: &mut Cache, None } Entry::Vacant(entry) => { - let mut fp = File::open(file.clone()).map_err(|err| { + let mut fp = File::open(file).map_err(|err| { if let FromRedirect(true) = redirect { - LoadError::BrokenRedirect(file.clone(), err) + LoadError::BrokenRedirect(file.to_path_buf(), err) } else { LoadError::IOError(err) } @@ -297,17 +269,14 @@ fn load_file(cache: &mut Cache, entry.insert(FileEntry { source: contents.clone(), ids: HashSet::new(), - names: HashSet::new(), }); } maybe } }; - file.pop(); - match maybe_redirect.map(|url| file.join(url)) { + match maybe_redirect.map(|url| file.parent().unwrap().join(url)) { Some(redirect_file) => { - let path = PathBuf::from(redirect_file); - load_file(cache, root, path, FromRedirect(true)) + load_file(cache, root, &redirect_file, FromRedirect(true)) } None => Ok((pretty_file, contents)), } @@ -329,10 +298,14 @@ fn maybe_redirect(source: &str) -> Option { }) } -fn with_attrs_in_source(contents: &str, attr: &str, mut f: F) { +fn with_attrs_in_source(contents: &str, attr: &str, mut f: F) { + let mut base = ""; for (i, mut line) in contents.lines().enumerate() { while let Some(j) = line.find(attr) { let rest = &line[j + attr.len()..]; + // The base tag should always be the first link in the document so + // we can get away with using one pass. + let is_base = line[..j].ends_with("