]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #50185 - dmizuk:mod_euc-fix-overflow, r=kennytm
authorkennytm <kennytm@gmail.com>
Tue, 24 Apr 2018 03:57:11 +0000 (11:57 +0800)
committerGitHub <noreply@github.com>
Tue, 24 Apr 2018 03:57:11 +0000 (11:57 +0800)
core: Fix overflow in `int::mod_euc` when `self < 0 && rhs == MIN`

This commit removes usage of `abs`, which overflows when `self == MIN`.

67 files changed:
CONTRIBUTING.md
src/libcore/cell.rs
src/libcore/char/decode.rs
src/libcore/char/mod.rs
src/libcore/hint.rs [new file with mode: 0644]
src/libcore/intrinsics.rs
src/libcore/lib.rs
src/libcore/macros.rs
src/libcore/mem.rs
src/libcore/tests/cell.rs
src/libcore/tests/char.rs
src/libcore/tests/lib.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_mir/interpret/mod.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_passes/ast_validation.rs
src/librustc_trans/mir/operand.rs
src/librustdoc/html/static/main.js
src/libstd/io/buffered.rs
src/libstd/io/cursor.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/os/android/fs.rs
src/libstd/os/bitrig/fs.rs
src/libstd/os/dragonfly/fs.rs
src/libstd/os/emscripten/fs.rs
src/libstd/os/freebsd/fs.rs
src/libstd/os/fuchsia/fs.rs
src/libstd/os/haiku/fs.rs
src/libstd/os/ios/fs.rs
src/libstd/os/linux/fs.rs
src/libstd/os/macos/fs.rs
src/libstd/os/netbsd/fs.rs
src/libstd/os/openbsd/fs.rs
src/libstd/os/solaris/fs.rs
src/libstd/path.rs
src/libstd/process.rs
src/libstd/sys/redox/ext/ffi.rs
src/libstd/sys/redox/ext/fs.rs
src/libstd/sys/redox/ext/process.rs
src/libstd/sys/redox/ext/thread.rs
src/libstd/sys/unix/ext/ffi.rs
src/libstd/sys/unix/ext/fs.rs
src/libstd/sys/unix/ext/process.rs
src/libstd/sys/unix/ext/thread.rs
src/libstd/sys/windows/ext/ffi.rs
src/libstd/sys/windows/ext/fs.rs
src/libstd/sys/windows/ext/process.rs
src/libsyntax/feature_gate.rs
src/libsyntax_pos/symbol.rs
src/test/compile-fail/issue-44578.rs [deleted file]
src/test/ui/const-eval/conditional_array_execution.rs
src/test/ui/const-eval/conditional_array_execution.stderr
src/test/ui/const-eval/issue-43197.rs
src/test/ui/const-eval/issue-43197.stderr
src/test/ui/const-eval/issue-44578.rs [new file with mode: 0644]
src/test/ui/const-eval/issue-44578.stderr [new file with mode: 0644]
src/test/ui/const-eval/promoted_errors.rs [new file with mode: 0644]
src/test/ui/const-eval/promoted_errors.stderr [new file with mode: 0644]
src/test/ui/feature-gate-generic_associated_types.rs
src/test/ui/feature-gate-generic_associated_types.stderr
src/test/ui/feature-gate/issue-49983-see-issue-0.rs [new file with mode: 0644]
src/test/ui/feature-gate/issue-49983-see-issue-0.stderr [new file with mode: 0644]
src/test/ui/update-references.sh
src/tools/compiletest/src/runtest.rs
src/tools/tidy/src/ui_tests.rs

index c5dd3cd720548c8ea1ca9a3b7b3035ac099d7df8..e7041dcddc42c1e222b3b5a8b8e7d23f188ae2c0 100644 (file)
@@ -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
index c8ee166fee3e9240383a7ff37c77a0c2e15be536..1ff187ed3f109722f397f705ce728e886494c87e 100644 (file)
@@ -256,6 +256,33 @@ impl<T:Copy> Cell<T> {
     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<F>(&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")]
index 48b531104f8829f4986ccc56985a486e31d789fc..45a73191db2f2cfc0004644c2fdd2954c716d31f 100644 (file)
 /// 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<I: Iterator<Item = u8>>(::iter::Peekable<I>);
 
 /// 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: IntoIterator<Item = u8>>(i: I) -> DecodeUtf8<I::IntoIter> {
     DecodeUtf8(i.into_iter().peekable())
@@ -29,10 +35,14 @@ pub fn decode_utf8<I: IntoIterator<Item = u8>>(i: I) -> DecodeUtf8<I::IntoIter>
 
 /// `<DecodeUtf8 as Iterator>::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<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
     type Item = Result<char, InvalidSequence>;
     #[inline]
@@ -127,6 +137,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 }
 
 #[unstable(feature = "decode_utf8", issue = "33906")]
+#[allow(deprecated)]
 impl<I: FusedIterator<Item = u8>> FusedIterator for DecodeUtf8<I> {}
 
 /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
index 210eceebc51010c74879667d4018a47fc7486d18..4f6c302247dd2034864f3cbaf9c53bf4fa2e5b3f 100644 (file)
@@ -51,6 +51,9 @@
 #[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 (file)
index 0000000..f4e96e6
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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()
+}
index 83274682250b0911f2e41b61c43894dbe4bed4fd..fb0d2d9c882196da3d7189d234ad7a9a992e5c93 100644 (file)
     /// 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.
index 7da5d9f76b55a0acc930ba2757b299665fcbb847..0e21a3327fddf471f6a486fb9e1f222f5e545981 100644 (file)
 pub mod mem;
 pub mod nonzero;
 pub mod ptr;
+pub mod hint;
 
 /* Core language traits */
 
index 346d404fa8c5924d5e6dd8186792ab40bdc275d5..f9371ed0575e49782f7471320d83c5b852d663a1 100644 (file)
@@ -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
 ///
index e3f08926610f69592ecb583a7165b05d5fc0ddad..10efab82ddff586d6c44671388968ecf8e8a318f 100644 (file)
@@ -1094,18 +1094,6 @@ fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
     }
 }
 
-/// 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
index cc0ef6a6f17e04b5e7358040d0ef689cb73ea871..962fb2f0e027b3924507205b43145beccef82485 100644 (file)
@@ -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");
index 4e10ceac878b6a4c5669d49a2b7fd9838efb4ca8..ab90763abf8d5ef8ad335e7cf97058b23c406920 100644 (file)
@@ -364,6 +364,7 @@ fn check(c: char) {
 }
 
 #[test]
+#[allow(deprecated)]
 fn test_decode_utf8() {
     macro_rules! assert_decode_utf8 {
         ($input_bytes: expr, $expected_str: expr) => {
index ccf647c358d67dabfaf551504d52f8189cd6e057..e4d277179382f3e522259bbc67abebafaab8b3d4 100644 (file)
@@ -10,6 +10,7 @@
 
 #![feature(ascii_ctype)]
 #![feature(box_syntax)]
+#![feature(cell_update)]
 #![feature(core_float)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
index 954a3dbe5b9ab0e78224cb1a508925810b4606a5..6fa68eb6ff1f098195d51a9f13e97e519aa30c68 100644 (file)
@@ -56,7 +56,7 @@ pub fn mk_eval_cx<'a, 'tcx>(
     Ok(ecx)
 }
 
-pub fn eval_body_with_mir<'a, 'mir, 'tcx>(
+pub fn eval_promoted<'a, 'mir, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     cid: GlobalId<'tcx>,
     mir: &'mir mir::Mir<'tcx>,
@@ -66,7 +66,7 @@ pub fn eval_body_with_mir<'a, 'mir, 'tcx>(
     match res {
         Ok(val) => Some(val),
         Err(mut err) => {
-            ecx.report(&mut err, true, None);
+            ecx.report(&mut err, false, None);
             None
         }
     }
index 147db3bdc0e7a41f082f167434d61c5ce3a36f1f..e0e05d6ae60ae868c18a78915173ff41974a654d 100644 (file)
@@ -19,7 +19,7 @@
 pub use self::memory::{Memory, MemoryKind, HasMemory};
 
 pub use self::const_eval::{
-    eval_body_with_mir,
+    eval_promoted,
     mk_borrowck_eval_cx,
     eval_body,
     CompileTimeEvaluator,
index 008165f33b2bbc69f23fffa1c9a7aac0ae907c5b..610e70b39ccf994e035da02f327858e325e33d3a 100644 (file)
@@ -1177,7 +1177,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         param_substs: instance.substs,
     }.visit_mir(&mir);
     let param_env = ty::ParamEnv::reveal_all();
-    for (i, promoted) in mir.promoted.iter().enumerate() {
+    for i in 0..mir.promoted.len() {
         use rustc_data_structures::indexed_vec::Idx;
         let cid = GlobalId {
             instance,
@@ -1185,9 +1185,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         };
         match tcx.const_eval(param_env.and(cid)) {
             Ok(val) => collect_const(tcx, val, instance.substs, output),
-            Err(err) => {
-                err.report(tcx, promoted.span, "promoted");
-            }
+            Err(_) => {},
         }
     }
 }
index f133d6e9c6dee847be829b68e1246284cc62091c..a3d96f0c0739d6b0c45191d1ba604e7b2dda155e 100644 (file)
@@ -20,7 +20,7 @@
 use rustc::middle::const_val::ConstVal;
 use rustc::ty::{TyCtxt, self, Instance};
 use rustc::mir::interpret::{Value, PrimVal, GlobalId};
-use interpret::{eval_body_with_mir, mk_borrowck_eval_cx, ValTy};
+use interpret::{eval_promoted, mk_borrowck_eval_cx, ValTy};
 use transform::{MirPass, MirSource};
 use syntax::codemap::Span;
 use rustc::ty::subst::Substs;
@@ -161,7 +161,7 @@ fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option<Const<'tcx>> {
                 };
                 // cannot use `const_eval` here, because that would require having the MIR
                 // for the current function available, but we're producing said MIR right now
-                let (value, _, ty) = eval_body_with_mir(self.tcx, cid, self.mir, self.param_env)?;
+                let (value, _, ty) = eval_promoted(self.tcx, cid, self.mir, self.param_env)?;
                 let val = (value, ty, c.span);
                 trace!("evaluated {:?} to {:?}", c, val);
                 Some(val)
index 1866122454c7057cab50c8511a3a1d2775512a0a..6708640379a54d2157a5f5adaba426a4d35c1d76 100644 (file)
@@ -273,7 +273,9 @@ fn visit_item(&mut self, item: &'a Item) {
                     self.err_handler().span_err(item.span, "inherent impls cannot be negative");
                 }
                 if defaultness == Defaultness::Default {
-                    self.err_handler().span_err(item.span, "inherent impls cannot be default");
+                    self.err_handler()
+                        .struct_span_err(item.span, "inherent impls cannot be default")
+                        .note("only trait implementations may be annotated with default").emit();
                 }
             }
             ItemKind::ForeignMod(..) => {
index 75df349de41ee9d7075a90c36f407bd3e9157854..656ab95a28cf3e1730c78092260dc9ec40e9fb90 100644 (file)
@@ -399,7 +399,14 @@ pub fn trans_operand(&mut self,
                 self.mir_constant_to_miri_value(bx, constant)
                     .and_then(|c| OperandRef::from_const(bx, c, ty))
                     .unwrap_or_else(|err| {
-                        err.report(bx.tcx(), constant.span, "const operand");
+                        match constant.literal {
+                            mir::Literal::Promoted { .. } => {
+                                // don't report errors inside promoteds, just warnings.
+                            },
+                            mir::Literal::Value { .. } => {
+                                err.report(bx.tcx(), constant.span, "const operand")
+                            },
+                        }
                         // We've errored, so we don't have to produce working code.
                         let layout = bx.cx.layout_of(ty);
                         PlaceRef::new_sized(
index 2cae88855e3ea431daaa3576fb333200a9a8e02b..ef8bf2244d97763186352b7593fb50a3da93dd4a 100644 (file)
 
         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;
             }
 
         };
     });
 
+    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);
         };
     }
 
index d6eac748334834ccae5136eb19cdc846b36995f9..ee297d3783e522caf24a8ca4b8f79d313770895d 100644 (file)
@@ -1251,6 +1251,7 @@ fn test_short_reads() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn read_char_buffered() {
         let buf = [195, 159];
         let reader = BufReader::with_capacity(1, &buf[..]);
@@ -1258,6 +1259,7 @@ fn read_char_buffered() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_chars() {
         let buf = [195, 159, b'a'];
         let reader = BufReader::with_capacity(1, &buf[..]);
index 2673f3ccfa3abd9cff77660e554a8938b5330a0d..8ac52572810c6c99e2ce8ccddaa0d1be66174a55 100644 (file)
@@ -566,6 +566,7 @@ fn test_buf_reader() {
     }
 
     #[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 @@ fn test_read_char() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_read_bad_char() {
         let b = &b"\x80"[..];
         let mut c = Cursor::new(b).chars();
index b02e133ee4dd72176d847361268cc3fd08005cdc..eba4e9fe70368f6de4e853316ede9a6110e43ab1 100644 (file)
@@ -840,6 +840,9 @@ fn bytes(self) -> Bytes<Self> where Self: Sized {
                                          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<Self> where Self: Sized {
         Chars { inner: self }
     }
@@ -2010,16 +2013,22 @@ fn next(&mut self) -> Option<Result<u8>> {
 /// [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<R> {
     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<R: Read> Iterator for Chars<R> {
     type Item = result::Result<char, CharsError>;
 
@@ -2063,6 +2073,7 @@ fn next(&mut self) -> Option<result::Result<char, CharsError>> {
 
 #[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 @@ fn cause(&self) -> Option<&std_error::Error> {
 
 #[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 {
index 1df7bc777d17e56b2a786bb26845134a3e1adf8e..419921931350906e5c9223ace3e19de4d80a63c0 100644 (file)
 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;
index a51b46559859e67a2d514ca42c2b7a8d77a3a80a..5899dc688e22563bc69dd709f0224dc696b7c9bd 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index e4f1c9432f3f08f4cc60859c5b6a968330f5f021..24caf326ab0fd2dba4b6cf69242d2f675667c296 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index db672e5643531181fb59b0759274cc81d74c7e50..6aea450774ffd39d9bb48a3dc04b1386604f09fb 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index 8056ce4fdc4ee4ba02365682be02ff5f5000acce..e0e197dc122a1d2aaa9f36e02b67d7a0ad30d64f 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index 2f17d2f7409434c568887478bbafaefc2ec702c5..5f24cd636d541ab75611244212d9f86a1ba712f3 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index d22f9a628bd1733e7c929546f5f772d66e29cd10..16802576356d192b24d762642d10c6d1c735da52 100644 (file)
@@ -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")]
index 54f8ea1b71b3effa9556cb0cc6672b95579831d0..453136e0ac864afe4cf42f0a875d20ec2e90fb65 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index 275daf3d3a0ac5f842c4e6d3db52f07447e01d62..296ce69ff43620e7f0aa70b01879f01ba1362cf3 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index 2be2fbcb2dbf75900627347081d556cb9754f538..76fb10da850b16b4044cd86fdfc4284d970dea53 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index 12b44901d03d93b6bb468e205c944b310cb09d6c..0b14c05cb5519bffbaf6481ece1af64d52ae18df 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index cd7d5fafd1c85d82afcc92a79bd13bf37d8eedcf..e9cad33fee61d7fceea55e767dff2e1f6081b832 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index cc812fcf12cfe5f9061694ff787a871cf584810c..0f6b83b6e324b56cf8e2f68d907fd4093ac279a9 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index 5dc43d03a866347e82c556fd45723ed80ab5460c..19dce1ba34c76c98482094cec0ea0ccc117bbf22 100644 (file)
@@ -18,7 +18,9 @@
 #[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
index ec96157547383daa4cbad54658beb78a602fd7bd..955a6af1ae67eaac5a78975499cf329658003667 100644 (file)
@@ -298,10 +298,9 @@ pub fn is_separator(c: char) -> bool {
 // Iterate through `iter` while it matches `prefix`; return `None` if `prefix`
 // is not a prefix of `iter`, otherwise return `Some(iter_after_prefix)` giving
 // `iter` after having exhausted `prefix`.
-fn iter_after<A, I, J>(mut iter: I, mut prefix: J) -> Option<I>
-    where I: Iterator<Item = A> + Clone,
-          J: Iterator<Item = A>,
-          A: PartialEq
+fn iter_after<'a, 'b, I, J>(mut iter: I, mut prefix: J) -> Option<I>
+    where I: Iterator<Item = Component<'a>> + Clone,
+          J: Iterator<Item = Component<'b>>,
 {
     loop {
         let mut iter_next = iter.clone();
@@ -1967,7 +1966,7 @@ pub fn file_name(&self) -> Option<&OsStr> {
     /// # Examples
     ///
     /// ```
-    /// use std::path::Path;
+    /// use std::path::{Path, PathBuf};
     ///
     /// let path = Path::new("/test/haha/foo.txt");
     ///
@@ -1978,17 +1977,20 @@ pub fn file_name(&self) -> Option<&OsStr> {
     /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
     /// assert_eq!(path.strip_prefix("test").is_ok(), false);
     /// assert_eq!(path.strip_prefix("/haha").is_ok(), false);
+    ///
+    /// let prefix = PathBuf::from("/test/");
+    /// assert_eq!(path.strip_prefix(prefix), Ok(Path::new("haha/foo.txt")));
     /// ```
     #[stable(since = "1.7.0", feature = "path_strip_prefix")]
-    pub fn strip_prefix<'a, P: ?Sized>(&'a self, base: &'a P)
-                                       -> Result<&'a Path, StripPrefixError>
+    pub fn strip_prefix<P>(&self, base: P)
+                           -> Result<&Path, StripPrefixError>
         where P: AsRef<Path>
     {
         self._strip_prefix(base.as_ref())
     }
 
-    fn _strip_prefix<'a>(&'a self, base: &'a Path)
-                         -> Result<&'a Path, StripPrefixError> {
+    fn _strip_prefix(&self, base: &Path)
+                     -> Result<&Path, StripPrefixError> {
         iter_after(self.components(), base.components())
             .map(|c| c.as_path())
             .ok_or(StripPrefixError(()))
index 92f0406c09bb5c752170212e06fe94effebd306a..00051d4487a214eac90bef8a089468bea345b835 100644 (file)
@@ -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()
index d59b4fc0b70b8032a961d9123da86e7b5c2276ac..cd88c8f46b3c0c6b3ef78a0342306b7b6a0642a9 100644 (file)
@@ -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 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 @@ fn into_vec(self) -> Vec<u8> {
     }
 }
 
-/// 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")]
index 0f4762aa8810a901490f828bb4975a51e470ec91..c1dba6edda484f66e6f702555d91ce372166f826 100644 (file)
@@ -18,7 +18,9 @@
 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 @@ fn from_mode(mode: u32) -> 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 @@ fn custom_flags(&mut self, flags: i32) -> &mut 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 @@ fn blocks(&self) -> u64 {
     }
 }
 
-/// 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<P: AsRef<Path>, Q: AsRef<Path>>(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.
index e68e180acf1c4cdf9a3c3dd5785c20e30af33ee3..cfb6d5fc703a614ef84e1c2b363ed8d7bb8b48c5 100644 (file)
@@ -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 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 @@ fn exec(&mut self) -> io::Error {
     }
 }
 
-/// 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
index 52be2ccd9f964b43906c8e935018555cba131760..71ff0d46b91e31f8553689730f1ccc9d2a519e7b 100644 (file)
@@ -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 @@
 #[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
index fb9984ccbdda5f63444ead83602afbe6e3f384a3..8347145db5aaf493a9c8ad3cf379415c5897a5bd 100644 (file)
@@ -17,7 +17,9 @@
 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 @@ fn into_vec(self) -> Vec<u8> {
     }
 }
 
-/// 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")]
index 3c5b9424fb06ea1688409166891d0356e686d406..4e981012669033ff393d85a44f1511bab82df6a0 100644 (file)
@@ -105,7 +105,9 @@ fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
     }
 }
 
-/// 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 @@ fn from_mode(mode: u32) -> 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 @@ fn custom_flags(&mut self, flags: i32) -> &mut 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 @@ fn blksize(&self) -> u64 { self.st_blksize() }
     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<P: AsRef<Path>, Q: AsRef<Path>>(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.
index 7b4ec20d91fb46e80a014cf95b25012f8c816cbf..21630ae9746fcdcca4aa3a4fe97a1e77fa551600 100644 (file)
@@ -18,7 +18,9 @@
 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 @@ fn exec(&mut self) -> io::Error {
     }
 }
 
-/// 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
index fe2a48764dc3a99799373cf3f0878a8b61d6dca7..8dadf29945c1a816a217cfb12f0634bb4189acf5 100644 (file)
@@ -21,7 +21,9 @@
 #[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
index d6b8896ac096d2e8caf3594a9b6459dfae69e8cb..98d4355248990a92ec748b667409e91b1e5a1f2d 100644 (file)
@@ -76,7 +76,9 @@
 #[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 @@ fn from_wide(wide: &[u16]) -> 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
index e5cd51b6550b161a78902784aac8dc043debc39d..78c9e95a05501d0821602ab330ecc8cde75ff178 100644 (file)
@@ -103,9 +103,9 @@ fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
     }
 }
 
-/// 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 @@ fn security_qos_flags(&mut self, flags: u32) -> &mut 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 @@ fn last_write_time(&self) -> u64 { self.as_inner().modified_u64() }
     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.
index 759f055c4b1236e4640982e21d4be19fd15b7155..a02bcbe0c87c259ad599c2e0d2dbb2b973fe73fd 100644 (file)
@@ -82,7 +82,9 @@ fn into_raw_handle(self) -> RawHandle {
     }
 }
 
-/// 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 @@ fn from_raw(raw: u32) -> Self {
     }
 }
 
-/// 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`.
index e4bfdf25001a86edb9ed9372f2a49ad7a146e6b1..120dff2dbb926acf80ea10b3c1bb793499f24ed1 100644 (file)
@@ -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 {
@@ -1768,8 +1767,8 @@ fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
                 }
             }
             ast::TraitItemKind::Type(_, ref default) => {
-                // We use two if statements instead of something like match guards so that both
-                // of these errors can be emitted if both cases apply.
+                // We use three if statements instead of something like match guards so that all
+                // of these errors can be emitted if all cases apply.
                 if default.is_some() {
                     gate_feature_post!(&self, associated_type_defaults, ti.span,
                                        "associated type defaults are unstable");
@@ -1778,6 +1777,10 @@ fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
                     gate_feature_post!(&self, generic_associated_types, ti.span,
                                        "generic associated types are unstable");
                 }
+                if !ti.generics.where_clause.predicates.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ti.span,
+                                       "where clauses on associated types are unstable");
+                }
             }
             _ => {}
         }
index 50fac600a978d21ab05dc0ae9174120f25621029..b449c5eea6658e7cdda063f0dac41b2c467bf008 100644 (file)
@@ -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 @@ fn eq(&self, other: &T) -> bool {
 
 #[derive(Default)]
 pub struct Interner {
-    names: HashMap<Box<str>, Symbol>,
+    names: FxHashMap<Box<str>, Symbol>,
     strings: Vec<Box<str>>,
     gensyms: Vec<Symbol>,
 }
diff --git a/src/test/compile-fail/issue-44578.rs b/src/test/compile-fail/issue-44578.rs
deleted file mode 100644 (file)
index 18cfb35..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait Foo {
-    const AMT: usize;
-}
-
-enum Bar<A, B> {
-    First(A),
-    Second(B),
-}
-
-impl<A: Foo, B: Foo> Foo for Bar<A, B> {
-    const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
-}
-
-impl Foo for u8 {
-    const AMT: usize = 1;
-}
-
-impl Foo for u16 {
-    const AMT: usize = 2;
-}
-
-fn main() {
-    println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ E0080
-}
index 324bcf60e8ff60d1c2c117b779712af6ce3db47d..e059c354d65a73151a3d06d8d9b57077cc1e59dd 100644 (file)
@@ -8,11 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-pass
+
 const X: u32 = 5;
 const Y: u32 = 6;
 const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
 //~^ WARN attempt to subtract with overflow
 
 fn main() {
-    println!("{}", FOO); //~ E0080
+    println!("{}", FOO);
+    //~^ WARN constant evaluation error
 }
index 9270dafbe651a4cd6d72220a42cd43cfacf5a841..fd29990fec295abd5c0d807b663020bec0c72a26 100644 (file)
@@ -1,17 +1,14 @@
 warning: attempt to subtract with overflow
-  --> $DIR/conditional_array_execution.rs:13:19
+  --> $DIR/conditional_array_execution.rs:15:19
    |
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    |                   ^^^^^
    |
    = note: #[warn(const_err)] on by default
 
-error[E0080]: constant evaluation error
-  --> $DIR/conditional_array_execution.rs:17:20
+warning: constant evaluation error
+  --> $DIR/conditional_array_execution.rs:19:20
    |
-LL |     println!("{}", FOO); //~ E0080
+LL |     println!("{}", FOO);
    |                    ^^^ referenced constant has errors
 
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0080`.
index d5c4796d0b497f86d8f98b545291b0e94e2cc2a4..b27791ef5337b7c7039d1005e2464e5b452521d5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-pass
+
 #![feature(const_fn)]
 
 const fn foo(x: u32) -> u32 {
@@ -20,6 +22,6 @@ fn main() {
     const Y: u32 = foo(0-1);
     //~^ WARN attempt to subtract with overflow
     println!("{} {}", X, Y);
-    //~^ ERROR constant evaluation error
-    //~| ERROR constant evaluation error
+    //~^ WARN constant evaluation error
+    //~| WARN constant evaluation error
 }
index 2d51e6603b59bc335caf86bced103ed26ef44e3c..5da47a85eb803f3b1b79e8179d72b93856dfa020 100644 (file)
@@ -1,29 +1,26 @@
 warning: attempt to subtract with overflow
-  --> $DIR/issue-43197.rs:18:20
+  --> $DIR/issue-43197.rs:20:20
    |
 LL |     const X: u32 = 0-1;
    |                    ^^^
    |
    = note: #[warn(const_err)] on by default
 
-error[E0080]: constant evaluation error
-  --> $DIR/issue-43197.rs:22:23
+warning: constant evaluation error
+  --> $DIR/issue-43197.rs:24:23
    |
 LL |     println!("{} {}", X, Y);
    |                       ^ referenced constant has errors
 
 warning: attempt to subtract with overflow
-  --> $DIR/issue-43197.rs:20:24
+  --> $DIR/issue-43197.rs:22:24
    |
 LL |     const Y: u32 = foo(0-1);
    |                        ^^^
 
-error[E0080]: constant evaluation error
-  --> $DIR/issue-43197.rs:22:26
+warning: constant evaluation error
+  --> $DIR/issue-43197.rs:24:26
    |
 LL |     println!("{} {}", X, Y);
    |                          ^ referenced constant has errors
 
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-44578.rs b/src/test/ui/const-eval/issue-44578.rs
new file mode 100644 (file)
index 0000000..765113c
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+
+trait Foo {
+    const AMT: usize;
+}
+
+enum Bar<A, B> {
+    First(A),
+    Second(B),
+}
+
+impl<A: Foo, B: Foo> Foo for Bar<A, B> {
+    const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+}
+
+impl Foo for u8 {
+    const AMT: usize = 1;
+}
+
+impl Foo for u16 {
+    const AMT: usize = 2;
+}
+
+fn main() {
+    println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
+    //~^ WARN const_err
+}
diff --git a/src/test/ui/const-eval/issue-44578.stderr b/src/test/ui/const-eval/issue-44578.stderr
new file mode 100644 (file)
index 0000000..01c6fa3
--- /dev/null
@@ -0,0 +1,14 @@
+warning: constant evaluation error
+  --> $DIR/issue-44578.rs:35:20
+   |
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+   |
+   = note: #[warn(const_err)] on by default
+
+warning: constant evaluation error
+  --> $DIR/issue-44578.rs:35:20
+   |
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
diff --git a/src/test/ui/const-eval/promoted_errors.rs b/src/test/ui/const-eval/promoted_errors.rs
new file mode 100644 (file)
index 0000000..dc30c7f
--- /dev/null
@@ -0,0 +1,28 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+// compile-flags: -O
+fn main() {
+    println!("{}", 0u32 - 1);
+    //~^ WARN const_err
+    //~| WARN const_err
+    let _x = 0u32 - 1;
+    //~^ WARN const_err
+    println!("{}", 1/(1-1));
+    //~^ WARN const_err
+    //~| WARN const_err
+    let _x = 1/(1-1);
+    //~^ WARN const_err
+    //~| WARN const_err
+    println!("{}", 1/(false as u32));
+    //~^ WARN const_err
+    let _x = 1/(false as u32);
+}
diff --git a/src/test/ui/const-eval/promoted_errors.stderr b/src/test/ui/const-eval/promoted_errors.stderr
new file mode 100644 (file)
index 0000000..a5db8cc
--- /dev/null
@@ -0,0 +1,50 @@
+warning: constant evaluation error
+  --> $DIR/promoted_errors.rs:14:20
+   |
+LL |     println!("{}", 0u32 - 1);
+   |                    ^^^^^^^^ attempted to do overflowing math
+   |
+   = note: #[warn(const_err)] on by default
+
+warning: constant evaluation error
+  --> $DIR/promoted_errors.rs:14:20
+   |
+LL |     println!("{}", 0u32 - 1);
+   |                    ^^^^^^^^ attempted to do overflowing math
+
+warning: constant evaluation error
+  --> $DIR/promoted_errors.rs:17:14
+   |
+LL |     let _x = 0u32 - 1;
+   |              ^^^^^^^^ attempted to do overflowing math
+
+warning: attempt to divide by zero
+  --> $DIR/promoted_errors.rs:19:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^
+
+warning: constant evaluation error
+  --> $DIR/promoted_errors.rs:19:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^ attempted to do overflowing math
+
+warning: attempt to divide by zero
+  --> $DIR/promoted_errors.rs:22:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^
+
+warning: constant evaluation error
+  --> $DIR/promoted_errors.rs:22:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^ attempted to do overflowing math
+
+warning: constant evaluation error
+  --> $DIR/promoted_errors.rs:25:20
+   |
+LL |     println!("{}", 1/(false as u32));
+   |                    ^^^^^^^^^^^^^^^^ attempted to do overflowing math
+
index 724ec2496f24cdc6a342f903b786e68caa392969..347066268664324aebffcbf3f6c254a96fa60e15 100644 (file)
@@ -15,6 +15,7 @@ trait PointerFamily<U> {
     //~^ ERROR generic associated types are unstable
     type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
     //~^ ERROR generic associated types are unstable
+    //~| ERROR where clauses on associated types are unstable
 }
 
 struct Foo;
@@ -25,4 +26,10 @@ impl PointerFamily<u32> for Foo {
     //~^ ERROR generic associated types are unstable
 }
 
+trait Bar {
+    type Assoc where Self: Sized;
+    //~^ ERROR where clauses on associated types are unstable
+}
+
+
 fn main() {}
index 5f23def88eb0633f6b4505e9f75ebd012883b125..d7891f13c6b4d9f6f283ecdb16ea2cc69e725502 100644 (file)
@@ -14,8 +14,16 @@ LL |     type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
    |
    = help: add #![feature(generic_associated_types)] to the crate attributes to enable
 
+error[E0658]: where clauses on associated types are unstable (see issue #44265)
+  --> $DIR/feature-gate-generic_associated_types.rs:16:5
+   |
+LL |     type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(generic_associated_types)] to the crate attributes to enable
+
 error[E0658]: generic associated types are unstable (see issue #44265)
-  --> $DIR/feature-gate-generic_associated_types.rs:22:5
+  --> $DIR/feature-gate-generic_associated_types.rs:23:5
    |
 LL |     type Pointer<usize> = Box<usize>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,13 +31,21 @@ LL |     type Pointer<usize> = Box<usize>;
    = help: add #![feature(generic_associated_types)] to the crate attributes to enable
 
 error[E0658]: generic associated types are unstable (see issue #44265)
-  --> $DIR/feature-gate-generic_associated_types.rs:24:5
+  --> $DIR/feature-gate-generic_associated_types.rs:25:5
    |
 LL |     type Pointer2<u32> = Box<u32>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(generic_associated_types)] to the crate attributes to enable
 
-error: aborting due to 4 previous errors
+error[E0658]: where clauses on associated types are unstable (see issue #44265)
+  --> $DIR/feature-gate-generic_associated_types.rs:30:5
+   |
+LL |     type Assoc where Self: Sized;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(generic_associated_types)] to the crate attributes to enable
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
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 (file)
index 0000000..1e0039a
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 (file)
index 0000000..986a2d8
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: use of unstable library feature 'ptr_internals': use NonNull instead and consider PhantomData<T> (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`.
index cfe9a43707cf614cd7318e004ce30e94d3b5633c..4fc11daaa3afa0de5758d8c046f433467e571299 100755 (executable)
@@ -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
index 0f4d247633a61b46016c27b0b8b860475d3aa19b..aabf2e6f8f0e675c2e918e7491c1cd59546c75d0 100644 (file)
@@ -26,7 +26,7 @@
 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 @@ fn new(line_number: u32) -> Mismatch {
     }
 }
 
+trait PathBufExt {
+    /// Append an extension to the path, even if it already has one.
+    fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf;
+}
+
+impl PathBufExt for PathBuf {
+    fn with_extra_extension<S: AsRef<OsStr>>(&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<Mismatch> {
     let mut line_number = 1;
@@ -1725,20 +1745,14 @@ fn make_lib_name(&self, auxfile: &Path) -> PathBuf {
     }
 
     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 @@ fn make_out_name(&self, extension: &str) -> PathBuf {
     }
 
     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
-    ///
-    ///     <output>/foo/bar-stage1
+    /// Given a test path like `compile-fail/foo/bar.rs` returns a name like
+    /// `/path/to/build/<triple>/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-<triple>`
+    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 @@ fn charset() -> &'static str {
     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 @@ fn run_rmake_test(&self) {
             .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 @@ fn expected_output_path(&self, kind: &str) -> PathBuf {
                                             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 @@ fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
             }
         }
 
-        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!(
index bda58bc09f77625714a23244b2018ebace908ddc..351005ff4b816b3038f4e6d99980f6320dd5d152 100644 (file)
 
 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;
                 }