about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/compiletest/compiletest.rs2
-rw-r--r--src/doc/trpl/SUMMARY.md1
-rw-r--r--src/doc/trpl/associated-constants.md79
-rw-r--r--src/libcollections/slice.rs12
-rw-r--r--src/libcollections/vec.rs5
-rw-r--r--src/libcollectionstest/vec.rs5
-rw-r--r--src/libcore/cell.rs59
-rw-r--r--src/libcore/fmt/mod.rs6
-rw-r--r--src/libcore/hash/sip.rs3
-rw-r--r--src/libcoretest/cell.rs24
-rw-r--r--src/librustc_trans/trans/_match.rs35
-rw-r--r--src/libstd/collections/hash/map.rs1
-rw-r--r--src/libstd/net/ip.rs28
-rw-r--r--src/libstd/sync/mutex.rs44
-rw-r--r--src/libstd/sync/rwlock.rs53
-rw-r--r--src/libtest/lib.rs59
-rw-r--r--src/test/compile-fail/bad-sized.rs4
-rw-r--r--src/test/run-pass/issue-23261.rs70
-rw-r--r--src/test/run-pass/out-of-stack.rs1
19 files changed, 386 insertions, 105 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index d014512666f..2ee391a9374 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -269,7 +269,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
         run_ignored: config.run_ignored,
         logfile: config.logfile.clone(),
         run_tests: true,
-        run_benchmarks: true,
+        bench_benchmarks: true,
         nocapture: env::var("RUST_TEST_NOCAPTURE").is_ok(),
         color: test::AutoColor,
     }
diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md
index 695dc42cb64..4dc77aaec5b 100644
--- a/src/doc/trpl/SUMMARY.md
+++ b/src/doc/trpl/SUMMARY.md
@@ -64,5 +64,6 @@
     * [Benchmark Tests](benchmark-tests.md)
     * [Box Syntax and Patterns](box-syntax-and-patterns.md)
     * [Slice Patterns](slice-patterns.md)
+    * [Associated Constants](associated-constants.md)
 * [Glossary](glossary.md)
 * [Academic Research](academic-research.md)
diff --git a/src/doc/trpl/associated-constants.md b/src/doc/trpl/associated-constants.md
new file mode 100644
index 00000000000..1c097be6d68
--- /dev/null
+++ b/src/doc/trpl/associated-constants.md
@@ -0,0 +1,79 @@
+% Associated Constants
+
+With the `associated_consts` feature, you can define constants like this:
+
+```rust
+#![feature(associated_consts)]
+
+trait Foo {
+    const ID: i32;
+}
+
+impl Foo for i32 {
+    const ID: i32 = 1;
+}
+
+fn main() {
+    assert_eq!(1, i32::ID);
+}
+```
+
+Any implementor of `Foo` will have to define `ID`. Without the definition:
+
+```rust,ignore
+#![feature(associated_consts)]
+
+trait Foo {
+    const ID: i32;
+}
+
+impl Foo for i32 {
+}
+```
+
+gives
+
+```text
+error: not all trait items implemented, missing: `ID` [E0046]
+     impl Foo for i32 {
+     }
+```
+
+A default value can be implemented as well:
+
+```rust
+#![feature(associated_consts)]
+
+trait Foo {
+    const ID: i32 = 1;
+}
+
+impl Foo for i32 {
+}
+
+impl Foo for i64 {
+    const ID: i32 = 5;
+}
+
+fn main() {
+    assert_eq!(1, i32::ID);
+    assert_eq!(5, i64::ID);
+}
+```
+
+As you can see, when implementing `Foo`, you can leave it unimplemented, as
+with `i32`. It will then use the default value. But, as in `i64`, we can also
+add our own definition.
+
+Associated constants don’t have to be associated with a trait. An `impl` block
+for a `struct` works fine too:
+
+```rust
+#![feature(associated_consts)]
+
+struct Foo;
+
+impl Foo {
+    pub const FOO: u32 = 3;
+}
+```
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 6622d8a9c40..729b0ebc3ce 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -1004,11 +1004,7 @@ pub trait SliceConcatExt<T: ?Sized, U> {
     /// # Examples
     ///
     /// ```
-    /// let v = vec!["hello", "world"];
-    ///
-    /// let s: String = v.concat();
-    ///
-    /// println!("{}", s); // prints "helloworld"
+    /// assert_eq!(["hello", "world"].concat(), "helloworld");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn concat(&self) -> U;
@@ -1018,11 +1014,7 @@ pub trait SliceConcatExt<T: ?Sized, U> {
     /// # Examples
     ///
     /// ```
-    /// let v = vec!["hello", "world"];
-    ///
-    /// let s: String = v.connect(" ");
-    ///
-    /// println!("{}", s); // prints "hello world"
+    /// assert_eq!(["hello", "world"].connect(" "), "hello world");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn connect(&self, sep: &T) -> U;
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 33de6b79736..935648099a7 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1777,6 +1777,11 @@ impl<T> Iterator for IntoIter<T> {
         let exact = diff / (if size == 0 {1} else {size});
         (exact, Some(exact))
     }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.size_hint().0
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs
index 8a8da0d9faa..ac9cf198d67 100644
--- a/src/libcollectionstest/vec.rs
+++ b/src/libcollectionstest/vec.rs
@@ -542,6 +542,11 @@ fn test_split_off() {
     assert_eq!(vec2, [5, 6]);
 }
 
+#[test]
+fn test_into_iter_count() {
+    assert_eq!(vec![1, 2, 3].into_iter().count(), 3);
+}
+
 #[bench]
 fn bench_new(b: &mut Bencher) {
     b.iter(|| {
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 9ff447a87f1..c717b608a24 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -144,7 +144,7 @@
 use clone::Clone;
 use cmp::PartialEq;
 use default::Default;
-use marker::{Copy, Send, Sync};
+use marker::{Copy, Send, Sync, Sized};
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{None, Some};
@@ -266,9 +266,9 @@ impl<T:PartialEq + Copy> PartialEq for Cell<T> {
 ///
 /// See the [module-level documentation](index.html) for more.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RefCell<T> {
-    value: UnsafeCell<T>,
+pub struct RefCell<T: ?Sized> {
     borrow: Cell<BorrowFlag>,
+    value: UnsafeCell<T>,
 }
 
 /// An enumeration of values returned from the `state` method on a `RefCell<T>`.
@@ -328,7 +328,9 @@ impl<T> RefCell<T> {
         debug_assert!(self.borrow.get() == UNUSED);
         unsafe { self.value.into_inner() }
     }
+}
 
+impl<T: ?Sized> RefCell<T> {
     /// Query the current state of this `RefCell`
     ///
     /// The returned value can be dispatched on to determine if a call to
@@ -449,7 +451,7 @@ impl<T> RefCell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T> Send for RefCell<T> where T: Send {}
+unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone> Clone for RefCell<T> {
@@ -469,7 +471,7 @@ impl<T:Default> Default for RefCell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: PartialEq> PartialEq for RefCell<T> {
+impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> {
     #[inline]
     fn eq(&self, other: &RefCell<T>) -> bool {
         *self.borrow() == *other.borrow()
@@ -519,7 +521,7 @@ impl<'b> Clone for BorrowRef<'b> {
 ///
 /// See the [module-level documentation](index.html) for more.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Ref<'b, T:'b> {
+pub struct Ref<'b, T: ?Sized + 'b> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
     _value: &'b T,
@@ -527,7 +529,7 @@ pub struct Ref<'b, T:'b> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, T> Deref for Ref<'b, T> {
+impl<'b, T: ?Sized> Deref for Ref<'b, T> {
     type Target = T;
 
     #[inline]
@@ -582,7 +584,7 @@ impl<'b> BorrowRefMut<'b> {
 ///
 /// See the [module-level documentation](index.html) for more.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RefMut<'b, T:'b> {
+pub struct RefMut<'b, T: ?Sized + 'b> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
     _value: &'b mut T,
@@ -590,7 +592,7 @@ pub struct RefMut<'b, T:'b> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, T> Deref for RefMut<'b, T> {
+impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
     type Target = T;
 
     #[inline]
@@ -600,7 +602,7 @@ impl<'b, T> Deref for RefMut<'b, T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, T> DerefMut for RefMut<'b, T> {
+impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
     #[inline]
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         self._value
@@ -633,7 +635,7 @@ impl<'b, T> DerefMut for RefMut<'b, T> {
 /// recommended to access its fields directly, `get` should be used instead.
 #[lang="unsafe_cell"]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct UnsafeCell<T> {
+pub struct UnsafeCell<T: ?Sized> {
     /// Wrapped value
     ///
     /// This field should not be accessed directly, it is made public for static
@@ -642,7 +644,7 @@ pub struct UnsafeCell<T> {
     pub value: T,
 }
 
-impl<T> !Sync for UnsafeCell<T> {}
+impl<T: ?Sized> !Sync for UnsafeCell<T> {}
 
 impl<T> UnsafeCell<T> {
     /// Constructs a new instance of `UnsafeCell` which will wrap the specified
@@ -664,7 +666,12 @@ impl<T> UnsafeCell<T> {
         UnsafeCell { value: value }
     }
 
-    /// Gets a mutable pointer to the wrapped value.
+    /// Unwraps the value.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because there is no guarantee that this or other threads are
+    /// currently inspecting the inner value.
     ///
     /// # Examples
     ///
@@ -673,22 +680,15 @@ impl<T> UnsafeCell<T> {
     ///
     /// let uc = UnsafeCell::new(5);
     ///
-    /// let five = uc.get();
+    /// let five = unsafe { uc.into_inner() };
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get(&self) -> *mut T {
-        // FIXME(#23542) Replace with type ascription.
-        #![allow(trivial_casts)]
-        &self.value as *const T as *mut T
-    }
+    pub unsafe fn into_inner(self) -> T { self.value }
+}
 
-    /// Unwraps the value.
-    ///
-    /// # Unsafety
-    ///
-    /// This function is unsafe because there is no guarantee that this or other threads are
-    /// currently inspecting the inner value.
+impl<T: ?Sized> UnsafeCell<T> {
+    /// Gets a mutable pointer to the wrapped value.
     ///
     /// # Examples
     ///
@@ -697,9 +697,14 @@ impl<T> UnsafeCell<T> {
     ///
     /// let uc = UnsafeCell::new(5);
     ///
-    /// let five = unsafe { uc.into_inner() };
+    /// let five = uc.get();
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn into_inner(self) -> T { self.value }
+    pub fn get(&self) -> *mut T {
+        // FIXME(#23542) Replace with type ascription.
+        #![allow(trivial_casts)]
+        &self.value as *const T as *mut T
+    }
+
 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 73778bfd038..f8a1ef96bcc 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1062,7 +1062,7 @@ impl<T: Copy + Debug> Debug for Cell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Debug> Debug for RefCell<T> {
+impl<T: ?Sized + Debug> Debug for RefCell<T> {
     fn fmt(&self, f: &mut Formatter) -> Result {
         match self.borrow_state() {
             BorrowState::Unused | BorrowState::Reading => {
@@ -1074,14 +1074,14 @@ impl<T: Debug> Debug for RefCell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, T: Debug> Debug for Ref<'b, T> {
+impl<'b, T: ?Sized + Debug> Debug for Ref<'b, T> {
     fn fmt(&self, f: &mut Formatter) -> Result {
         Debug::fmt(&**self, f)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, T: Debug> Debug for RefMut<'b, T> {
+impl<'b, T: ?Sized + Debug> Debug for RefMut<'b, T> {
     fn fmt(&self, f: &mut Formatter) -> Result {
         Debug::fmt(&*(self.deref()), f)
     }
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index be419e2cdad..a92b72e0f00 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -111,6 +111,7 @@ impl SipHasher {
         state
     }
 
+    #[inline]
     fn reset(&mut self) {
         self.length = 0;
         self.v0 = self.k0 ^ 0x736f6d6570736575;
@@ -120,6 +121,7 @@ impl SipHasher {
         self.ntail = 0;
     }
 
+    #[inline]
     fn write(&mut self, msg: &[u8]) {
         let length = msg.len();
         self.length += length;
@@ -173,6 +175,7 @@ impl Hasher for SipHasher {
         self.write(msg)
     }
 
+    #[inline]
     fn finish(&self) -> u64 {
         let mut v0 = self.v0;
         let mut v1 = self.v1;
diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs
index 85dd1039003..0bd0b66318f 100644
--- a/src/libcoretest/cell.rs
+++ b/src/libcoretest/cell.rs
@@ -159,3 +159,27 @@ fn refcell_default() {
     let cell: RefCell<u64> = Default::default();
     assert_eq!(0, *cell.borrow());
 }
+
+#[test]
+fn unsafe_cell_unsized() {
+    let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]);
+    {
+        let val: &mut [i32] = unsafe { &mut *cell.get() };
+        val[0] = 4;
+        val[2] = 5;
+    }
+    let comp: &mut [i32] = &mut [4, 2, 5];
+    assert_eq!(unsafe { &mut *cell.get() }, comp);
+}
+
+#[test]
+fn refcell_unsized() {
+    let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
+    {
+        let b = &mut *cell.borrow_mut();
+        b[0] = 4;
+        b[2] = 5;
+    }
+    let comp: &mut [i32] = &mut [4, 2, 5];
+    assert_eq!(&*cell.borrow(), comp);
+}
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 060dde02c2d..84d464e8f07 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -210,6 +210,7 @@ use trans::consts;
 use trans::datum::*;
 use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
 use trans::expr::{self, Dest};
+use trans::monomorphize;
 use trans::tvec;
 use trans::type_of;
 use middle::ty::{self, Ty};
@@ -1076,9 +1077,39 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) {
         let repr = adt::represent_type(bcx.ccx(), left_ty);
         let arg_count = adt::num_args(&*repr, 0);
-        let field_vals: Vec<ValueRef> = (0..arg_count).map(|ix|
-            adt::trans_field_ptr(bcx, &*repr, val, 0, ix)
+        let (arg_count, struct_val) = if type_is_sized(bcx.tcx(), left_ty) {
+            (arg_count, val)
+        } else {
+            // For an unsized ADT (i.e. DST struct), we need to treat
+            // the last field specially: instead of simply passing a
+            // ValueRef pointing to that field, as with all the others,
+            // we skip it and instead construct a 'fat ptr' below.
+            (arg_count - 1, Load(bcx, expr::get_dataptr(bcx, val)))
+        };
+        let mut field_vals: Vec<ValueRef> = (0..arg_count).map(|ix|
+            adt::trans_field_ptr(bcx, &*repr, struct_val, 0, ix)
         ).collect();
+
+        match left_ty.sty {
+            ty::ty_struct(def_id, substs) if !type_is_sized(bcx.tcx(), left_ty) => {
+                // The last field is technically unsized but
+                // since we can only ever match that field behind
+                // a reference we construct a fat ptr here.
+                let fields = ty::lookup_struct_fields(bcx.tcx(), def_id);
+                let unsized_ty = fields.iter().last().map(|field| {
+                    let fty = ty::lookup_field_type(bcx.tcx(), def_id, field.id, substs);
+                    monomorphize::normalize_associated_type(bcx.tcx(), &fty)
+                }).unwrap();
+                let llty = type_of::type_of(bcx.ccx(), unsized_ty);
+                let scratch = alloca_no_lifetime(bcx, llty, "__struct_field_fat_ptr");
+                let data = adt::trans_field_ptr(bcx, &*repr, struct_val, 0, arg_count);
+                let len = Load(bcx, expr::get_len(bcx, val));
+                Store(bcx, data, expr::get_dataptr(bcx, scratch));
+                Store(bcx, len, expr::get_len(bcx, scratch));
+                field_vals.push(scratch);
+            }
+            _ => {}
+        }
         Some(field_vals)
     } else if any_uniq_pat(m, col) || any_region_pat(m, col) {
         Some(vec!(Load(bcx, val)))
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index ec130e8233a..f82c1653be1 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1600,6 +1600,7 @@ impl RandomState {
            reason = "hashing an hash maps may be altered")]
 impl HashState for RandomState {
     type Hasher = SipHasher;
+    #[inline]
     fn hasher(&self) -> SipHasher {
         SipHasher::new_with_keys(self.k0, self.k1)
     }
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 9fd69840f7f..bd0408b21d2 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -113,10 +113,13 @@ impl Ipv4Addr {
 
     /// Returns true if the address appears to be globally routable.
     ///
-    /// Non-globally-routable networks include the private networks (10.0.0.0/8,
-    /// 172.16.0.0/12 and 192.168.0.0/16), the loopback network (127.0.0.0/8),
-    /// the link-local network (169.254.0.0/16), the broadcast address (255.255.255.255/32) and
-    /// the test networks used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24).
+    /// The following return false:
+    ///
+    /// - private address (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16)
+    /// - the loopback address (127.0.0.0/8)
+    /// - the link-local address (169.254.0.0/16)
+    /// - the broadcast address (255.255.255.255/32)
+    /// - test addresses used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24)
     pub fn is_global(&self) -> bool {
         !self.is_private() && !self.is_loopback() && !self.is_link_local() &&
         !self.is_broadcast() && !self.is_documentation()
@@ -284,9 +287,11 @@ impl Ipv6Addr {
 
     /// Returns true if the address appears to be globally routable.
     ///
-    /// Non-globally-routable networks include the loopback address; the
-    /// link-local, site-local, and unique local unicast addresses; and the
-    /// interface-, link-, realm-, admin- and site-local multicast addresses.
+    /// The following return false:
+    ///
+    /// - the loopback address
+    /// - link-local, site-local, and unique local unicast addresses
+    /// - interface-, link-, realm-, admin- and site-local multicast addresses
     pub fn is_global(&self) -> bool {
         match self.multicast_scope() {
             Some(Ipv6MulticastScope::Global) => true,
@@ -315,9 +320,12 @@ impl Ipv6Addr {
 
     /// Returns true if the address is a globally routable unicast address.
     ///
-    /// Non-globally-routable unicast addresses include the loopback address,
-    /// the link-local addresses, the deprecated site-local addresses and the
-    /// unique local addresses.
+    /// The following return false:
+    ///
+    /// - the loopback address
+    /// - the link-local addresses
+    /// - the (deprecated) site-local addresses
+    /// - unique local addresses
     pub fn is_unicast_global(&self) -> bool {
         !self.is_multicast()
             && !self.is_loopback() && !self.is_unicast_link_local()
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 30c7407a96d..222aff9188a 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -112,7 +112,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 /// *guard += 1;
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Mutex<T> {
+pub struct Mutex<T: ?Sized> {
     // Note that this static mutex is in a *box*, not inlined into the struct
     // itself. Once a native mutex has been used once, its address can never
     // change (it can't be moved). This mutex type can be safely moved at any
@@ -124,9 +124,9 @@ pub struct Mutex<T> {
 
 // these are the only places where `T: Send` matters; all other
 // functionality works fine on a single thread.
-unsafe impl<T: Send> Send for Mutex<T> { }
+unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
 
-unsafe impl<T: Send> Sync for Mutex<T> { }
+unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
 
 /// The static mutex type is provided to allow for static allocation of mutexes.
 ///
@@ -164,7 +164,7 @@ pub struct StaticMutex {
 /// `Deref` and `DerefMut` implementations
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct MutexGuard<'a, T: 'a> {
+pub struct MutexGuard<'a, T: ?Sized + 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
     // disregard field privacy).
     __lock: &'a StaticMutex,
@@ -172,7 +172,7 @@ pub struct MutexGuard<'a, T: 'a> {
     __poison: poison::Guard,
 }
 
-impl<'a, T> !marker::Send for MutexGuard<'a, T> {}
+impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
 
 /// Static initialization of a mutex. This constant can be used to initialize
 /// other mutex constants.
@@ -192,7 +192,9 @@ impl<T> Mutex<T> {
             data: UnsafeCell::new(t),
         }
     }
+}
 
+impl<T: ?Sized> Mutex<T> {
     /// Acquires a mutex, blocking the current task until it is able to do so.
     ///
     /// This function will block the local task until it is available to acquire
@@ -245,7 +247,7 @@ impl<T> Mutex<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for Mutex<T> {
+impl<T: ?Sized> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
         // this mutex (it's up to the user to arrange for a mutex to get
@@ -255,12 +257,12 @@ impl<T> Drop for Mutex<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Debug + 'static> fmt::Debug for Mutex<T> {
+impl<T: ?Sized + fmt::Debug + 'static> fmt::Debug for Mutex<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.try_lock() {
-            Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", *guard),
+            Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", &*guard),
             Err(TryLockError::Poisoned(err)) => {
-                write!(f, "Mutex {{ data: Poisoned({:?}) }}", **err.get_ref())
+                write!(f, "Mutex {{ data: Poisoned({:?}) }}", &**err.get_ref())
             },
             Err(TryLockError::WouldBlock) => write!(f, "Mutex {{ <locked> }}")
         }
@@ -310,7 +312,7 @@ impl StaticMutex {
     }
 }
 
-impl<'mutex, T> MutexGuard<'mutex, T> {
+impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
 
     fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
            -> LockResult<MutexGuard<'mutex, T>> {
@@ -325,7 +327,7 @@ impl<'mutex, T> MutexGuard<'mutex, T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
+impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
     type Target = T;
 
     fn deref<'a>(&'a self) -> &'a T {
@@ -333,14 +335,14 @@ impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
+impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         unsafe { &mut *self.__data.get() }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Drop for MutexGuard<'a, T> {
+impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
     #[inline]
     fn drop(&mut self) {
         unsafe {
@@ -350,11 +352,11 @@ impl<'a, T> Drop for MutexGuard<'a, T> {
     }
 }
 
-pub fn guard_lock<'a, T>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
+pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
     &guard.__lock.lock
 }
 
-pub fn guard_poison<'a, T>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
+pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
     &guard.__lock.poison
 }
 
@@ -528,4 +530,16 @@ mod tests {
         let lock = arc.lock().unwrap();
         assert_eq!(*lock, 2);
     }
+
+    #[test]
+    fn test_mutex_unsized() {
+        let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
+        {
+            let b = &mut *mutex.lock().unwrap();
+            b[0] = 4;
+            b[2] = 5;
+        }
+        let comp: &[i32] = &[4, 2, 5];
+        assert_eq!(&*mutex.lock().unwrap(), comp);
+    }
 }
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index a133bb01b61..9294fb64783 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -60,13 +60,13 @@ use sys_common::rwlock as sys;
 /// } // write lock is dropped here
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RwLock<T> {
+pub struct RwLock<T: ?Sized> {
     inner: Box<StaticRwLock>,
     data: UnsafeCell<T>,
 }
 
-unsafe impl<T: Send + Sync> Send for RwLock<T> {}
-unsafe impl<T: Send + Sync> Sync for RwLock<T> {}
+unsafe impl<T: ?Sized + Send + Sync> Send for RwLock<T> {}
+unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 
 /// Structure representing a statically allocated RwLock.
 ///
@@ -111,24 +111,24 @@ pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
 /// dropped.
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RwLockReadGuard<'a, T: 'a> {
+pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
     __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
 }
 
-impl<'a, T> !marker::Send for RwLockReadGuard<'a, T> {}
+impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
 
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RwLockWriteGuard<'a, T: 'a> {
+pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
     __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
     __poison: poison::Guard,
 }
 
-impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {}
+impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {}
 
 impl<T> RwLock<T> {
     /// Creates a new instance of an `RwLock<T>` which is unlocked.
@@ -144,7 +144,9 @@ impl<T> RwLock<T> {
     pub fn new(t: T) -> RwLock<T> {
         RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) }
     }
+}
 
+impl<T: ?Sized> RwLock<T> {
     /// Locks this rwlock with shared read access, blocking the current thread
     /// until it can be acquired.
     ///
@@ -250,19 +252,19 @@ impl<T> RwLock<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for RwLock<T> {
+impl<T: ?Sized> Drop for RwLock<T> {
     fn drop(&mut self) {
         unsafe { self.inner.lock.destroy() }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
+impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.try_read() {
-            Ok(guard) => write!(f, "RwLock {{ data: {:?} }}", *guard),
+            Ok(guard) => write!(f, "RwLock {{ data: {:?} }}", &*guard),
             Err(TryLockError::Poisoned(err)) => {
-                write!(f, "RwLock {{ data: Poisoned({:?}) }}", **err.get_ref())
+                write!(f, "RwLock {{ data: Poisoned({:?}) }}", &**err.get_ref())
             },
             Err(TryLockError::WouldBlock) => write!(f, "RwLock {{ <locked> }}")
         }
@@ -341,8 +343,7 @@ impl StaticRwLock {
     }
 }
 
-impl<'rwlock, T> RwLockReadGuard<'rwlock, T> {
-
+impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
     fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
            -> LockResult<RwLockReadGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |_| {
@@ -353,8 +354,8 @@ impl<'rwlock, T> RwLockReadGuard<'rwlock, T> {
         })
     }
 }
-impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
 
+impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
     fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
            -> LockResult<RwLockWriteGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
@@ -368,33 +369,35 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'rwlock, T> Deref for RwLockReadGuard<'rwlock, T> {
+impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
+
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'rwlock, T> Deref for RwLockWriteGuard<'rwlock, T> {
+impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
+
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> {
+impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
     fn deref_mut(&mut self) -> &mut T {
         unsafe { &mut *self.__data.get() }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Drop for RwLockReadGuard<'a, T> {
+impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
     fn drop(&mut self) {
         unsafe { self.__lock.lock.read_unlock(); }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
+impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
     fn drop(&mut self) {
         self.__lock.poison.done(&self.__poison);
         unsafe { self.__lock.lock.write_unlock(); }
@@ -562,4 +565,16 @@ mod tests {
         let lock = arc.read().unwrap();
         assert_eq!(*lock, 2);
     }
+
+    #[test]
+    fn test_rwlock_unsized() {
+        let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
+        {
+            let b = &mut *rw.write().unwrap();
+            b[0] = 4;
+            b[2] = 5;
+        }
+        let comp: &[i32] = &[4, 2, 5];
+        assert_eq!(&*rw.read().unwrap(), comp);
+    }
 }
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index b68b1d28b35..9cbfe283cbd 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -139,7 +139,7 @@ impl TestDesc {
 }
 
 /// Represents a benchmark function.
-pub trait TDynBenchFn {
+pub trait TDynBenchFn: Send {
     fn run(&self, harness: &mut Bencher);
 }
 
@@ -285,7 +285,7 @@ pub struct TestOpts {
     pub filter: Option<String>,
     pub run_ignored: bool,
     pub run_tests: bool,
-    pub run_benchmarks: bool,
+    pub bench_benchmarks: bool,
     pub logfile: Option<PathBuf>,
     pub nocapture: bool,
     pub color: ColorConfig,
@@ -298,7 +298,7 @@ impl TestOpts {
             filter: None,
             run_ignored: false,
             run_tests: false,
-            run_benchmarks: false,
+            bench_benchmarks: false,
             logfile: None,
             nocapture: false,
             color: AutoColor,
@@ -377,8 +377,8 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
     let logfile = matches.opt_str("logfile");
     let logfile = logfile.map(|s| PathBuf::from(&s));
 
-    let run_benchmarks = matches.opt_present("bench");
-    let run_tests = ! run_benchmarks ||
+    let bench_benchmarks = matches.opt_present("bench");
+    let run_tests = ! bench_benchmarks ||
         matches.opt_present("test");
 
     let mut nocapture = matches.opt_present("nocapture");
@@ -400,7 +400,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         filter: filter,
         run_ignored: run_ignored,
         run_tests: run_tests,
-        run_benchmarks: run_benchmarks,
+        bench_benchmarks: bench_benchmarks,
         logfile: logfile,
         nocapture: nocapture,
         color: color,
@@ -778,7 +778,11 @@ fn run_tests<F>(opts: &TestOpts,
                 mut callback: F) -> io::Result<()> where
     F: FnMut(TestEvent) -> io::Result<()>,
 {
-    let filtered_tests = filter_tests(opts, tests);
+    let mut filtered_tests = filter_tests(opts, tests);
+    if !opts.bench_benchmarks {
+        filtered_tests = convert_benchmarks_to_tests(filtered_tests);
+    }
+
     let filtered_descs = filtered_tests.iter()
                                        .map(|t| t.desc.clone())
                                        .collect();
@@ -824,13 +828,15 @@ fn run_tests<F>(opts: &TestOpts,
         pending -= 1;
     }
 
-    // All benchmarks run at the end, in serial.
-    // (this includes metric fns)
-    for b in filtered_benchs_and_metrics {
-        try!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
-        run_test(opts, !opts.run_benchmarks, b, tx.clone());
-        let (test, result, stdout) = rx.recv().unwrap();
-        try!(callback(TeResult(test, result, stdout)));
+    if opts.bench_benchmarks {
+        // All benchmarks run at the end, in serial.
+        // (this includes metric fns)
+        for b in filtered_benchs_and_metrics {
+            try!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
+            run_test(opts, false, b, tx.clone());
+            let (test, result, stdout) = rx.recv().unwrap();
+            try!(callback(TeResult(test, result, stdout)));
+        }
     }
     Ok(())
 }
@@ -893,6 +899,22 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
     filtered
 }
 
+pub fn convert_benchmarks_to_tests(tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
+    // convert benchmarks to tests, if we're not benchmarking them
+    tests.into_iter().map(|x| {
+        let testfn = match x.testfn {
+            DynBenchFn(bench) => {
+                DynTestFn(Box::new(move || bench::run_once(|b| bench.run(b))))
+            }
+            StaticBenchFn(benchfn) => {
+                DynTestFn(Box::new(move || bench::run_once(|b| benchfn(b))))
+            }
+            f => f
+        };
+        TestDescAndFn { desc: x.desc, testfn: testfn }
+    }).collect()
+}
+
 pub fn run_test(opts: &TestOpts,
                 force_ignore: bool,
                 test: TestDescAndFn,
@@ -1159,6 +1181,15 @@ pub mod bench {
             mb_s: mb_s as usize
         }
     }
+
+    pub fn run_once<F>(f: F) where F: FnOnce(&mut Bencher) {
+        let mut bs = Bencher {
+            iterations: 0,
+            dur: Duration::nanoseconds(0),
+            bytes: 0
+        };
+        bs.bench_n(1, f);
+    }
 }
 
 #[cfg(test)]
diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs
index fca74e457c2..8c13ff70515 100644
--- a/src/test/compile-fail/bad-sized.rs
+++ b/src/test/compile-fail/bad-sized.rs
@@ -8,14 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::cell::RefCell;
-
 trait Trait {}
 
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
     //~^ ERROR the trait `core::marker::Sized` is not implemented
     //~^^ ERROR the trait `core::marker::Sized` is not implemented
-    let x: Vec<Box<RefCell<Trait + Sized>>> = Vec::new();
-    //~^ ERROR the trait `core::marker::Sized` is not implemented
 }
diff --git a/src/test/run-pass/issue-23261.rs b/src/test/run-pass/issue-23261.rs
new file mode 100644
index 00000000000..fc806f5429a
--- /dev/null
+++ b/src/test/run-pass/issue-23261.rs
@@ -0,0 +1,70 @@
+// Copyright 2015 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.
+
+// Matching on a DST struct should not trigger an LLVM assertion.
+
+struct Foo<T: ?Sized> {
+    a: i32,
+    inner: T
+}
+
+trait Get {
+    fn get(&self) -> i32;
+}
+
+impl Get for i32 {
+    fn get(&self) -> i32 {
+        *self
+    }
+}
+
+fn check_val(val: &Foo<[u8]>) {
+    match *val {
+        Foo { a, .. } => {
+            assert_eq!(a, 32);
+        }
+    }
+}
+
+fn check_dst_val(val: &Foo<[u8]>) {
+    match *val {
+        Foo { ref inner, .. } => {
+            assert_eq!(inner, [1, 2, 3]);
+        }
+    }
+}
+
+fn check_both(val: &Foo<[u8]>) {
+    match *val {
+        Foo { a, ref inner } => {
+            assert_eq!(a, 32);
+            assert_eq!(inner, [1, 2, 3]);
+        }
+    }
+}
+
+fn check_trait_obj(val: &Foo<Get>) {
+    match *val {
+        Foo { a, ref inner } => {
+            assert_eq!(a, 32);
+            assert_eq!(inner.get(), 32);
+        }
+    }
+}
+
+fn main() {
+    let foo: &Foo<[u8]> = &Foo { a: 32, inner: [1, 2, 3] };
+    check_val(foo);
+    check_dst_val(foo);
+    check_both(foo);
+
+    let foo: &Foo<Get> = &Foo { a: 32, inner: 32 };
+    check_trait_obj(foo);
+}
diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs
index d90b88cbfd5..cff46f80cf4 100644
--- a/src/test/run-pass/out-of-stack.rs
+++ b/src/test/run-pass/out-of-stack.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // ignore-android: FIXME (#20004)
+// ignore-musl
 
 #![feature(asm)]