diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c5dd3cd720548..e7041dcddc42c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,6 +47,12 @@ as it's possible that someone else has already reported your error. This doesn't always work, and sometimes it's hard to know what to search for, so consider this extra credit. We won't mind if you accidentally file a duplicate report. +Similarly, to help others who encountered the bug find your issue, +consider filing an issue with with a descriptive title, which contains information that might be unique to it. +This can be the language or compiler feature used, the conditions that trigger the bug, +or part of the error message if there is any. +An example could be: **"impossible case reached" on lifetime inference for impl Trait in return position**. + Opening an issue is as easy as following [this link](https://github.com/rust-lang/rust/issues/new) and filling out the fields. Here's a template that you can use to file a bug, though it's not necessary to diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index c8ee166fee3e9..1ff187ed3f109 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -256,6 +256,33 @@ impl Cell { pub fn get(&self) -> T { unsafe{ *self.value.get() } } + + /// Updates the contained value using a function and returns the new value. + /// + /// # Examples + /// + /// ``` + /// #![feature(cell_update)] + /// + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// let new = c.update(|x| x + 1); + /// + /// assert_eq!(new, 6); + /// assert_eq!(c.get(), 6); + /// ``` + #[inline] + #[unstable(feature = "cell_update", issue = "50186")] + pub fn update(&self, f: F) -> T + where + F: FnOnce(T) -> T, + { + let old = self.get(); + let new = f(old); + self.set(new); + new + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/char/decode.rs b/src/libcore/char/decode.rs index 48b531104f882..45a73191db2f2 100644 --- a/src/libcore/char/decode.rs +++ b/src/libcore/char/decode.rs @@ -17,11 +17,17 @@ use super::from_u32_unchecked; /// An iterator over an iterator of bytes of the characters the bytes represent /// as UTF-8 #[unstable(feature = "decode_utf8", issue = "33906")] +#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: + https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] #[derive(Clone, Debug)] +#[allow(deprecated)] pub struct DecodeUtf8>(::iter::Peekable); /// Decodes an `Iterator` of bytes as UTF-8. #[unstable(feature = "decode_utf8", issue = "33906")] +#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: + https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] +#[allow(deprecated)] #[inline] pub fn decode_utf8>(i: I) -> DecodeUtf8 { DecodeUtf8(i.into_iter().peekable()) @@ -29,10 +35,14 @@ pub fn decode_utf8>(i: I) -> DecodeUtf8 /// `::next` returns this for an invalid input sequence. #[unstable(feature = "decode_utf8", issue = "33906")] +#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: + https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] #[derive(PartialEq, Eq, Debug)] +#[allow(deprecated)] pub struct InvalidSequence(()); #[unstable(feature = "decode_utf8", issue = "33906")] +#[allow(deprecated)] impl> Iterator for DecodeUtf8 { type Item = Result; #[inline] @@ -127,6 +137,7 @@ impl> Iterator for DecodeUtf8 { } #[unstable(feature = "decode_utf8", issue = "33906")] +#[allow(deprecated)] impl> FusedIterator for DecodeUtf8 {} /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s. diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index 210eceebc5101..4f6c302247dd2 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -51,6 +51,9 @@ pub use unicode::tables::UNICODE_VERSION; #[unstable(feature = "unicode_version", issue = "49726")] pub use unicode::version::UnicodeVersion; #[unstable(feature = "decode_utf8", issue = "33906")] +#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: + https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] +#[allow(deprecated)] pub use self::decode::{decode_utf8, DecodeUtf8, InvalidSequence}; use fmt::{self, Write}; diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs new file mode 100644 index 0000000000000..f4e96e67b2c66 --- /dev/null +++ b/src/libcore/hint.rs @@ -0,0 +1,61 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![stable(feature = "core_hint", since = "1.27.0")] + +//! Hints to compiler that affects how code should be emitted or optimized. + +use intrinsics; + +/// Informs the compiler that this point in the code is not reachable, enabling +/// further optimizations. +/// +/// # Safety +/// +/// Reaching this function is completely *undefined behavior* (UB). In +/// particular, the compiler assumes that all UB must never happen, and +/// therefore will eliminate all branches that reach to a call to +/// `unreachable_unchecked()`. +/// +/// Like all instances of UB, if this assumption turns out to be wrong, i.e. the +/// `unreachable_unchecked()` call is actually reachable among all possible +/// control flow, the compiler will apply the wrong optimization strategy, and +/// may sometimes even corrupt seemingly unrelated code, causing +/// difficult-to-debug problems. +/// +/// Use this function only when you can prove that the code will never call it. +/// +/// The [`unreachable!()`] macro is the safe counterpart of this function, which +/// will panic instead when executed. +/// +/// [`unreachable!()`]: ../macro.unreachable.html +/// +/// # Example +/// +/// ``` +/// fn div_1(a: u32, b: u32) -> u32 { +/// use std::hint::unreachable_unchecked; +/// +/// // `b.saturating_add(1)` is always positive (not zero), +/// // hence `checked_div` will never return None. +/// // Therefore, the else branch is unreachable. +/// a.checked_div(b.saturating_add(1)) +/// .unwrap_or_else(|| unsafe { unreachable_unchecked() }) +/// } +/// +/// assert_eq!(div_1(7, 0), 7); +/// assert_eq!(div_1(9, 1), 4); +/// assert_eq!(div_1(11, std::u32::MAX), 0); +/// ``` +#[inline] +#[stable(feature = "unreachable", since = "1.27.0")] +pub unsafe fn unreachable_unchecked() -> ! { + intrinsics::unreachable() +} diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 83274682250b0..fb0d2d9c88219 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -638,6 +638,9 @@ extern "rust-intrinsic" { /// NB: This is very different from the `unreachable!()` macro: Unlike the /// macro, which panics when it is executed, it is *undefined behavior* to /// reach code marked with this function. + /// + /// The stabilized version of this intrinsic is + /// [`std::hint::unreachable_unchecked`](../../std/hint/fn.unreachable_unchecked.html). pub fn unreachable() -> !; /// Informs the optimizer that a condition is always true. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 7da5d9f76b55a..0e21a3327fddf 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -163,6 +163,7 @@ pub mod intrinsics; pub mod mem; pub mod nonzero; pub mod ptr; +pub mod hint; /* Core language traits */ diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 346d404fa8c59..f9371ed0575e4 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -421,13 +421,13 @@ macro_rules! writeln { /// * Iterators that dynamically terminate. /// /// If the determination that the code is unreachable proves incorrect, the -/// program immediately terminates with a [`panic!`]. The function [`unreachable`], -/// which belongs to the [`std::intrinsics`] module, informs the compilier to +/// program immediately terminates with a [`panic!`]. The function [`unreachable_unchecked`], +/// which belongs to the [`std::hint`] module, informs the compilier to /// optimize the code out of the release version entirely. /// /// [`panic!`]: ../std/macro.panic.html -/// [`unreachable`]: ../std/intrinsics/fn.unreachable.html -/// [`std::intrinsics`]: ../std/intrinsics/index.html +/// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html +/// [`std::hint`]: ../std/hint/index.html /// /// # Panics /// diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index e3f08926610f6..10efab82ddff5 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1094,18 +1094,6 @@ impl ::hash::Hash for ManuallyDrop { } } -/// Tells LLVM that this point in the code is not reachable, enabling further -/// optimizations. -/// -/// NB: This is very different from the `unreachable!()` macro: Unlike the -/// macro, which panics when it is executed, it is *undefined behavior* to -/// reach code marked with this function. -#[inline] -#[unstable(feature = "unreachable", issue = "43751")] -pub unsafe fn unreachable() -> ! { - intrinsics::unreachable() -} - /// A pinned reference. /// /// A pinned reference is a lot like a mutable reference, except that it is not diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index aa4d4bc638b1d..a062fbda5bad0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1765,7 +1765,11 @@ assert_eq!((-a).mod_euc(-b), 1); pub fn mod_euc(self, rhs: Self) -> Self { let r = self % rhs; if r < 0 { - r + rhs.abs() + if rhs < 0 { + r - rhs + } else { + r + rhs + } } else { r } diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index cc0ef6a6f17e0..962fb2f0e027b 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -26,6 +26,17 @@ fn smoketest_cell() { assert!(y.get() == (30, 40)); } +#[test] +fn cell_update() { + let x = Cell::new(10); + + assert_eq!(x.update(|x| x + 5), 15); + assert_eq!(x.get(), 15); + + assert_eq!(x.update(|x| x / 3), 5); + assert_eq!(x.get(), 5); +} + #[test] fn cell_has_sensible_show() { let x = Cell::new("foo bar"); diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs index 4e10ceac878b6..ab90763abf8d5 100644 --- a/src/libcore/tests/char.rs +++ b/src/libcore/tests/char.rs @@ -364,6 +364,7 @@ fn eu_iterator_specializations() { } #[test] +#[allow(deprecated)] fn test_decode_utf8() { macro_rules! assert_decode_utf8 { ($input_bytes: expr, $expected_str: expr) => { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 7d3852d2f2a98..e4d277179382f 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -10,11 +10,13 @@ #![feature(ascii_ctype)] #![feature(box_syntax)] +#![feature(cell_update)] #![feature(core_float)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] #![feature(decode_utf8)] +#![feature(euclidean_division)] #![feature(exact_size_is_empty)] #![feature(fixed_size_array)] #![feature(float_internals)] diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 8d791283ab87e..71d2e7945389b 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -30,6 +30,11 @@ mod tests { num::test_num(10 as $T, 2 as $T); } + #[test] + fn test_mod_euc() { + assert!((-1 as $T).mod_euc(MIN) == MAX); + } + #[test] pub fn test_abs() { assert!((1 as $T).abs() == 1 as $T); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 2cae88855e3ea..ef8bf2244d977 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1375,13 +1375,17 @@ function search(e) { var params = getQueryStringParams(); - var query = getQuery(document.getElementsByClassName('search-input')[0].value.trim()); + var search_input = document.getElementsByClassName('search-input')[0]; + var query = getQuery(search_input.value.trim()); if (e) { e.preventDefault(); } if (!query.query || query.id === currentResults) { + if (query.query.length > 0) { + putBackSearch(search_input); + } return; } @@ -2072,19 +2076,23 @@ }; }); + function putBackSearch(search_input) { + if (search_input.value !== "") { + addClass(document.getElementById("main"), "hidden"); + removeClass(document.getElementById("search"), "hidden"); + if (browserSupportsHistoryApi()) { + history.replaceState(search_input.value, + "", + "?search=" + encodeURIComponent(search_input.value)); + } + } + } + var search_input = document.getElementsByClassName("search-input")[0]; if (search_input) { search_input.onfocus = function() { - if (search_input.value !== "") { - addClass(document.getElementById("main"), "hidden"); - removeClass(document.getElementById("search"), "hidden"); - if (browserSupportsHistoryApi()) { - history.replaceState(search_input.value, - "", - "?search=" + encodeURIComponent(search_input.value)); - } - } + putBackSearch(this); }; } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index d6eac74833483..ee297d3783e52 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -1251,6 +1251,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn read_char_buffered() { let buf = [195, 159]; let reader = BufReader::with_capacity(1, &buf[..]); @@ -1258,6 +1259,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_chars() { let buf = [195, 159, b'a']; let reader = BufReader::with_capacity(1, &buf[..]); diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 2673f3ccfa3ab..8ac52572810c6 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -566,6 +566,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_read_char() { let b = &b"Vi\xE1\xBB\x87t"[..]; let mut c = Cursor::new(b).chars(); @@ -577,6 +578,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_read_bad_char() { let b = &b"\x80"[..]; let mut c = Cursor::new(b).chars(); diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index b02e133ee4dd7..eba4e9fe70368 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -840,6 +840,9 @@ pub trait Read { of where errors happen is currently \ unclear and may change", issue = "27802")] + #[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: + https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] + #[allow(deprecated)] fn chars(self) -> Chars where Self: Sized { Chars { inner: self } } @@ -2010,16 +2013,22 @@ impl Iterator for Bytes { /// [chars]: trait.Read.html#method.chars #[unstable(feature = "io", reason = "awaiting stability of Read::chars", issue = "27802")] +#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: + https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] #[derive(Debug)] +#[allow(deprecated)] pub struct Chars { inner: R, } /// An enumeration of possible errors that can be generated from the `Chars` /// adapter. -#[derive(Debug)] #[unstable(feature = "io", reason = "awaiting stability of Read::chars", issue = "27802")] +#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: + https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] +#[derive(Debug)] +#[allow(deprecated)] pub enum CharsError { /// Variant representing that the underlying stream was read successfully /// but it did not contain valid utf8 data. @@ -2031,6 +2040,7 @@ pub enum CharsError { #[unstable(feature = "io", reason = "awaiting stability of Read::chars", issue = "27802")] +#[allow(deprecated)] impl Iterator for Chars { type Item = result::Result; @@ -2063,6 +2073,7 @@ impl Iterator for Chars { #[unstable(feature = "io", reason = "awaiting stability of Read::chars", issue = "27802")] +#[allow(deprecated)] impl std_error::Error for CharsError { fn description(&self) -> &str { match *self { @@ -2080,6 +2091,7 @@ impl std_error::Error for CharsError { #[unstable(feature = "io", reason = "awaiting stability of Read::chars", issue = "27802")] +#[allow(deprecated)] impl fmt::Display for CharsError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 1df7bc777d17e..4199219313509 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -461,6 +461,8 @@ pub use alloc_crate::vec; pub use core::char; #[stable(feature = "i128", since = "1.26.0")] pub use core::u128; +#[stable(feature = "core_hint", since = "1.27.0")] +pub use core::hint; pub mod f32; pub mod f64; diff --git a/src/libstd/os/android/fs.rs b/src/libstd/os/android/fs.rs index a51b46559859e..5899dc688e225 100644 --- a/src/libstd/os/android/fs.rs +++ b/src/libstd/os/android/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::android::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/bitrig/fs.rs b/src/libstd/os/bitrig/fs.rs index e4f1c9432f3f0..24caf326ab0fd 100644 --- a/src/libstd/os/bitrig/fs.rs +++ b/src/libstd/os/bitrig/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::bitrig::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/dragonfly/fs.rs b/src/libstd/os/dragonfly/fs.rs index db672e5643531..6aea450774ffd 100644 --- a/src/libstd/os/dragonfly/fs.rs +++ b/src/libstd/os/dragonfly/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::dragonfly::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/emscripten/fs.rs b/src/libstd/os/emscripten/fs.rs index 8056ce4fdc4ee..e0e197dc122a1 100644 --- a/src/libstd/os/emscripten/fs.rs +++ b/src/libstd/os/emscripten/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::emscripten::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/freebsd/fs.rs b/src/libstd/os/freebsd/fs.rs index 2f17d2f740943..5f24cd636d541 100644 --- a/src/libstd/os/freebsd/fs.rs +++ b/src/libstd/os/freebsd/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::freebsd::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/fuchsia/fs.rs b/src/libstd/os/fuchsia/fs.rs index d22f9a628bd17..16802576356d1 100644 --- a/src/libstd/os/fuchsia/fs.rs +++ b/src/libstd/os/fuchsia/fs.rs @@ -13,7 +13,9 @@ use fs::Metadata; use sys_common::AsInner; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { #[stable(feature = "metadata_ext2", since = "1.8.0")] diff --git a/src/libstd/os/haiku/fs.rs b/src/libstd/os/haiku/fs.rs index 54f8ea1b71b3e..453136e0ac864 100644 --- a/src/libstd/os/haiku/fs.rs +++ b/src/libstd/os/haiku/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::haiku::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/ios/fs.rs b/src/libstd/os/ios/fs.rs index 275daf3d3a0ac..296ce69ff4362 100644 --- a/src/libstd/os/ios/fs.rs +++ b/src/libstd/os/ios/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::ios::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs index 2be2fbcb2dbf7..76fb10da850b1 100644 --- a/src/libstd/os/linux/fs.rs +++ b/src/libstd/os/linux/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::linux::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/macos/fs.rs b/src/libstd/os/macos/fs.rs index 12b44901d03d9..0b14c05cb5519 100644 --- a/src/libstd/os/macos/fs.rs +++ b/src/libstd/os/macos/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::macos::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/netbsd/fs.rs b/src/libstd/os/netbsd/fs.rs index cd7d5fafd1c85..e9cad33fee61d 100644 --- a/src/libstd/os/netbsd/fs.rs +++ b/src/libstd/os/netbsd/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::netbsd::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/openbsd/fs.rs b/src/libstd/os/openbsd/fs.rs index cc812fcf12cfe..0f6b83b6e324b 100644 --- a/src/libstd/os/openbsd/fs.rs +++ b/src/libstd/os/openbsd/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::openbsd::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/os/solaris/fs.rs b/src/libstd/os/solaris/fs.rs index 5dc43d03a8663..19dce1ba34c76 100644 --- a/src/libstd/os/solaris/fs.rs +++ b/src/libstd/os/solaris/fs.rs @@ -18,7 +18,9 @@ use sys_common::AsInner; #[allow(deprecated)] use os::solaris::raw; -/// OS-specific extension methods for `fs::Metadata` +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 92f0406c09bb5..00051d4487a21 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1121,8 +1121,13 @@ impl ExitCode { } impl Child { - /// Forces the child to exit. This is equivalent to sending a - /// SIGKILL on unix platforms. + /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`] + /// error is returned. + /// + /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function, + /// especially the [`Other`] kind might change to more specific kinds in the future. + /// + /// This is equivalent to sending a SIGKILL on Unix platforms. /// /// # Examples /// @@ -1138,6 +1143,10 @@ impl Child { /// println!("yes command didn't start"); /// } /// ``` + /// + /// [`ErrorKind`]: ../io/enum.ErrorKind.html + /// [`InvalidInput`]: ../io/enum.ErrorKind.html#variant.InvalidInput + /// [`Other`]: ../io/enum.ErrorKind.html#variant.Other #[stable(feature = "process", since = "1.0.0")] pub fn kill(&mut self) -> io::Result<()> { self.handle.kill() diff --git a/src/libstd/sys/redox/ext/ffi.rs b/src/libstd/sys/redox/ext/ffi.rs index d59b4fc0b70b8..cd88c8f46b3c0 100644 --- a/src/libstd/sys/redox/ext/ffi.rs +++ b/src/libstd/sys/redox/ext/ffi.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Unix-specific extension to the primitives in the `std::ffi` module +//! Redox-specific extension to the primitives in the `std::ffi` module. #![stable(feature = "rust1", since = "1.0.0")] @@ -17,7 +17,9 @@ use mem; use sys::os_str::Buf; use sys_common::{FromInner, IntoInner, AsInner}; -/// Unix-specific extensions to `OsString`. +/// Redox-specific extensions to [`OsString`]. +/// +/// [`OsString`]: ../../../../std/ffi/struct.OsString.html #[stable(feature = "rust1", since = "1.0.0")] pub trait OsStringExt { /// Creates an `OsString` from a byte vector. @@ -39,7 +41,9 @@ impl OsStringExt for OsString { } } -/// Unix-specific extensions to `OsStr`. +/// Redox-specific extensions to [`OsStr`]. +/// +/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html #[stable(feature = "rust1", since = "1.0.0")] pub trait OsStrExt { #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs index 0f4762aa8810a..c1dba6edda484 100644 --- a/src/libstd/sys/redox/ext/fs.rs +++ b/src/libstd/sys/redox/ext/fs.rs @@ -18,7 +18,9 @@ use path::Path; use sys; use sys_common::{FromInner, AsInner, AsInnerMut}; -/// Redox-specific extensions to `Permissions` +/// Redox-specific extensions to [`fs::Permissions`]. +/// +/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html #[stable(feature = "fs_ext", since = "1.1.0")] pub trait PermissionsExt { /// Returns the underlying raw `mode_t` bits that are the standard Redox @@ -95,7 +97,9 @@ impl PermissionsExt for Permissions { } } -/// Redox-specific extensions to `OpenOptions` +/// Redox-specific extensions to [`fs::OpenOptions`]. +/// +/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html #[stable(feature = "fs_ext", since = "1.1.0")] pub trait OpenOptionsExt { /// Sets the mode bits that a new file will be created with. @@ -163,13 +167,9 @@ impl OpenOptionsExt for OpenOptions { } } -// Hm, why are there casts here to the returned type, shouldn't the types always -// be the same? Right you are! Turns out, however, on android at least the types -// in the raw `stat` structure are not the same as the types being returned. Who -// knew! -// -// As a result to make sure this compiles for all platforms we do the manual -// casts and rely on manual lowering to `stat` if the raw type is desired. +/// Redox-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { #[stable(feature = "metadata_ext", since = "1.1.0")] @@ -204,6 +204,13 @@ pub trait MetadataExt { fn blocks(&self) -> u64; } +// Hm, why are there casts here to the returned type, shouldn't the types always +// be the same? Right you are! Turns out, however, on android at least the types +// in the raw `stat` structure are not the same as the types being returned. Who +// knew! +// +// As a result to make sure this compiles for all platforms we do the manual +// casts and rely on manual lowering to `stat` if the raw type is desired. #[stable(feature = "metadata_ext", since = "1.1.0")] impl MetadataExt for fs::Metadata { fn dev(&self) -> u64 { @@ -253,7 +260,12 @@ impl MetadataExt for fs::Metadata { } } -/// Add special Redox types (block/char device, fifo and socket) +/// Redox-specific extensions for [`FileType`]. +/// +/// Adds support for special Unix file types such as block/character devices, +/// pipes, and sockets. +/// +/// [`FileType`]: ../../../../std/fs/struct.FileType.html #[stable(feature = "file_type_ext", since = "1.5.0")] pub trait FileTypeExt { /// Returns whether this file type is a block device. @@ -307,8 +319,10 @@ pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> sys::fs::symlink(src.as_ref(), dst.as_ref()) } +/// Redox-specific extensions to [`fs::DirBuilder`]. +/// +/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html #[stable(feature = "dir_builder", since = "1.6.0")] -/// An extension trait for `fs::DirBuilder` for Redox-specific options. pub trait DirBuilderExt { /// Sets the mode to create new directories with. This option defaults to /// 0o777. diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index e68e180acf1c4..cfb6d5fc703a6 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Unix-specific extensions to primitives in the `std::process` module. +//! Redox-specific extensions to primitives in the `std::process` module. #![stable(feature = "rust1", since = "1.0.0")] @@ -18,7 +18,9 @@ use process; use sys; use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; -/// Unix-specific extensions to the `std::process::Command` builder +/// Redox-specific extensions to the [`process::Command`] builder, +/// +/// [`process::Command`]: ../../../../std/process/struct.Command.html #[stable(feature = "rust1", since = "1.0.0")] pub trait CommandExt { /// Sets the child process's user id. This translates to a @@ -107,7 +109,9 @@ impl CommandExt for process::Command { } } -/// Unix-specific extensions to `std::process::ExitStatus` +/// Redox-specific extensions to [`process::ExitStatus`]. +/// +/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html #[stable(feature = "rust1", since = "1.0.0")] pub trait ExitStatusExt { /// Creates a new `ExitStatus` from the raw underlying `i32` return value of diff --git a/src/libstd/sys/redox/ext/thread.rs b/src/libstd/sys/redox/ext/thread.rs index 52be2ccd9f964..71ff0d46b91e3 100644 --- a/src/libstd/sys/redox/ext/thread.rs +++ b/src/libstd/sys/redox/ext/thread.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Unix-specific extensions to primitives in the `std::thread` module. +//! Redox-specific extensions to primitives in the `std::thread` module. #![stable(feature = "thread_extensions", since = "1.9.0")] @@ -19,7 +19,9 @@ use thread::JoinHandle; #[allow(deprecated)] pub type RawPthread = usize; -/// Unix-specific extensions to `std::thread::JoinHandle` +/// Redox-specific extensions to [`thread::JoinHandle`]. +/// +/// [`thread::JoinHandle`]: ../../../../std/thread/struct.JoinHandle.html #[stable(feature = "thread_extensions", since = "1.9.0")] pub trait JoinHandleExt { /// Extracts the raw pthread_t without taking ownership diff --git a/src/libstd/sys/unix/ext/ffi.rs b/src/libstd/sys/unix/ext/ffi.rs index fb9984ccbdda5..8347145db5aaf 100644 --- a/src/libstd/sys/unix/ext/ffi.rs +++ b/src/libstd/sys/unix/ext/ffi.rs @@ -17,7 +17,9 @@ use mem; use sys::os_str::Buf; use sys_common::{FromInner, IntoInner, AsInner}; -/// Unix-specific extensions to `OsString`. +/// Unix-specific extensions to [`OsString`]. +/// +/// [`OsString`]: ../../../../std/ffi/struct.OsString.html #[stable(feature = "rust1", since = "1.0.0")] pub trait OsStringExt { /// Creates an [`OsString`] from a byte vector. @@ -66,7 +68,9 @@ impl OsStringExt for OsString { } } -/// Unix-specific extensions to `OsStr`. +/// Unix-specific extensions to [`OsStr`]. +/// +/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html #[stable(feature = "rust1", since = "1.0.0")] pub trait OsStrExt { #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 3c5b9424fb06e..4e98101266903 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -105,7 +105,9 @@ impl FileExt for fs::File { } } -/// Unix-specific extensions to `Permissions` +/// Unix-specific extensions to [`fs::Permissions`]. +/// +/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html #[stable(feature = "fs_ext", since = "1.1.0")] pub trait PermissionsExt { /// Returns the underlying raw `st_mode` bits that contain the standard @@ -180,7 +182,9 @@ impl PermissionsExt for Permissions { } } -/// Unix-specific extensions to `OpenOptions` +/// Unix-specific extensions to [`fs::OpenOptions`]. +/// +/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html #[stable(feature = "fs_ext", since = "1.1.0")] pub trait OpenOptionsExt { /// Sets the mode bits that a new file will be created with. @@ -246,13 +250,9 @@ impl OpenOptionsExt for OpenOptions { } } -// Hm, why are there casts here to the returned type, shouldn't the types always -// be the same? Right you are! Turns out, however, on android at least the types -// in the raw `stat` structure are not the same as the types being returned. Who -// knew! -// -// As a result to make sure this compiles for all platforms we do the manual -// casts and rely on manual lowering to `stat` if the raw type is desired. +/// Unix-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Returns the ID of the device containing the file. @@ -555,7 +555,12 @@ impl MetadataExt for fs::Metadata { fn blocks(&self) -> u64 { self.st_blocks() } } -/// Add support for special unix types (block/char device, fifo and socket). +/// Unix-specific extensions for [`FileType`]. +/// +/// Adds support for special Unix file types such as block/character devices, +/// pipes, and sockets. +/// +/// [`FileType`]: ../../../../std/fs/struct.FileType.html #[stable(feature = "file_type_ext", since = "1.5.0")] pub trait FileTypeExt { /// Returns whether this file type is a block device. @@ -701,10 +706,10 @@ pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> sys::fs::symlink(src.as_ref(), dst.as_ref()) } -#[stable(feature = "dir_builder", since = "1.6.0")] -/// An extension trait for [`fs::DirBuilder`] for unix-specific options. +/// Unix-specific extensions to [`fs::DirBuilder`]. /// /// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html +#[stable(feature = "dir_builder", since = "1.6.0")] pub trait DirBuilderExt { /// Sets the mode to create new directories with. This option defaults to /// 0o777. diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 7b4ec20d91fb4..21630ae9746fc 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -18,7 +18,9 @@ use process; use sys; use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; -/// Unix-specific extensions to the `std::process::Command` builder +/// Unix-specific extensions to the [`process::Command`] builder. +/// +/// [`process::Command`]: ../../../../std/process/struct.Command.html #[stable(feature = "rust1", since = "1.0.0")] pub trait CommandExt { /// Sets the child process's user id. This translates to a @@ -117,7 +119,9 @@ impl CommandExt for process::Command { } } -/// Unix-specific extensions to `std::process::ExitStatus` +/// Unix-specific extensions to [`process::ExitStatus`]. +/// +/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html #[stable(feature = "rust1", since = "1.0.0")] pub trait ExitStatusExt { /// Creates a new `ExitStatus` from the raw underlying `i32` return value of diff --git a/src/libstd/sys/unix/ext/thread.rs b/src/libstd/sys/unix/ext/thread.rs index fe2a48764dc3a..8dadf29945c1a 100644 --- a/src/libstd/sys/unix/ext/thread.rs +++ b/src/libstd/sys/unix/ext/thread.rs @@ -21,7 +21,9 @@ use thread::JoinHandle; #[allow(deprecated)] pub type RawPthread = pthread_t; -/// Unix-specific extensions to `std::thread::JoinHandle` +/// Unix-specific extensions to [`thread::JoinHandle`]. +/// +/// [`thread::JoinHandle`]: ../../../../std/thread/struct.JoinHandle.html #[stable(feature = "thread_extensions", since = "1.9.0")] pub trait JoinHandleExt { /// Extracts the raw pthread_t without taking ownership diff --git a/src/libstd/sys/windows/ext/ffi.rs b/src/libstd/sys/windows/ext/ffi.rs index d6b8896ac096d..98d4355248990 100644 --- a/src/libstd/sys/windows/ext/ffi.rs +++ b/src/libstd/sys/windows/ext/ffi.rs @@ -76,7 +76,9 @@ use sys_common::{FromInner, AsInner}; #[stable(feature = "rust1", since = "1.0.0")] pub use sys_common::wtf8::EncodeWide; -/// Windows-specific extensions to `OsString`. +/// Windows-specific extensions to [`OsString`]. +/// +/// [`OsString`]: ../../../../std/ffi/struct.OsString.html #[stable(feature = "rust1", since = "1.0.0")] pub trait OsStringExt { /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of @@ -109,7 +111,9 @@ impl OsStringExt for OsString { } } -/// Windows-specific extensions to `OsStr`. +/// Windows-specific extensions to [`OsStr`]. +/// +/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html #[stable(feature = "rust1", since = "1.0.0")] pub trait OsStrExt { /// Re-encodes an `OsStr` as a wide character sequence, i.e. potentially diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index e5cd51b6550b1..78c9e95a05501 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -103,9 +103,9 @@ impl FileExt for fs::File { } } -/// Windows-specific extensions to [`OpenOptions`]. +/// Windows-specific extensions to [`fs::OpenOptions`]. /// -/// [`OpenOptions`]: ../../../fs/struct.OpenOptions.html +/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html #[stable(feature = "open_options_ext", since = "1.10.0")] pub trait OpenOptionsExt { /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`] @@ -281,13 +281,12 @@ impl OpenOptionsExt for OpenOptions { } } -/// Extension methods for [`fs::Metadata`] to access the raw fields contained -/// within. +/// Windows-specific extensions to [`fs::Metadata`]. /// /// The data members that this trait exposes correspond to the members /// of the [`BY_HANDLE_FILE_INFORMATION`] structure. /// -/// [`fs::Metadata`]: ../../../fs/struct.Metadata.html +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html /// [`BY_HANDLE_FILE_INFORMATION`]: /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] @@ -445,8 +444,11 @@ impl MetadataExt for Metadata { fn file_size(&self) -> u64 { self.as_inner().size() } } -/// Add support for the Windows specific fact that a symbolic link knows whether it is a file -/// or directory. +/// Windows-specific extensions to [`FileType`]. +/// +/// On Windows, a symbolic link knows whether it is a file or directory. +/// +/// [`FileType`]: ../../../../std/fs/struct.FileType.html #[unstable(feature = "windows_file_type_ext", issue = "0")] pub trait FileTypeExt { /// Returns whether this file type is a symbolic link that is also a directory. diff --git a/src/libstd/sys/windows/ext/process.rs b/src/libstd/sys/windows/ext/process.rs index 759f055c4b123..a02bcbe0c87c2 100644 --- a/src/libstd/sys/windows/ext/process.rs +++ b/src/libstd/sys/windows/ext/process.rs @@ -82,7 +82,9 @@ impl IntoRawHandle for process::ChildStderr { } } -/// Windows-specific extensions to `std::process::ExitStatus` +/// Windows-specific extensions to [`process::ExitStatus`]. +/// +/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html #[stable(feature = "exit_status_from", since = "1.12.0")] pub trait ExitStatusExt { /// Creates a new `ExitStatus` from the raw underlying `u32` return value of @@ -98,7 +100,9 @@ impl ExitStatusExt for process::ExitStatus { } } -/// Windows-specific extensions to the `std::process::Command` builder +/// Windows-specific extensions to the [`process::Command`] builder. +/// +/// [`process::Command`]: ../../../../std/process/struct.Command.html #[stable(feature = "windows_process_extensions", since = "1.16.0")] pub trait CommandExt { /// Sets the [process creation flags][1] to be passed to `CreateProcess`. diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index d20e94b018b3f..120dff2dbb926 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1242,10 +1242,9 @@ fn leveled_feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue GateIssue::Library(lib) => lib, }; - let explanation = if let Some(n) = issue { - format!("{} (see issue #{})", explain, n) - } else { - explain.to_owned() + let explanation = match issue { + None | Some(0) => explain.to_owned(), + Some(n) => format!("{} (see issue #{})", explain, n) }; let mut err = match level { diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 50fac600a978d..b449c5eea6658 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -15,8 +15,8 @@ use hygiene::SyntaxContext; use {Span, DUMMY_SP, GLOBALS}; +use rustc_data_structures::fx::FxHashMap; use serialize::{Decodable, Decoder, Encodable, Encoder}; -use std::collections::HashMap; use std::fmt; use std::hash::{Hash, Hasher}; @@ -184,7 +184,7 @@ impl> PartialEq for Symbol { #[derive(Default)] pub struct Interner { - names: HashMap, Symbol>, + names: FxHashMap, Symbol>, strings: Vec>, gensyms: Vec, } diff --git a/src/test/ui/feature-gate/issue-49983-see-issue-0.rs b/src/test/ui/feature-gate/issue-49983-see-issue-0.rs new file mode 100644 index 0000000000000..1e0039aba04bb --- /dev/null +++ b/src/test/ui/feature-gate/issue-49983-see-issue-0.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate core; + +// error should not say "(see issue #0)" +#[allow(unused_imports)] use core::ptr::Unique; //~ ERROR use of unstable library feature + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-49983-see-issue-0.stderr b/src/test/ui/feature-gate/issue-49983-see-issue-0.stderr new file mode 100644 index 0000000000000..986a2d88e00a2 --- /dev/null +++ b/src/test/ui/feature-gate/issue-49983-see-issue-0.stderr @@ -0,0 +1,11 @@ +error[E0658]: use of unstable library feature 'ptr_internals': use NonNull instead and consider PhantomData (if you also use #[may_dangle]), Send, and/or Sync + --> $DIR/issue-49983-see-issue-0.rs:14:30 + | +LL | #[allow(unused_imports)] use core::ptr::Unique; //~ ERROR use of unstable library feature + | ^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(ptr_internals)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/update-references.sh b/src/test/ui/update-references.sh index cfe9a43707cf6..4fc11daaa3afa 100755 --- a/src/test/ui/update-references.sh +++ b/src/test/ui/update-references.sh @@ -31,24 +31,17 @@ MYDIR=$(dirname $0) BUILD_DIR="$1" shift +shopt -s nullglob + while [[ "$1" != "" ]]; do - STDERR_NAME="${1/%.rs/.stderr}" - STDERR_NLL_NAME="${1/%.rs/.nll.stderr}" - STDOUT_NAME="${1/%.rs/.stdout}" + for EXT in "stderr" "stdout"; do + for OUT_NAME in $BUILD_DIR/${1%.rs}.*$EXT; do + OUT_BASE=`basename "$OUT_NAME"` + if ! (diff $OUT_NAME $MYDIR/$OUT_BASE >& /dev/null); then + echo updating $MYDIR/$OUT_BASE + cp $OUT_NAME $MYDIR + fi + done + done shift - if [ -f $BUILD_DIR/$STDOUT_NAME ] && \ - ! (diff $BUILD_DIR/$STDOUT_NAME $MYDIR/$STDOUT_NAME >& /dev/null); then - echo updating $MYDIR/$STDOUT_NAME - cp $BUILD_DIR/$STDOUT_NAME $MYDIR/$STDOUT_NAME - fi - if [ -f $BUILD_DIR/$STDERR_NAME ] && \ - ! (diff $BUILD_DIR/$STDERR_NAME $MYDIR/$STDERR_NAME >& /dev/null); then - echo updating $MYDIR/$STDERR_NAME - cp $BUILD_DIR/$STDERR_NAME $MYDIR/$STDERR_NAME - fi - if [ -f $BUILD_DIR/$STDERR_NLL_NAME ] && \ - ! (diff $BUILD_DIR/$STDERR_NLL_NAME $MYDIR/$STDERR_NLL_NAME >& /dev/null); then - echo updating $MYDIR/$STDERR_NLL_NAME - cp $BUILD_DIR/$STDERR_NLL_NAME $MYDIR/$STDERR_NLL_NAME - fi done diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 0f4d247633a61..aabf2e6f8f0e6 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -26,7 +26,7 @@ use std::collections::VecDeque; use std::collections::HashMap; use std::collections::HashSet; use std::env; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fs::{self, create_dir_all, File}; use std::fmt; use std::io::prelude::*; @@ -72,6 +72,26 @@ impl Mismatch { } } +trait PathBufExt { + /// Append an extension to the path, even if it already has one. + fn with_extra_extension>(&self, extension: S) -> PathBuf; +} + +impl PathBufExt for PathBuf { + fn with_extra_extension>(&self, extension: S) -> PathBuf { + if extension.as_ref().len() == 0 { + self.clone() + } else { + let mut fname = self.file_name().unwrap().to_os_string(); + if !extension.as_ref().to_str().unwrap().starts_with(".") { + fname.push("."); + } + fname.push(extension); + self.with_file_name(fname) + } + } +} + // Produces a diff between the expected output and actual output. pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec { let mut line_number = 1; @@ -1725,20 +1745,14 @@ impl<'test> TestCx<'test> { } fn make_exe_name(&self) -> PathBuf { - let mut f = self.output_base_name(); + let mut f = self.output_base_name_stage(); // FIXME: This is using the host architecture exe suffix, not target! if self.config.target.contains("emscripten") { - let mut fname = f.file_name().unwrap().to_os_string(); - fname.push(".js"); - f.set_file_name(&fname); + f = f.with_extra_extension("js"); } else if self.config.target.contains("wasm32") { - let mut fname = f.file_name().unwrap().to_os_string(); - fname.push(".wasm"); - f.set_file_name(&fname); + f = f.with_extra_extension("wasm"); } else if !env::consts::EXE_SUFFIX.is_empty() { - let mut fname = f.file_name().unwrap().to_os_string(); - fname.push(env::consts::EXE_SUFFIX); - f.set_file_name(&fname); + f = f.with_extra_extension(env::consts::EXE_SUFFIX); } f } @@ -1846,25 +1860,28 @@ impl<'test> TestCx<'test> { } fn aux_output_dir_name(&self) -> PathBuf { - let f = self.output_base_name(); - let mut fname = f.file_name().unwrap().to_os_string(); - fname.push(&format!("{}.aux", self.config.mode.disambiguator())); - f.with_file_name(&fname) + self.output_base_name_stage() + .with_extra_extension(self.config.mode.disambiguator()) + .with_extra_extension(".aux") } fn output_testname(&self, filepath: &Path) -> PathBuf { PathBuf::from(filepath.file_stem().unwrap()) } - /// Given a test path like `compile-fail/foo/bar.rs` Returns a name like - /// - /// /foo/bar-stage1 + /// Given a test path like `compile-fail/foo/bar.rs` returns a name like + /// `/path/to/build//test/compile-fail/foo/bar`. fn output_base_name(&self) -> PathBuf { let dir = self.config.build_base.join(&self.testpaths.relative_dir); // Note: The directory `dir` is created during `collect_tests_from_dir` dir.join(&self.output_testname(&self.testpaths.file)) - .with_extension(&self.config.stage_id) + } + + /// Same as `output_base_name`, but includes the stage ID as an extension, + /// such as: `.../compile-fail/foo/bar.stage1-` + fn output_base_name_stage(&self) -> PathBuf { + self.output_base_name().with_extension(&self.config.stage_id) } fn maybe_dump_to_stdout(&self, out: &str, err: &str) { @@ -1989,7 +2006,7 @@ impl<'test> TestCx<'test> { fn run_rustdoc_test(&self) { assert!(self.revision.is_none(), "revisions not relevant here"); - let out_dir = self.output_base_name(); + let out_dir = self.output_base_name_stage(); let _ = fs::remove_dir_all(&out_dir); create_dir_all(&out_dir).unwrap(); @@ -2391,7 +2408,7 @@ impl<'test> TestCx<'test> { .unwrap(); let src_root = cwd.join(&src_root); - let tmpdir = cwd.join(self.output_base_name()); + let tmpdir = cwd.join(self.output_base_name_stage()); if tmpdir.exists() { self.aggressive_rm_rf(&tmpdir).unwrap(); } @@ -2816,7 +2833,6 @@ impl<'test> TestCx<'test> { self.revision, &self.config.compare_mode, kind); - if !path.exists() && self.config.compare_mode.is_some() { // fallback! path = expected_output_path(&self.testpaths, self.revision, &None, kind); @@ -2880,10 +2896,12 @@ impl<'test> TestCx<'test> { } } - let expected_output = self.expected_output_path(kind); - // #50113: output is abspath; only want filename component. - let expected_output = expected_output.file_name().expect("output path requires file name"); - let output_file = self.output_base_name().with_file_name(&expected_output); + let mode = self.config.compare_mode.as_ref().map_or("", |m| m.to_str()); + let output_file = self.output_base_name() + .with_extra_extension(self.revision.unwrap_or("")) + .with_extra_extension(mode) + .with_extra_extension(kind); + match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) { Ok(()) => {} Err(e) => self.fatal(&format!( diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index bda58bc09f776..351005ff4b816 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -12,38 +12,26 @@ use std::path::Path; -// See rust-lang/rust#48879: In addition to the mapping from `foo.rs` -// to `foo.stderr`/`foo.stdout`, we also can optionally have -// `foo.$mode.stderr`, where $mode is one of the strings on this list, -// as an alternative to use when running under that mode. -static COMPARE_MODE_NAMES: [&'static str; 1] = ["nll"]; - pub fn check(path: &Path, bad: &mut bool) { super::walk_many(&[&path.join("test/ui"), &path.join("test/ui-fulldeps")], &mut |_| false, &mut |file_path| { if let Some(ext) = file_path.extension() { - if (ext == "stderr" || ext == "stdout") && !file_path.with_extension("rs").exists() { - - // rust-lang/rust#48879: this fn used to be beautful - // because Path API special-cases replacing - // extensions. That works great for ".stderr" but not - // so well for ".nll.stderr". To support the latter, - // we explicitly search backwards for mode's starting - // point and build corresponding source name. - let filename = file_path.file_name().expect("need filename") - .to_str().expect("need UTF-8 filename"); - let found_matching_prefix = COMPARE_MODE_NAMES.iter().any(|mode| { - if let Some(r_idx) = filename.rfind(&format!(".{}", mode)) { - let source_name = format!("{}.rs", &filename[0..r_idx]); - let source_path = file_path.with_file_name(source_name); - source_path.exists() - } else { - false - } - }); - - if !found_matching_prefix { + if ext == "stderr" || ext == "stdout" { + // Test output filenames have the format: + // $testname.stderr + // $testname.$mode.stderr + // $testname.$revision.stderr + // $testname.$revision.$mode.stderr + // + // For now, just make sure that there is a corresponding + // $testname.rs file. + let testname = file_path.file_name().unwrap() + .to_str().unwrap() + .splitn(2, '.').next().unwrap(); + if !file_path.with_file_name(testname) + .with_extension("rs") + .exists() { println!("Stray file with UI testing output: {:?}", file_path); *bad = true; }