about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-06 19:28:54 +0000
committerbors <bors@rust-lang.org>2018-02-06 19:28:54 +0000
commitbd98fe0c05601d8a318a709adc4263f3348ea8d4 (patch)
tree6f6f45f6da609c2c34e0cedb81f08a7f5bd5a8aa
parentca7d839088cbfe5b9bf232f5c27c48703d4f1605 (diff)
parent7f0e87a781b449f463b4238d5d08c59056127e3d (diff)
downloadrust-bd98fe0c05601d8a318a709adc4263f3348ea8d4.tar.gz
rust-bd98fe0c05601d8a318a709adc4263f3348ea8d4.zip
Auto merge of #48040 - kennytm:rollup, r=kennytm
Rollup of 7 pull requests

- Successful merges: #46962, #47986, #48012, #48013, #48026, #48031, #48036
- Failed merges:
-rw-r--r--config.toml.example8
-rw-r--r--src/Cargo.lock1
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/dist.rs6
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/libcore/iter/range.rs46
-rw-r--r--src/libcore/tests/iter.rs20
-rw-r--r--src/libproc_macro/lib.rs2
-rw-r--r--src/librustc/diagnostics.rs22
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/os/raw/char.md11
-rw-r--r--src/libstd/os/raw/double.md7
-rw-r--r--src/libstd/os/raw/float.md6
-rw-r--r--src/libstd/os/raw/int.md7
-rw-r--r--src/libstd/os/raw/long.md7
-rw-r--r--src/libstd/os/raw/longlong.md7
-rw-r--r--src/libstd/os/raw/mod.rs (renamed from src/libstd/os/raw.rs)38
-rw-r--r--src/libstd/os/raw/schar.md6
-rw-r--r--src/libstd/os/raw/short.md6
-rw-r--r--src/libstd/os/raw/uchar.md6
-rw-r--r--src/libstd/os/raw/uint.md7
-rw-r--r--src/libstd/os/raw/ulong.md7
-rw-r--r--src/libstd/os/raw/ulonglong.md7
-rw-r--r--src/libstd/os/raw/ushort.md6
-rw-r--r--src/libtest/lib.rs17
25 files changed, 235 insertions, 18 deletions
diff --git a/config.toml.example b/config.toml.example
index 75cab74258b..c2ec731eeb8 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -295,7 +295,7 @@
 
 # Flag indicating whether git info will be retrieved from .git automatically.
 # Having the git information can cause a lot of rebuilds during development.
-# Note: If this attribute is not explicity set (e.g. if left commented out) it
+# Note: If this attribute is not explicitly set (e.g. if left commented out) it
 # will default to true if channel = "dev", but will default to false otherwise.
 #ignore-git = true
 
@@ -317,8 +317,8 @@
 # bootstrap)
 #codegen-backends = ["llvm"]
 
-# Flag indicating whether `libstd` calls an imported function to hande basic IO
-# when targetting WebAssembly. Enable this to debug tests for the `wasm32-unknown-unknown`
+# Flag indicating whether `libstd` calls an imported function to handle basic IO
+# when targeting WebAssembly. Enable this to debug tests for the `wasm32-unknown-unknown`
 # target, as without this option the test output will not be captured.
 #wasm-syscall = false
 
@@ -349,7 +349,7 @@
 #linker = "cc"
 
 # Path to the `llvm-config` binary of the installation of a custom LLVM to link
-# against. Note that if this is specifed we don't compile LLVM at all for this
+# against. Note that if this is specified we don't compile LLVM at all for this
 # target.
 #llvm-config = "../path/to/llvm/root/bin/llvm-config"
 
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 1393dd46d6b..52ed134c01e 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -133,6 +133,7 @@ dependencies = [
  "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index bbbbf0e1915..2d478341317 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -41,3 +41,4 @@ serde_derive = "1.0.8"
 serde_json = "1.0.2"
 toml = "0.4"
 lazy_static = "0.2"
+time = "0.1"
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index dbb7d19e432..6717b1cb098 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -33,6 +33,7 @@ use builder::{Builder, RunConfig, ShouldRun, Step};
 use compile;
 use tool::{self, Tool};
 use cache::{INTERNER, Interned};
+use time;
 
 pub fn pkgname(build: &Build, component: &str) -> String {
     if component == "cargo" {
@@ -445,8 +446,7 @@ impl Step for Rustc {
             t!(fs::create_dir_all(image.join("share/man/man1")));
             let man_src = build.src.join("src/doc/man");
             let man_dst = image.join("share/man/man1");
-            let date_output = output(Command::new("date").arg("+%B %Y"));
-            let month_year = date_output.trim();
+            let month_year = t!(time::strftime("%B %Y", &time::now()));
             // don't use our `bootstrap::util::{copy, cp_r}`, because those try
             // to hardlink, and we don't want to edit the source templates
             for entry_result in t!(fs::read_dir(man_src)) {
@@ -456,7 +456,7 @@ impl Step for Rustc {
                 t!(fs::copy(&page_src, &page_dst));
                 // template in month/year and version number
                 replace_in_file(&page_dst,
-                                &[("<INSERT DATE HERE>", month_year),
+                                &[("<INSERT DATE HERE>", &month_year),
                                   ("<INSERT VERSION HERE>", channel::CFG_RELEASE_NUM)]);
             }
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index f2a7ce30c8a..a84a6a8990b 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -130,6 +130,7 @@ extern crate cc;
 extern crate getopts;
 extern crate num_cpus;
 extern crate toml;
+extern crate time;
 
 #[cfg(unix)]
 extern crate libc;
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 66a76a24df4..3b034efcce1 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -10,7 +10,7 @@
 
 use convert::TryFrom;
 use mem;
-use ops::{self, Add, Sub};
+use ops::{self, Add, Sub, Try};
 use usize;
 
 use super::{FusedIterator, TrustedLen};
@@ -397,6 +397,28 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
     fn max(mut self) -> Option<A> {
         self.next_back()
     }
+
+    #[inline]
+    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        let mut accum = init;
+        if self.start <= self.end {
+            loop {
+                let (x, done) =
+                    if self.start < self.end {
+                        let n = self.start.add_one();
+                        (mem::replace(&mut self.start, n), false)
+                    } else {
+                        self.end.replace_zero();
+                        (self.start.replace_one(), true)
+                    };
+                accum = f(accum, x)?;
+                if done { break }
+            }
+        }
+        Try::from_ok(accum)
+    }
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
@@ -418,6 +440,28 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
             _ => None,
         }
     }
+
+    #[inline]
+    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        let mut accum = init;
+        if self.start <= self.end {
+            loop {
+                let (x, done) =
+                    if self.start < self.end {
+                        let n = self.end.sub_one();
+                        (mem::replace(&mut self.end, n), false)
+                    } else {
+                        self.start.replace_one();
+                        (self.end.replace_zero(), true)
+                    };
+                accum = f(accum, x)?;
+                if done { break }
+            }
+        }
+        Try::from_ok(accum)
+    }
 }
 
 #[unstable(feature = "fused", issue = "35602")]
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index e52e119ff59..dc866d180bf 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1460,6 +1460,26 @@ fn test_range_inclusive_min() {
 }
 
 #[test]
+fn test_range_inclusive_folds() {
+    assert_eq!((1..=10).sum::<i32>(), 55);
+    assert_eq!((1..=10).rev().sum::<i32>(), 55);
+
+    let mut it = 40..=50;
+    assert_eq!(it.try_fold(0, i8::checked_add), None);
+    assert_eq!(it, 44..=50);
+    assert_eq!(it.try_rfold(0, i8::checked_add), None);
+    assert_eq!(it, 44..=47);
+
+    let mut it = 10..=20;
+    assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(165));
+    assert_eq!(it, 1..=0);
+
+    let mut it = 10..=20;
+    assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(165));
+    assert_eq!(it, 1..=0);
+}
+
+#[test]
 fn test_repeat() {
     let mut it = repeat(42);
     assert_eq!(it.next(), Some(42));
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index b9e816baac0..6768e0ade43 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -685,7 +685,7 @@ impl TokenTree {
                 })
             }
 
-            DotEq => unreachable!(),
+            DotEq => joint!('.', Eq),
             OpenDelim(..) | CloseDelim(..) => unreachable!(),
             Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
         };
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 8bd89b834d6..4c256556191 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -256,6 +256,28 @@ trait Foo {
 }
 ```
 
+### The trait cannot contain associated constants
+
+Just like static functions, associated constants aren't stored on the method
+table. If the trait or any subtrait contain an associated constant, they cannot
+be made into an object.
+
+```compile_fail,E0038
+trait Foo {
+    const X: i32;
+}
+
+impl Foo {}
+```
+
+A simple workaround is to use a helper method instead:
+
+```
+trait Foo {
+    fn x(&self) -> i32;
+}
+```
+
 ### The trait cannot use `Self` as a type parameter in the supertrait listing
 
 This is similar to the second sub-error, but subtler. It happens in situations
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index a8049e676b3..642fa8775a4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -260,6 +260,7 @@
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
+#![feature(external_doc)]
 #![feature(fs_read_write)]
 #![feature(fixed_size_array)]
 #![feature(float_from_str_radix)]
diff --git a/src/libstd/os/raw/char.md b/src/libstd/os/raw/char.md
new file mode 100644
index 00000000000..9a55767d965
--- /dev/null
+++ b/src/libstd/os/raw/char.md
@@ -0,0 +1,11 @@
+Equivalent to C's `char` type.
+
+[C's `char` type] is completely unlike [Rust's `char` type]; while Rust's type represents a unicode scalar value, C's `char` type is just an ordinary integer. This type will always be either [`i8`] or [`u8`], as the type is defined as being one byte long.
+
+C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See [`CStr`] for more information.
+
+[C's `char` type]: https://en.wikipedia.org/wiki/C_data_types#Basic_types
+[Rust's `char` type]: ../../primitive.char.html
+[`CStr`]: ../../ffi/struct.CStr.html
+[`i8`]: ../../primitive.i8.html
+[`u8`]: ../../primitive.u8.html
diff --git a/src/libstd/os/raw/double.md b/src/libstd/os/raw/double.md
new file mode 100644
index 00000000000..6818dada317
--- /dev/null
+++ b/src/libstd/os/raw/double.md
@@ -0,0 +1,7 @@
+Equivalent to C's `double` type.
+
+This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
+
+[IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
+[`float`]: type.c_float.html
+[`f64`]: ../../primitive.f64.html
diff --git a/src/libstd/os/raw/float.md b/src/libstd/os/raw/float.md
new file mode 100644
index 00000000000..57d1071d0da
--- /dev/null
+++ b/src/libstd/os/raw/float.md
@@ -0,0 +1,6 @@
+Equivalent to C's `float` type.
+
+This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
+
+[IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
+[`f32`]: ../../primitive.f32.html
diff --git a/src/libstd/os/raw/int.md b/src/libstd/os/raw/int.md
new file mode 100644
index 00000000000..a0d25fd21d8
--- /dev/null
+++ b/src/libstd/os/raw/int.md
@@ -0,0 +1,7 @@
+Equivalent to C's `signed int` (`int`) type.
+
+This type will almost always be [`i32`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer that is at least the size of a [`short`]; some systems define it as an [`i16`], for example.
+
+[`short`]: type.c_short.html
+[`i32`]: ../../primitive.i32.html
+[`i16`]: ../../primitive.i16.html
diff --git a/src/libstd/os/raw/long.md b/src/libstd/os/raw/long.md
new file mode 100644
index 00000000000..c620b402819
--- /dev/null
+++ b/src/libstd/os/raw/long.md
@@ -0,0 +1,7 @@
+Equivalent to C's `signed long` (`long`) type.
+
+This type will always be [`i32`] or [`i64`]. Most notably, many Linux-based systems assume an `i64`, but Windows assumes `i32`. The C standard technically only requires that this type be a signed integer that is at least 32 bits and at least the size of an [`int`], although in practice, no system would have a `long` that is neither an `i32` nor `i64`.
+
+[`int`]: type.c_int.html
+[`i32`]: ../../primitive.i32.html
+[`i64`]: ../../primitive.i64.html
diff --git a/src/libstd/os/raw/longlong.md b/src/libstd/os/raw/longlong.md
new file mode 100644
index 00000000000..ab3d6436568
--- /dev/null
+++ b/src/libstd/os/raw/longlong.md
@@ -0,0 +1,7 @@
+Equivalent to C's `signed long long` (`long long`) type.
+
+This type will almost always be [`i64`], but may differ on some systems. The C standard technically only requires that this type be a signed integer that is at least 64 bits and at least the size of a [`long`], although in practice, no system would have a `long long` that is not an `i64`, as most systems do not have a standardised [`i128`] type.
+
+[`long`]: type.c_int.html
+[`i64`]: ../../primitive.i64.html
+[`i128`]: ../../primitive.i128.html
diff --git a/src/libstd/os/raw.rs b/src/libstd/os/raw/mod.rs
index 279caf8053a..d5eeb5252f0 100644
--- a/src/libstd/os/raw.rs
+++ b/src/libstd/os/raw/mod.rs
@@ -8,12 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Raw OS-specific types for the current platform/architecture
+//! Platform-specific types, as defined by C.
+//!
+//! Code that interacts via FFI will almost certainly be using the
+//! base types provided by C, which aren't nearly as nicely defined
+//! as Rust's primitive types. This module provides types which will
+//! match those defined by C, so that code that interacts with C will
+//! refer to the correct types.
 
 #![stable(feature = "raw_os", since = "1.1.0")]
 
 use fmt;
 
+#[doc(include = "os/raw/char.md")]
 #[cfg(any(all(target_os = "linux", any(target_arch = "aarch64",
                                        target_arch = "arm",
                                        target_arch = "powerpc",
@@ -25,6 +32,7 @@ use fmt;
           all(target_os = "openbsd", target_arch = "aarch64"),
           all(target_os = "fuchsia", target_arch = "aarch64")))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
+#[doc(include = "os/raw/char.md")]
 #[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64",
                                            target_arch = "arm",
                                            target_arch = "powerpc",
@@ -36,30 +44,50 @@ use fmt;
               all(target_os = "openbsd", target_arch = "aarch64"),
               all(target_os = "fuchsia", target_arch = "aarch64"))))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
+#[doc(include = "os/raw/schar.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
+#[doc(include = "os/raw/uchar.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8;
+#[doc(include = "os/raw/short.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16;
+#[doc(include = "os/raw/ushort.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16;
+#[doc(include = "os/raw/int.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32;
+#[doc(include = "os/raw/uint.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32;
+#[doc(include = "os/raw/long.md")]
 #[cfg(any(target_pointer_width = "32", windows))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32;
+#[doc(include = "os/raw/ulong.md")]
 #[cfg(any(target_pointer_width = "32", windows))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32;
+#[doc(include = "os/raw/long.md")]
 #[cfg(all(target_pointer_width = "64", not(windows)))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64;
+#[doc(include = "os/raw/ulong.md")]
 #[cfg(all(target_pointer_width = "64", not(windows)))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64;
+#[doc(include = "os/raw/longlong.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64;
+#[doc(include = "os/raw/ulonglong.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64;
+#[doc(include = "os/raw/float.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32;
+#[doc(include = "os/raw/double.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64;
 
-/// Type used to construct void pointers for use with C.
+/// Equivalent to C's `void` type when used as a [pointer].
 ///
-/// This type is only useful as a pointer target. Do not use it as a
-/// return type for FFI functions which have the `void` return type in
-/// C. Use the unit type `()` or omit the return type instead.
+/// In essence, `*const c_void` is equivalent to C's `const void*`
+/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
+/// *not* the same as C's `void` return type, which is Rust's `()` type.
+///
+/// Ideally, this type would be equivalent to [`!`], but currently it may
+/// be more ideal to use `c_void` for FFI purposes.
+///
+/// [`!`]: ../../primitive.never.html
+/// [pointer]: ../../primitive.pointer.html
 // NB: For LLVM to recognize the void pointer type and by extension
 //     functions like malloc(), we need to have it represented as i8* in
 //     LLVM bitcode. The enum used here ensures this and prevents misuse
diff --git a/src/libstd/os/raw/schar.md b/src/libstd/os/raw/schar.md
new file mode 100644
index 00000000000..6aa8b1211d8
--- /dev/null
+++ b/src/libstd/os/raw/schar.md
@@ -0,0 +1,6 @@
+Equivalent to C's `signed char` type.
+
+This type will always be [`i8`], but is included for completeness. It is defined as being a signed integer the same size as a C [`char`].
+
+[`char`]: type.c_char.html
+[`i8`]: ../../primitive.i8.html
diff --git a/src/libstd/os/raw/short.md b/src/libstd/os/raw/short.md
new file mode 100644
index 00000000000..be92c6c106d
--- /dev/null
+++ b/src/libstd/os/raw/short.md
@@ -0,0 +1,6 @@
+Equivalent to C's `signed short` (`short`) type.
+
+This type will almost always be [`i16`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer with at least 16 bits; some systems may define it as `i32`, for example.
+
+[`char`]: type.c_char.html
+[`i16`]: ../../primitive.i16.html
diff --git a/src/libstd/os/raw/uchar.md b/src/libstd/os/raw/uchar.md
new file mode 100644
index 00000000000..b6ca711f869
--- /dev/null
+++ b/src/libstd/os/raw/uchar.md
@@ -0,0 +1,6 @@
+Equivalent to C's `unsigned char` type.
+
+This type will always be [`u8`], but is included for completeness. It is defined as being an unsigned integer the same size as a C [`char`].
+
+[`char`]: type.c_char.html
+[`u8`]: ../../primitive.u8.html
diff --git a/src/libstd/os/raw/uint.md b/src/libstd/os/raw/uint.md
new file mode 100644
index 00000000000..6f7013a8ac1
--- /dev/null
+++ b/src/libstd/os/raw/uint.md
@@ -0,0 +1,7 @@
+Equivalent to C's `unsigned int` type.
+
+This type will almost always be [`u32`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as an [`int`]; some systems define it as a [`u16`], for example.
+
+[`int`]: type.c_int.html
+[`u32`]: ../../primitive.u32.html
+[`u16`]: ../../primitive.u16.html
diff --git a/src/libstd/os/raw/ulong.md b/src/libstd/os/raw/ulong.md
new file mode 100644
index 00000000000..c350395080e
--- /dev/null
+++ b/src/libstd/os/raw/ulong.md
@@ -0,0 +1,7 @@
+Equivalent to C's `unsigned long` type.
+
+This type will always be [`u32`] or [`u64`]. Most notably, many Linux-based systems assume an `u64`, but Windows assumes `u32`. The C standard technically only requires that this type be an unsigned integer with the size of a [`long`], although in practice, no system would have a `ulong` that is neither a `u32` nor `u64`.
+
+[`long`]: type.c_long.html
+[`u32`]: ../../primitive.u32.html
+[`u64`]: ../../primitive.u64.html
diff --git a/src/libstd/os/raw/ulonglong.md b/src/libstd/os/raw/ulonglong.md
new file mode 100644
index 00000000000..c41faf74c5c
--- /dev/null
+++ b/src/libstd/os/raw/ulonglong.md
@@ -0,0 +1,7 @@
+Equivalent to C's `unsigned long long` type.
+
+This type will almost always be [`u64`], but may differ on some systems. The C standard technically only requires that this type be an unsigned integer with the size of a [`long long`], although in practice, no system would have a `long long` that is not a `u64`, as most systems do not have a standardised [`u128`] type.
+
+[`long long`]: type.c_longlong.html
+[`u64`]: ../../primitive.u64.html
+[`u128`]: ../../primitive.u128.html
diff --git a/src/libstd/os/raw/ushort.md b/src/libstd/os/raw/ushort.md
new file mode 100644
index 00000000000..d364abb3c8e
--- /dev/null
+++ b/src/libstd/os/raw/ushort.md
@@ -0,0 +1,6 @@
+Equivalent to C's `unsigned short` type.
+
+This type will almost always be [`u16`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as a [`short`].
+
+[`short`]: type.c_short.html
+[`u16`]: ../../primitive.u16.html
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index ffa27688cf1..9ea5f39b71f 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -72,6 +72,7 @@ use std::sync::{Arc, Mutex};
 use std::thread;
 use std::time::{Instant, Duration};
 use std::borrow::Cow;
+use std::process;
 
 const TEST_WARN_TIMEOUT_S: u64 = 60;
 const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in quiet mode
@@ -266,19 +267,27 @@ impl Options {
 pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
     let mut opts = match parse_opts(args) {
         Some(Ok(o)) => o,
-        Some(Err(msg)) => panic!("{:?}", msg),
+        Some(Err(msg)) => {
+            eprintln!("error: {}", msg);
+            process::exit(101);
+        },
         None => return,
     };
+
     opts.options = options;
     if opts.list {
         if let Err(e) = list_tests_console(&opts, tests) {
-            panic!("io error when listing tests: {:?}", e);
+            eprintln!("error: io error when listing tests: {:?}", e);
+            process::exit(101);
         }
     } else {
         match run_tests_console(&opts, tests) {
             Ok(true) => {}
-            Ok(false) => std::process::exit(101),
-            Err(e) => panic!("io error when running tests: {:?}", e),
+            Ok(false) => process::exit(101),
+            Err(e) => {
+                eprintln!("error: io error when listing tests: {:?}", e);
+                process::exit(101);
+            },
         }
     }
 }