about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-27 23:15:17 +0000
committerbors <bors@rust-lang.org>2015-02-27 23:15:17 +0000
commite233987ce1de88a48db2ce612019ba644d3cf5dd (patch)
treef776ae018199c9ff2350a29dc569630f64455f87
parentbd0d8e47e53f25bbd50418a0f117973c366c1b08 (diff)
parentbde4c1d6fbefcd914a06b5eab6ef6f9a6f26f271 (diff)
downloadrust-e233987ce1de88a48db2ce612019ba644d3cf5dd.tar.gz
rust-e233987ce1de88a48db2ce612019ba644d3cf5dd.zip
Auto merge of #22860 - Manishearth:rollup, r=alexcrichton
Passes check-stage1, check-stage2
-rw-r--r--src/doc/reference.md15
-rw-r--r--src/doc/trpl/hello-cargo.md66
-rw-r--r--src/liballoc/heap.rs2
-rw-r--r--src/libcollections/slice.rs4
-rw-r--r--src/libcollections/vec.rs4
-rw-r--r--src/libcore/intrinsics.rs7
-rw-r--r--src/libcore/iter.rs9
-rw-r--r--src/libcore/marker.rs8
-rw-r--r--src/libcore/result.rs4
-rw-r--r--src/libcore/str/mod.rs1
-rw-r--r--src/libcoretest/result.rs4
-rw-r--r--src/libcoretest/slice.rs6
-rw-r--r--src/librand/reseeding.rs6
-rw-r--r--src/librustc/lint/builtin.rs5
-rw-r--r--src/librustc/middle/astconv_util.rs3
-rw-r--r--src/librustc/middle/stability.rs121
-rw-r--r--src/librustc/middle/ty.rs5
-rw-r--r--src/librustc_privacy/lib.rs10
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_trans/trans/_match.rs1
-rw-r--r--src/librustc_trans/trans/callee.rs2
-rw-r--r--src/librustc_trans/trans/cleanup.rs8
-rw-r--r--src/librustc_trans/trans/common.rs43
-rw-r--r--src/librustc_trans/trans/controlflow.rs2
-rw-r--r--src/librustc_trans/trans/datum.rs5
-rw-r--r--src/librustc_trans/trans/expr.rs6
-rw-r--r--src/librustc_trans/trans/glue.rs14
-rw-r--r--src/librustc_trans/trans/intrinsic.rs5
-rw-r--r--src/librustc_trans/trans/meth.rs2
-rw-r--r--src/librustc_trans/trans/tvec.rs3
-rw-r--r--src/librustc_typeck/astconv.rs23
-rw-r--r--src/libserialize/json.rs2
-rw-r--r--src/libstd/io/cursor.rs12
-rw-r--r--src/libstd/old_io/mem.rs1
-rw-r--r--src/libstd/sync/mpsc/mod.rs2
-rw-r--r--src/libstd/sys/unix/fs.rs15
-rw-r--r--src/libstd/sys/unix/process2.rs1
-rw-r--r--src/libstd/sys/windows/time.rs27
-rw-r--r--src/libstd/thread_local/mod.rs2
-rw-r--r--src/libsyntax/ast_util.rs8
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs8
-rw-r--r--src/libtest/lib.rs17
-rw-r--r--src/rustbook/book.rs8
-rw-r--r--src/test/auxiliary/lint_stability.rs24
-rw-r--r--src/test/auxiliary/lint_stability_fields.rs60
-rw-r--r--src/test/auxiliary/static-methods-crate.rs6
-rw-r--r--src/test/bench/task-perf-alloc-unwind.rs10
-rw-r--r--src/test/compile-fail/lint-stability-fields.rs346
-rw-r--r--src/test/compile-fail/lint-stability.rs12
-rw-r--r--src/test/compile-fail/unused-macro-with-bad-frag-spec.rs17
-rw-r--r--src/test/compile-fail/unused-macro-with-follow-violation.rs15
-rw-r--r--src/test/run-pass/deriving-primitive.rs6
-rw-r--r--src/test/run-pass/issue-17216.rs4
-rw-r--r--src/test/run-pass/issue-21721.rs17
-rw-r--r--src/test/run-pass/issue-22536-copy-mustnt-zero.rs34
-rw-r--r--src/test/run-pass/match-with-ret-arm.rs4
-rw-r--r--src/test/run-pass/traits-issue-22655.rs29
57 files changed, 952 insertions, 131 deletions
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 781b40be768..87130c08991 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -302,7 +302,7 @@ nonzero_dec: '1' | '2' | '3' | '4'
 
 A _character literal_ is a single Unicode character enclosed within two
 `U+0027` (single-quote) characters, with the exception of `U+0027` itself,
-which must be _escaped_ by a preceding U+005C character (`\`).
+which must be _escaped_ by a preceding `U+005C` character (`\`).
 
 ##### String literals
 
@@ -311,6 +311,19 @@ A _string literal_ is a sequence of any Unicode characters enclosed within two
 which must be _escaped_ by a preceding `U+005C` character (`\`), or a _raw
 string literal_.
 
+A multi-line string literal may be defined by terminating each line with a
+`U+005C` character (`\`) immediately before the newline. This causes the
+`U+005C` character, the newline, and all whitespace at the beginning of the
+next line to be ignored.
+
+```rust
+let a = "foobar";
+let b = "foo\
+         bar";
+
+assert_eq!(a,b);
+```
+
 ##### Character escapes
 
 Some additional _escapes_ are available in either character or non-raw string
diff --git a/src/doc/trpl/hello-cargo.md b/src/doc/trpl/hello-cargo.md
index 5eb6cd7c5cd..587da69d4a6 100644
--- a/src/doc/trpl/hello-cargo.md
+++ b/src/doc/trpl/hello-cargo.md
@@ -18,13 +18,15 @@ the Cargo
 README](https://github.com/rust-lang/cargo#installing-cargo-from-nightlies)
 for specific instructions about installing it.
 
+## Converting to Cargo
+
 Let's convert Hello World to Cargo.
 
 To Cargo-ify our project, we need to do two things: Make a `Cargo.toml`
 configuration file, and put our source file in the right place. Let's
 do that part first:
 
-```{bash}
+```bash
 $ mkdir src
 $ mv main.rs src/main.rs
 ```
@@ -36,7 +38,7 @@ place for everything, and everything in its place.
 
 Next, our configuration file:
 
-```{bash}
+```bash
 $ editor Cargo.toml
 ```
 
@@ -73,7 +75,7 @@ well as what it is named.
 
 Once you have this file in place, we should be ready to build! Try this:
 
-```{bash}
+```bash
 $ cargo build
    Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
 $ ./target/hello_world
@@ -103,6 +105,62 @@ That's it! We've successfully built `hello_world` with Cargo. Even though our
 program is simple, it's using much of the real tooling that you'll use for the
 rest of your Rust career.
 
+## A New Project
+
+You don't have to go through this whole process every time you want to start a new
+project! Cargo has the ability to make a bare-bones project directory in which you
+can start developing right away.
+
+To start a new project with Cargo, use `cargo new`:
+
+```bash
+$ cargo new hello_world --bin
+```
+
+We're passing `--bin` because we're making a binary program: if we
+were making a library, we'd leave it off.
+
+Let's check out what Cargo has generated for us:
+
+```bash
+$ cd hello_world
+$ tree .
+.
+├── Cargo.toml
+└── src
+    └── main.rs
+
+1 directory, 2 files
+```
+
+If you don't have the `tree` command, you can probably get it from your distro's package
+manager. It's not necessary, but it's certainly useful.
+
+This is all we need to get started. First, let's check out `Cargo.toml`:
+
+```toml
+[package]
+
+name = "hello_world"
+version = "0.0.1"
+authors = ["Your Name <you@example.com>"]
+```
+
+Cargo has populated this file with reasonable defaults based off the arguments you gave
+it and your `git` global configuration. You may notice that Cargo has also initialized
+the `hello_world` directory as a `git` repository.
+
+Here's what's in `src/main.rs`:
+
+```rust
+fn main() {
+    println!("Hello, world!");
+}
+```
+
+Cargo has generated a "Hello World!" for us, and you're ready to start coding! A
+much more in-depth guide to Cargo can be found [here](http://doc.crates.io/guide.html).
+
 Now that you've got the tools down, let's actually learn more about the Rust
 language itself. These are the basics that will serve you well through the rest
-of your time with Rust.
+of your time with Rust.
\ No newline at end of file
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index d3d86270d1e..726d5c8a23b 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -300,7 +300,7 @@ mod imp {
             libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
         } else {
             let new_ptr = allocate(size, align);
-            ptr::copy_memory(new_ptr, ptr, cmp::min(size, old_size));
+            ptr::copy(new_ptr, ptr, cmp::min(size, old_size));
             deallocate(ptr, old_size, align);
             new_ptr
         }
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index d4c53739686..a2924f8fe53 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -2663,7 +2663,7 @@ mod tests {
             let (left, right) = values.split_at_mut(2);
             {
                 let left: &[_] = left;
-                assert!(left[..left.len()] == [1, 2][]);
+                assert!(left[..left.len()] == [1, 2]);
             }
             for p in left {
                 *p += 1;
@@ -2671,7 +2671,7 @@ mod tests {
 
             {
                 let right: &[_] = right;
-                assert!(right[..right.len()] == [3, 4, 5][]);
+                assert!(right[..right.len()] == [3, 4, 5]);
             }
             for p in right {
                 *p += 2;
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index e18fa8c3082..78ab9b6ab9b 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -2093,7 +2093,7 @@ mod tests {
             let (left, right) = values.split_at_mut(2);
             {
                 let left: &[_] = left;
-                assert!(&left[..left.len()] == &[1, 2][]);
+                assert!(&left[..left.len()] == &[1, 2]);
             }
             for p in left {
                 *p += 1;
@@ -2101,7 +2101,7 @@ mod tests {
 
             {
                 let right: &[_] = right;
-                assert!(&right[..right.len()] == &[3, 4, 5][]);
+                assert!(&right[..right.len()] == &[3, 4, 5]);
             }
             for p in right {
                 *p += 2;
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index e7af0be88a0..1ca243134cc 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -241,7 +241,12 @@ extern "rust-intrinsic" {
     /// will trigger a compiler error.
     pub fn return_address() -> *const u8;
 
-    /// Returns `true` if a type requires drop glue.
+    /// Returns `true` if the actual type given as `T` requires drop
+    /// glue; returns `false` if the actual type provided for `T`
+    /// implements `Copy`.
+    ///
+    /// If the actual type neither requires drop glue nor implements
+    /// `Copy`, then may return `true` or `false`.
     pub fn needs_drop<T>() -> bool;
 
     /// Returns `true` if a type is managed (will be allocated on the local heap)
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 8f767e62678..94cc933d844 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -171,8 +171,7 @@ pub trait IteratorExt: Iterator + Sized {
         self.fold(0, |cnt, _x| cnt + 1)
     }
 
-    /// Loops through the entire iterator, returning the last element of the
-    /// iterator.
+    /// Loops through the entire iterator, returning the last element.
     ///
     /// # Examples
     ///
@@ -637,8 +636,8 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn all<F>(self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool {
-        for x in self { if !f(x) { return false; } }
+    fn all<F>(&mut self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool {
+        for x in self.by_ref() { if !f(x) { return false; } }
         true
     }
 
@@ -1637,8 +1636,6 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
         for x in self.iter.by_ref() {
             if (self.predicate)(&x) {
                 return Some(x);
-            } else {
-                continue
             }
         }
         None
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 6c934a998de..868a671b956 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -275,7 +275,13 @@ macro_rules! impls{
 /// any methods, but instead is used to gate access to data.
 ///
 /// FIXME. Better documentation needed here!
-pub trait MarkerTrait : PhantomFn<Self> { }
+pub trait MarkerTrait : PhantomFn<Self,Self> { }
+//                                    ~~~~~ <-- FIXME(#22806)?
+//
+// Marker trait has been made invariant so as to avoid inf recursion,
+// but we should ideally solve the underlying problem. That's a bit
+// complicated.
+
 impl<T:?Sized> MarkerTrait for T { }
 
 /// `PhantomFn` is a marker trait for use with traits that contain
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index bca73782491..b8271562d2e 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -641,9 +641,9 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn or(self, res: Result<T, E>) -> Result<T, E> {
+    pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> {
         match self {
-            Ok(_) => self,
+            Ok(v) => Ok(v),
             Err(_) => res,
         }
     }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 7e51f8e8503..b354116993c 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -939,6 +939,7 @@ impl<'a, P: Pattern<'a>> Iterator for SplitStr<'a, P> {
     type Item = &'a str;
 
     #[inline]
+    #[allow(deprecated)]
     fn next(&mut self) -> Option<&'a str> {
         Iterator::next(&mut self.0)
     }
diff --git a/src/libcoretest/result.rs b/src/libcoretest/result.rs
index ab7b5101e72..10cc3ad6424 100644
--- a/src/libcoretest/result.rs
+++ b/src/libcoretest/result.rs
@@ -36,10 +36,10 @@ pub fn test_and_then() {
 
 #[test]
 pub fn test_or() {
-    assert_eq!(op1().or(Ok(667)).unwrap(), 666);
+    assert_eq!(op1().or(Ok::<_, &'static str>(667)).unwrap(), 666);
     assert_eq!(op1().or(Err("bad")).unwrap(), 666);
 
-    assert_eq!(op2().or(Ok(667)).unwrap(), 667);
+    assert_eq!(op2().or(Ok::<_, &'static str>(667)).unwrap(), 667);
     assert_eq!(op2().or(Err("bad")).unwrap_err(), "bad");
 }
 
diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs
index 46c7730cc64..fe73b3b4407 100644
--- a/src/libcoretest/slice.rs
+++ b/src/libcoretest/slice.rs
@@ -59,16 +59,16 @@ fn iterator_to_slice() {
                 let mut iter = data.iter_mut();
                 assert_eq!(&iter[..], &other_data[..]);
                 // mutability:
-                assert!(&mut iter[] == other_data);
+                assert!(&mut iter[..] == other_data);
 
                 iter.next();
                 assert_eq!(&iter[..], &other_data[1..]);
-                assert!(&mut iter[] == &mut other_data[1..]);
+                assert!(&mut iter[..] == &mut other_data[1..]);
 
                 iter.next_back();
 
                 assert_eq!(&iter[..], &other_data[1..2]);
-                assert!(&mut iter[] == &mut other_data[1..2]);
+                assert!(&mut iter[..] == &mut other_data[1..2]);
 
                 let s = iter.into_slice();
                 assert!(s == &mut other_data[1..2]);
diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs
index f4d3e975b75..06828911471 100644
--- a/src/librand/reseeding.rs
+++ b/src/librand/reseeding.rs
@@ -134,11 +134,7 @@ pub trait Reseeder<R> {
 /// Reseed an RNG using a `Default` instance. This reseeds by
 /// replacing the RNG with the result of a `Default::default` call.
 #[derive(Copy)]
-pub struct ReseedWithDefault { __hack: [u8; 0] }
-// FIXME(#21721) used to be an unit struct but that can cause
-// certain LLVM versions to abort during optimizations.
-#[allow(non_upper_case_globals)]
-pub const ReseedWithDefault: ReseedWithDefault = ReseedWithDefault { __hack: [] };
+pub struct ReseedWithDefault;
 
 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
     fn reseed(&mut self, rng: &mut R) {
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index a4f69e651df..0bd7f83b959 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1771,6 +1771,11 @@ impl LintPass for Stability {
         stability::check_path(cx.tcx, path, id,
                               &mut |id, sp, stab| self.lint(cx, id, sp, stab));
     }
+
+    fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
+        stability::check_pat(cx.tcx, pat,
+                             &mut |id, sp, stab| self.lint(cx, id, sp, stab))
+    }
 }
 
 declare_lint! {
diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs
index 17fd80ceaea..0f98b3c33fb 100644
--- a/src/librustc/middle/astconv_util.rs
+++ b/src/librustc/middle/astconv_util.rs
@@ -68,7 +68,7 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
             Some(d) => d.full_def()
         };
         if let def::DefPrimTy(nty) = def {
-            Some(prim_ty_to_ty(tcx, &path.segments[], nty))
+            Some(prim_ty_to_ty(tcx, &path.segments, nty))
         } else {
             None
         }
@@ -76,4 +76,3 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
         None
     }
 }
-
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index f67e470ee54..ddac6cc7514 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -58,8 +58,10 @@ impl<'a> Annotator<'a> {
                    attrs: &Vec<Attribute>, item_sp: Span, f: F, required: bool) where
         F: FnOnce(&mut Annotator),
     {
+        debug!("annotate(id = {:?}, attrs = {:?})", id, attrs);
         match attr::find_stability(self.sess.diagnostic(), attrs, item_sp) {
             Some(stab) => {
+                debug!("annotate: found {:?}", stab);
                 self.index.local.insert(id, stab.clone());
 
                 // Don't inherit #[stable(feature = "rust1", since = "1.0.0")]
@@ -72,6 +74,8 @@ impl<'a> Annotator<'a> {
                 }
             }
             None => {
+                debug!("annotate: not found, use_parent = {:?}, parent = {:?}",
+                       use_parent, self.parent);
                 if use_parent {
                     if let Some(stab) = self.parent.clone() {
                         self.index.local.insert(id, stab);
@@ -299,6 +303,12 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
                    &mut |id, sp, stab| self.check(id, sp, stab));
         visit::walk_path(self, path)
     }
+
+    fn visit_pat(&mut self, pat: &ast::Pat) {
+        check_pat(self.tcx, pat,
+                  &mut |id, sp, stab| self.check(id, sp, stab));
+        visit::walk_pat(self, pat)
+    }
 }
 
 /// Helper for discovering nodes to check for stability
@@ -385,6 +395,76 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
                 None => return
             }
         }
+        ast::ExprField(ref base_e, ref field) => {
+            span = field.span;
+            match ty::expr_ty_adjusted(tcx, base_e).sty {
+                ty::ty_struct(did, _) => {
+                    ty::lookup_struct_fields(tcx, did)
+                        .iter()
+                        .find(|f| f.name == field.node.name)
+                        .unwrap_or_else(|| {
+                            tcx.sess.span_bug(field.span,
+                                              "stability::check_expr: unknown named field access")
+                        })
+                        .id
+                }
+                _ => tcx.sess.span_bug(e.span,
+                                       "stability::check_expr: named field access on non-struct")
+            }
+        }
+        ast::ExprTupField(ref base_e, ref field) => {
+            span = field.span;
+            match ty::expr_ty_adjusted(tcx, base_e).sty {
+                ty::ty_struct(did, _) => {
+                    ty::lookup_struct_fields(tcx, did)
+                        .get(field.node)
+                        .unwrap_or_else(|| {
+                            tcx.sess.span_bug(field.span,
+                                              "stability::check_expr: unknown unnamed field access")
+                        })
+                        .id
+                }
+                ty::ty_tup(..) => return,
+                _ => tcx.sess.span_bug(e.span,
+                                       "stability::check_expr: unnamed field access on \
+                                        something other than a tuple or struct")
+            }
+        }
+        ast::ExprStruct(_, ref expr_fields, _) => {
+            let type_ = ty::expr_ty(tcx, e);
+            match type_.sty {
+                ty::ty_struct(did, _) => {
+                    let struct_fields = ty::lookup_struct_fields(tcx, did);
+                    // check the stability of each field that appears
+                    // in the construction expression.
+                    for field in expr_fields {
+                        let did = struct_fields
+                            .iter()
+                            .find(|f| f.name == field.ident.node.name)
+                            .unwrap_or_else(|| {
+                                tcx.sess.span_bug(field.span,
+                                                  "stability::check_expr: unknown named \
+                                                   field access")
+                            })
+                            .id;
+                        maybe_do_stability_check(tcx, did, field.span, cb);
+                    }
+
+                    // we're done.
+                    return
+                }
+                // we don't look at stability attributes on
+                // struct-like enums (yet...), but it's definitely not
+                // a bug to have construct one.
+                ty::ty_enum(..) => return,
+                _ => {
+                    tcx.sess.span_bug(e.span,
+                                      &format!("stability::check_expr: struct construction \
+                                                of non-struct, type {:?}",
+                                               type_.repr(tcx)));
+                }
+            }
+        }
         _ => return
     };
 
@@ -403,6 +483,47 @@ pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
 
 }
 
+pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
+                 cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
+    debug!("check_pat(pat = {:?})", pat);
+    if is_internal(tcx, pat.span) { return; }
+
+    let did = match ty::pat_ty_opt(tcx, pat) {
+        Some(&ty::TyS { sty: ty::ty_struct(did, _), .. }) => did,
+        Some(_) | None => return,
+    };
+    let struct_fields = ty::lookup_struct_fields(tcx, did);
+    match pat.node {
+        // Foo(a, b, c)
+        ast::PatEnum(_, Some(ref pat_fields)) => {
+            for (field, struct_field) in pat_fields.iter().zip(struct_fields.iter()) {
+                // a .. pattern is fine, but anything positional is
+                // not.
+                if let ast::PatWild(ast::PatWildMulti) = field.node {
+                    continue
+                }
+                maybe_do_stability_check(tcx, struct_field.id, field.span, cb)
+            }
+        }
+        // Foo { a, b, c }
+        ast::PatStruct(_, ref pat_fields, _) => {
+            for field in pat_fields {
+                let did = struct_fields
+                    .iter()
+                    .find(|f| f.name == field.node.ident.name)
+                    .unwrap_or_else(|| {
+                        tcx.sess.span_bug(field.span,
+                                          "stability::check_pat: unknown named field access")
+                    })
+                    .id;
+                maybe_do_stability_check(tcx, did, field.span, cb);
+            }
+        }
+        // everything else is fine.
+        _ => {}
+    }
+}
+
 fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span,
                             cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
     if !is_staged_api(tcx, id) { return  }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 78b8d4f7b1e..635ec09d339 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3896,7 +3896,7 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
                 let types_a = substs_a.types.get_slice(subst::TypeSpace);
                 let types_b = substs_b.types.get_slice(subst::TypeSpace);
 
-                let pairs = types_a.iter().zip(types_b.iter());
+                let mut pairs = types_a.iter().zip(types_b.iter());
 
                 pairs.all(|(&a, &b)| same_type(a, b))
             }
@@ -4298,6 +4298,9 @@ pub fn free_region_from_def(outlives_extent: region::DestructionScopeData,
 pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
     return node_id_to_type(cx, pat.id);
 }
+pub fn pat_ty_opt<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Option<Ty<'tcx>> {
+    return node_id_to_type_opt(cx, pat.id);
+}
 
 
 // Returns the type of an expression as a monotype.
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 436a826687e..46729988bb6 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -233,6 +233,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
             ast::ItemEnum(ref def, _) if public_first => {
                 for variant in &def.variants {
                     self.exported_items.insert(variant.node.id);
+                    self.public_items.insert(variant.node.id);
                 }
             }
 
@@ -321,6 +322,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
                     Some(id) => { self.exported_items.insert(id); }
                     None => {}
                 }
+                // fields can be public or private, so lets check
+                for field in &def.fields {
+                    let vis = match field.node.kind {
+                        ast::NamedField(_, vis) | ast::UnnamedField(vis) => vis
+                    };
+                    if vis == ast::Public {
+                        self.public_items.insert(field.node.id);
+                    }
+                }
             }
 
             ast::ItemTy(ref ty, _) if public_first => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 95523be68c3..78ce9abe07d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2985,7 +2985,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         } else {
             let msg = format!("use of undeclared trait name `{}`",
                               self.path_names_to_string(trait_path, path_depth));
-            self.resolve_error(trait_path.span, &msg[]);
+            self.resolve_error(trait_path.span, &msg);
             Err(())
         }
     }
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 9a121a8830b..48ff4c83320 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -1499,6 +1499,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                        pat: &ast::Pat)
                                        -> Block<'blk, 'tcx> {
+        let _icx = push_ctxt("create_dummy_locals");
         // create dummy memory for the variables if we have no
         // value to store into them immediately
         let tcx = bcx.tcx();
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 59fcd5492eb..4f234fac9a4 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -734,7 +734,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             };
             if !is_rust_fn ||
               type_of::return_uses_outptr(ccx, ret_ty) ||
-              common::type_needs_drop(bcx.tcx(), ret_ty) {
+              bcx.fcx.type_needs_drop(ret_ty) {
                 // Push the out-pointer if we use an out-pointer for this
                 // return type, otherwise push "undef".
                 if common::type_is_zero_size(ccx, ret_ty) {
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index a3705a67cdc..ad07f3953cc 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -386,7 +386,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                          cleanup_scope: ScopeId,
                          val: ValueRef,
                          ty: Ty<'tcx>) {
-        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !self.type_needs_drop(ty) { return; }
         let drop = box DropValue {
             is_immediate: false,
             must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
@@ -408,7 +408,8 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                                   cleanup_scope: ScopeId,
                                   val: ValueRef,
                                   ty: Ty<'tcx>) {
-        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !self.type_needs_drop(ty) { return; }
+
         let drop = box DropValue {
             is_immediate: false,
             must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
@@ -432,7 +433,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                                val: ValueRef,
                                ty: Ty<'tcx>) {
 
-        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !self.type_needs_drop(ty) { return; }
         let drop = box DropValue {
             is_immediate: true,
             must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
@@ -1007,6 +1008,7 @@ impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> {
                    bcx: Block<'blk, 'tcx>,
                    debug_loc: DebugLoc)
                    -> Block<'blk, 'tcx> {
+        let _icx = base::push_ctxt("<DropValue as Cleanup>::trans");
         let bcx = if self.is_immediate {
             glue::drop_ty_immediate(bcx, self.val, self.ty, debug_loc)
         } else {
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index d8fc6df2685..ec7ed2fe890 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -213,8 +213,43 @@ pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<
     }
 }
 
+/// If `type_needs_drop` returns true, then `ty` is definitely
+/// non-copy and *might* have a destructor attached; if it returns
+/// false, then `ty` definitely has no destructor (i.e. no drop glue).
+///
+/// (Note that this implies that if `ty` has a destructor attached,
+/// then `type_needs_drop` will definitely return `true` for `ty`.)
 pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    ty::type_contents(cx, ty).needs_drop(cx)
+    type_needs_drop_given_env(cx, ty, &ty::empty_parameter_environment(cx))
+}
+
+/// Core implementation of type_needs_drop, potentially making use of
+/// and/or updating caches held in the `param_env`.
+fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>,
+                                      ty: Ty<'tcx>,
+                                      param_env: &ty::ParameterEnvironment<'a,'tcx>) -> bool {
+    // Issue #22536: We first query type_moves_by_default.  It sees a
+    // normalized version of the type, and therefore will definitely
+    // know whether the type implements Copy (and thus needs no
+    // cleanup/drop/zeroing) ...
+    let implements_copy = !ty::type_moves_by_default(&param_env, DUMMY_SP, ty);
+
+    if implements_copy { return false; }
+
+    // ... (issue #22536 continued) but as an optimization, still use
+    // prior logic of asking if the `needs_drop` bit is set; we need
+    // not zero non-Copy types if they have no destructor.
+
+    // FIXME(#22815): Note that calling `ty::type_contents` is a
+    // conservative heuristic; it may report that `needs_drop` is set
+    // when actual type does not actually have a destructor associated
+    // with it. But since `ty` absolutely did not have the `Copy`
+    // bound attached (see above), it is sound to treat it as having a
+    // destructor (e.g. zero its memory on move).
+
+    let contents = ty::type_contents(cx, ty);
+    debug!("type_needs_drop ty={} contents={:?}", ty.repr(cx), contents);
+    contents.needs_drop(cx)
 }
 
 fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
@@ -534,6 +569,12 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
                                          self.param_substs,
                                          value)
     }
+
+    /// This is the same as `common::type_needs_drop`, except that it
+    /// may use or update caches within this `FunctionContext`.
+    pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
+        type_needs_drop_given_env(self.ccx.tcx(), ty, &self.param_env)
+    }
 }
 
 // Basic block context.  We create a block context for each basic block
diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs
index ad96c506c9d..85d0bc0319f 100644
--- a/src/librustc_trans/trans/controlflow.rs
+++ b/src/librustc_trans/trans/controlflow.rs
@@ -77,7 +77,7 @@ pub fn trans_stmt_semi<'blk, 'tcx>(cx: Block<'blk, 'tcx>, e: &ast::Expr)
                                    -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_stmt_semi");
     let ty = expr_ty(cx, e);
-    if type_needs_drop(cx.tcx(), ty) {
+    if cx.fcx.type_needs_drop(ty) {
         expr::trans_to_lvalue(cx, e, "stmt").bcx
     } else {
         expr::trans_into(cx, e, expr::Ignore)
diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs
index 8262dbf55dd..6ca71254868 100644
--- a/src/librustc_trans/trans/datum.rs
+++ b/src/librustc_trans/trans/datum.rs
@@ -311,7 +311,8 @@ impl KindOps for Lvalue {
                               val: ValueRef,
                               ty: Ty<'tcx>)
                               -> Block<'blk, 'tcx> {
-        if type_needs_drop(bcx.tcx(), ty) {
+        let _icx = push_ctxt("<Lvalue as KindOps>::post_store");
+        if bcx.fcx.type_needs_drop(ty) {
             // cancel cleanup of affine values by zeroing out
             let () = zero_mem(bcx, val, ty);
             bcx
@@ -656,7 +657,7 @@ impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> {
     /// scalar-ish (like an int or a pointer) which (1) does not require drop glue and (2) is
     /// naturally passed around by value, and not by reference.
     pub fn to_llscalarish<'blk>(self, bcx: Block<'blk, 'tcx>) -> ValueRef {
-        assert!(!type_needs_drop(bcx.tcx(), self.ty));
+        assert!(!bcx.fcx.type_needs_drop(self.ty));
         assert!(self.appropriate_rvalue_mode(bcx.ccx()) == ByValue);
         if self.kind.is_by_ref() {
             load_ty(bcx, self.val, self.ty)
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 5cc1baf66c6..27f9b9506a5 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -974,7 +974,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
             let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &**dst, "assign"));
 
-            if type_needs_drop(bcx.tcx(), dst_datum.ty) {
+            if bcx.fcx.type_needs_drop(dst_datum.ty) {
                 // If there are destructors involved, make sure we
                 // are copying from an rvalue, since that cannot possible
                 // alias an lvalue. We are concerned about code like:
@@ -1498,7 +1498,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         assert_eq!(discr, 0);
 
         match ty::expr_kind(bcx.tcx(), &*base.expr) {
-            ty::RvalueDpsExpr | ty::RvalueDatumExpr if !type_needs_drop(bcx.tcx(), ty) => {
+            ty::RvalueDpsExpr | ty::RvalueDatumExpr if !bcx.fcx.type_needs_drop(ty) => {
                 bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
             },
             ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr"),
@@ -2116,7 +2116,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Evaluate LHS (destination), which should be an lvalue
     let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
-    assert!(!type_needs_drop(bcx.tcx(), dst_datum.ty));
+    assert!(!bcx.fcx.type_needs_drop(dst_datum.ty));
     let dst_ty = dst_datum.ty;
     let dst = load_ty(bcx, dst_datum.val, dst_datum.ty);
 
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index c14683aeade..9491c8377a6 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -99,6 +99,16 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     if !type_is_sized(tcx, t) {
         return t
     }
+
+    // FIXME (#22815): note that type_needs_drop conservatively
+    // approximates in some cases and may say a type expression
+    // requires drop glue when it actually does not.
+    //
+    // (In this case it is not clear whether any harm is done, i.e.
+    // erroneously returning `t` in some cases where we could have
+    // returned `tcx.types.i8` does not appear unsound. The impact on
+    // code quality is unknown at this time.)
+
     if !type_needs_drop(tcx, t) {
         return tcx.types.i8;
     }
@@ -125,7 +135,7 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // NB: v is an *alias* of type t here, not a direct value.
     debug!("drop_ty(t={})", t.repr(bcx.tcx()));
     let _icx = push_ctxt("drop_ty");
-    if type_needs_drop(bcx.tcx(), t) {
+    if bcx.fcx.type_needs_drop(t) {
         let ccx = bcx.ccx();
         let glue = get_drop_glue(ccx, t);
         let glue_type = get_drop_glue_type(ccx, t);
@@ -480,7 +490,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
         },
         _ => {
             assert!(type_is_sized(bcx.tcx(), t));
-            if type_needs_drop(bcx.tcx(), t) && ty::type_is_structural(t) {
+            if bcx.fcx.type_needs_drop(t) && ty::type_is_structural(t) {
                 iter_structural_ty(bcx,
                                    v0,
                                    t,
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index 993c9eae45b..54644c92869 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -156,6 +156,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let ccx = fcx.ccx;
     let tcx = bcx.tcx();
 
+    let _icx = push_ctxt("trans_intrinsic_call");
+
     let ret_ty = match callee_ty.sty {
         ty::ty_bare_fn(_, ref f) => {
             ty::erase_late_bound_regions(bcx.tcx(), &f.sig.output())
@@ -376,7 +378,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         }
         (_, "needs_drop") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
-            C_bool(ccx, type_needs_drop(ccx.tcx(), tp_ty))
+
+            C_bool(ccx, bcx.fcx.type_needs_drop(tp_ty))
         }
         (_, "owns_managed") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 3411f12886d..4423cd27744 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -454,7 +454,7 @@ fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let self_datum = unpack_datum!(
         bcx, expr::trans(bcx, self_expr));
 
-    let llval = if type_needs_drop(bcx.tcx(), self_datum.ty) {
+    let llval = if bcx.fcx.type_needs_drop(self_datum.ty) {
         let self_datum = unpack_datum!(
             bcx, self_datum.to_rvalue_datum(bcx, "trait_callee"));
 
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index d3acd23e641..a5c3923336a 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -53,11 +53,10 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let not_null = IsNotNull(bcx, vptr);
     with_cond(bcx, not_null, |bcx| {
         let ccx = bcx.ccx();
-        let tcx = bcx.tcx();
         let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
 
         let dataptr = get_dataptr(bcx, vptr);
-        let bcx = if type_needs_drop(tcx, unit_ty) {
+        let bcx = if bcx.fcx.type_needs_drop(unit_ty) {
             let len = get_len(bcx, vptr);
             iter_vec_raw(bcx,
                          dataptr,
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 844635117b5..d9dc050aebf 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -991,6 +991,17 @@ fn trait_ref_to_object_type<'tcx>(this: &AstConv<'tcx>,
     result
 }
 
+fn report_ambiguous_associated_type(tcx: &ty::ctxt,
+                                    span: Span,
+                                    type_str: &str,
+                                    trait_str: &str,
+                                    name: &str) {
+    span_err!(tcx.sess, span, E0223,
+              "ambiguous associated type; specify the type using the syntax \
+               `<{} as {}>::{}`",
+              type_str, trait_str, name);
+}
+
 fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                    span: Span,
                                    ty: Ty<'tcx>,
@@ -1011,10 +1022,8 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
     let ty_param_node_id = if is_param {
         ty_path_def.local_node_id()
     } else {
-        span_err!(tcx.sess, span, E0223,
-                "ambiguous associated type; specify the type using the syntax \
-                `<{} as Trait>::{}`",
-                ty.user_string(tcx), token::get_name(assoc_name));
+        report_ambiguous_associated_type(
+            tcx, span, &ty.user_string(tcx), "Trait", &token::get_name(assoc_name));
         return (tcx.types.err, ty_path_def);
     };
 
@@ -1109,10 +1118,8 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
         ty
     } else {
         let path_str = ty::item_path_str(tcx, trait_def_id);
-        span_err!(tcx.sess, span, E0223,
-                  "ambiguous associated type; specify the type using the syntax \
-                   `<Type as {}>::{}`",
-                   path_str, &token::get_ident(item_segment.identifier));
+        report_ambiguous_associated_type(
+            tcx, span, "Type", &path_str, &token::get_ident(item_segment.identifier));
         return tcx.types.err;
     };
 
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 05d4e0f59fe..14930f91c91 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -3945,9 +3945,7 @@ mod tests {
 
     #[test]
     fn test_encode_hashmap_with_arbitrary_key() {
-        use std::old_io::Writer;
         use std::collections::HashMap;
-        use std::fmt;
         #[derive(PartialEq, Eq, Hash, RustcEncodable)]
         struct ArbitraryType(uint);
         let mut hm: HashMap<ArbitraryType, bool> = HashMap::new();
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index f6cb4a8c9f3..b1779587528 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -173,7 +173,7 @@ mod tests {
         assert_eq!(writer.write(&[1, 2, 3]), Ok(3));
         assert_eq!(writer.write(&[4, 5, 6, 7]), Ok(4));
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
     }
 
     #[test]
@@ -369,28 +369,28 @@ mod tests {
         assert_eq!(writer.write(&[4, 5, 6, 7]), Ok(4));
         assert_eq!(writer.position(), 8);
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
         assert_eq!(writer.seek(SeekFrom::Start(0)), Ok(0));
         assert_eq!(writer.position(), 0);
         assert_eq!(writer.write(&[3, 4]), Ok(2));
         let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
         assert_eq!(writer.seek(SeekFrom::Current(1)), Ok(3));
         assert_eq!(writer.write(&[0, 1]), Ok(2));
         let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
         assert_eq!(writer.seek(SeekFrom::End(-1)), Ok(7));
         assert_eq!(writer.write(&[1, 2]), Ok(2));
         let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
         assert_eq!(writer.seek(SeekFrom::End(1)), Ok(10));
         assert_eq!(writer.write(&[1]), Ok(1));
         let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
     }
 
     #[test]
diff --git a/src/libstd/old_io/mem.rs b/src/libstd/old_io/mem.rs
index c08a2c1f477..e6a8b90ea33 100644
--- a/src/libstd/old_io/mem.rs
+++ b/src/libstd/old_io/mem.rs
@@ -102,6 +102,7 @@ impl MemWriter {
 
 impl Writer for MemWriter {
     #[inline]
+    #[allow(deprecated)]
     fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
         self.buf.push_all(buf);
         Ok(())
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 7bd1f3542eb..1310d476f8e 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -384,7 +384,7 @@ impl<T> !Sync for SyncSender<T> {}
 /// contains the data being sent as a payload so it can be recovered.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, Clone, Copy)]
-pub struct SendError<T>(pub T);
+pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
 
 /// An error returned from the `recv` function on a `Receiver`.
 ///
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 1c28d629d40..71b6214460f 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -291,29 +291,14 @@ fn mkstat(stat: &libc::stat) -> FileStat {
     // FileStat times are in milliseconds
     fn mktime(secs: u64, nsecs: u64) -> u64 { secs * 1000 + nsecs / 1000000 }
 
-    #[cfg(target_os = "bitrig")]
-    fn ctime(stat: &libc::stat) -> u64 {
-      mktime(stat.st_ctim.tv_sec as u64, stat.st_ctim.tv_nsec as u64)
-    }
-    #[cfg(not(target_os = "bitrig"))]
     fn ctime(stat: &libc::stat) -> u64 {
       mktime(stat.st_ctime as u64, stat.st_ctime_nsec as u64)
     }
 
-    #[cfg(target_os = "bitrig")]
-    fn atime(stat: &libc::stat) -> u64 {
-      mktime(stat.st_atim.tv_sec as u64, stat.st_atim.tv_nsec as u64)
-    }
-    #[cfg(not(target_os = "bitrig"))]
     fn atime(stat: &libc::stat) -> u64 {
       mktime(stat.st_atime as u64, stat.st_atime_nsec as u64)
     }
 
-    #[cfg(target_os = "bitrig")]
-    fn mtime(stat: &libc::stat) -> u64 {
-      mktime(stat.st_mtim.tv_sec as u64, stat.st_mtim.tv_nsec as u64)
-    }
-    #[cfg(not(target_os = "bitrig"))]
     fn mtime(stat: &libc::stat) -> u64 {
       mktime(stat.st_mtime as u64, stat.st_mtime_nsec as u64)
     }
diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs
index b7a1b002f55..a7d0a864a08 100644
--- a/src/libstd/sys/unix/process2.rs
+++ b/src/libstd/sys/unix/process2.rs
@@ -439,6 +439,7 @@ fn translate_status(status: c_int) -> ExitStatus {
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
+              target_os = "bitrig",
               target_os = "openbsd"))]
     mod imp {
         pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 }
diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs
index 20ceff0aa69..209460df10b 100644
--- a/src/libstd/sys/windows/time.rs
+++ b/src/libstd/sys/windows/time.rs
@@ -12,6 +12,8 @@ use ops::Sub;
 use time::Duration;
 use sync::{Once, ONCE_INIT};
 
+const NANOS_PER_SEC: i64 = 1_000_000_000;
+
 pub struct SteadyTime {
     t: libc::LARGE_INTEGER,
 }
@@ -24,7 +26,7 @@ impl SteadyTime {
     }
 
     pub fn ns(&self) -> u64 {
-        self.t as u64 * 1_000_000_000 / frequency() as u64
+        mul_div_i64(self.t as i64, NANOS_PER_SEC, frequency() as i64) as u64
     }
 }
 
@@ -45,6 +47,27 @@ impl<'a> Sub for &'a SteadyTime {
 
     fn sub(self, other: &SteadyTime) -> Duration {
         let diff = self.t as i64 - other.t as i64;
-        Duration::microseconds(diff * 1_000_000 / frequency() as i64)
+        Duration::nanoseconds(mul_div_i64(diff, NANOS_PER_SEC, frequency() as i64))
     }
 }
+
+// Computes (value*numer)/denom without overflow, as long as both
+// (numer*denom) and the overall result fit into i64 (which is the case
+// for our time conversions).
+fn mul_div_i64(value: i64, numer: i64, denom: i64) -> i64 {
+    let q = value / denom;
+    let r = value % denom;
+    // Decompose value as (value/denom*denom + value%denom),
+    // substitute into (value*numer)/denom and simplify.
+    // r < denom, so (denom*numer) is the upper bound of (r*numer)
+    q * numer + r * numer / denom
+}
+
+#[test]
+fn test_muldiv() {
+    assert_eq!(mul_div_i64( 1_000_000_000_001, 1_000_000_000, 1_000_000),  1_000_000_000_001_000);
+    assert_eq!(mul_div_i64(-1_000_000_000_001, 1_000_000_000, 1_000_000), -1_000_000_000_001_000);
+    assert_eq!(mul_div_i64(-1_000_000_000_001,-1_000_000_000, 1_000_000),  1_000_000_000_001_000);
+    assert_eq!(mul_div_i64( 1_000_000_000_001, 1_000_000_000,-1_000_000), -1_000_000_000_001_000);
+    assert_eq!(mul_div_i64( 1_000_000_000_001,-1_000_000_000,-1_000_000),  1_000_000_000_001_000);
+}
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index d65156dae96..764c7d730cb 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -105,10 +105,12 @@ pub struct Key<T> {
     // This is trivially devirtualizable by LLVM because we never store anything
     // to this field and rustc can declare the `static` as constant as well.
     #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
     pub inner: fn() -> &'static __impl::KeyInner<UnsafeCell<Option<T>>>,
 
     // initialization routine to invoke to create a value
     #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
     pub init: fn() -> T,
 }
 
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 79f0433761d..264e05f5c8d 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -760,13 +760,13 @@ mod test {
     #[test] fn idents_name_eq_test() {
         assert!(segments_name_eq(
             &[Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[],
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>(),
             &[Ident{name:Name(3),ctxt:104}, Ident{name:Name(78),ctxt:182}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[]));
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()));
         assert!(!segments_name_eq(
             &[Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[],
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>(),
             &[Ident{name:Name(3),ctxt:104}, Ident{name:Name(77),ctxt:182}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[]));
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()));
     }
 }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index fa6d934a457..67011ad21a6 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -334,6 +334,10 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
                 let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
                 // If T' is in the set FOLLOW(NT), continue. Else, reject.
                 match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
+                    (_, Err(msg)) => {
+                        cx.span_err(sp, &msg);
+                        continue
+                    }
                     (&Eof, _) => return Some((sp, tok.clone())),
                     (_, Ok(true)) => continue,
                     (next, Ok(false)) => {
@@ -343,10 +347,6 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
                                                  token_to_string(next)));
                         continue
                     },
-                    (_, Err(msg)) => {
-                        cx.span_err(sp, &msg);
-                        continue
-                    }
                 }
             },
             TtSequence(sp, ref seq) => {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 82c1a4b1195..7c7f1fd478a 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -506,16 +506,25 @@ impl<T: Writer> ConsoleTestState<T> {
                 if self.use_color {
                     try!(term.reset());
                 }
-                Ok(())
+                term.flush()
+            }
+            Raw(ref mut stdout) => {
+                try!(stdout.write_all(word.as_bytes()));
+                stdout.flush()
             }
-            Raw(ref mut stdout) => stdout.write_all(word.as_bytes())
         }
     }
 
     pub fn write_plain(&mut self, s: &str) -> old_io::IoResult<()> {
         match self.out {
-            Pretty(ref mut term) => term.write_all(s.as_bytes()),
-            Raw(ref mut stdout) => stdout.write_all(s.as_bytes())
+            Pretty(ref mut term) => {
+                try!(term.write_all(s.as_bytes()));
+                term.flush()
+            },
+            Raw(ref mut stdout) => {
+                try!(stdout.write_all(s.as_bytes()));
+                stdout.flush()
+            },
         }
     }
 
diff --git a/src/rustbook/book.rs b/src/rustbook/book.rs
index 3c116aa860b..8900b60d191 100644
--- a/src/rustbook/book.rs
+++ b/src/rustbook/book.rs
@@ -114,12 +114,12 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String
             }
         };
 
-        let star_idx = match line.find_str("*") { Some(i) => i, None => continue };
+        let star_idx = match line.find("*") { Some(i) => i, None => continue };
 
-        let start_bracket = star_idx + line[star_idx..].find_str("[").unwrap();
-        let end_bracket = start_bracket + line[start_bracket..].find_str("](").unwrap();
+        let start_bracket = star_idx + line[star_idx..].find("[").unwrap();
+        let end_bracket = start_bracket + line[start_bracket..].find("](").unwrap();
         let start_paren = end_bracket + 1;
-        let end_paren = start_paren + line[start_paren..].find_str(")").unwrap();
+        let end_paren = start_paren + line[start_paren..].find(")").unwrap();
 
         let given_path = &line[start_paren + 1 .. end_paren];
         let title = line[start_bracket + 1..end_bracket].to_string();
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs
index fb535eb8336..d47575403e1 100644
--- a/src/test/auxiliary/lint_stability.rs
+++ b/src/test/auxiliary/lint_stability.rs
@@ -100,14 +100,22 @@ pub trait UnstableTrait { fn dummy(&self) { } }
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedStruct { pub i: int }
+pub struct DeprecatedStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: int
+}
 #[unstable(feature = "test_feature")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedUnstableStruct { pub i: int }
+pub struct DeprecatedUnstableStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: int
+}
 #[unstable(feature = "test_feature")]
-pub struct UnstableStruct { pub i: int }
+pub struct UnstableStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: int
+}
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct StableStruct { pub i: int }
+pub struct StableStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: int
+}
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
@@ -137,14 +145,14 @@ pub enum Enum {
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedTupleStruct(pub int);
+pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
 #[unstable(feature = "test_feature")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedUnstableTupleStruct(pub int);
+pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
 #[unstable(feature = "test_feature")]
-pub struct UnstableTupleStruct(pub int);
+pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct StableTupleStruct(pub int);
+pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
 
 #[macro_export]
 macro_rules! macro_test {
diff --git a/src/test/auxiliary/lint_stability_fields.rs b/src/test/auxiliary/lint_stability_fields.rs
new file mode 100644
index 00000000000..66940ee0081
--- /dev/null
+++ b/src/test/auxiliary/lint_stability_fields.rs
@@ -0,0 +1,60 @@
+// 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.
+
+#![feature(staged_api)]
+#![staged_api]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stable {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub inherit: u8, // it's a lie (stable doesn't inherit)
+    #[unstable(feature = "test_feature")]
+    pub override1: u8,
+    #[deprecated(since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    pub override2: u8,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stable2(#[stable(feature = "rust1", since = "1.0.0")] pub u8,
+                   #[unstable(feature = "test_feature")] pub u8,
+                   #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] pub u8);
+
+#[unstable(feature = "test_feature")]
+pub struct Unstable {
+    pub inherit: u8,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub override1: u8,
+    #[deprecated(since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    pub override2: u8,
+}
+
+#[unstable(feature = "test_feature")]
+pub struct Unstable2(pub u8,
+                     #[stable(feature = "rust1", since = "1.0.0")] pub u8,
+                     #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] pub u8);
+
+#[unstable(feature = "test_feature")]
+#[deprecated(feature = "rust1", since = "1.0.0")]
+pub struct Deprecated {
+    pub inherit: u8,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub override1: u8,
+    #[unstable(feature = "test_feature")]
+    pub override2: u8,
+}
+
+#[unstable(feature = "test_feature")]
+#[deprecated(feature = "rust1", since = "1.0.0")]
+pub struct Deprecated2(pub u8,
+                       #[stable(feature = "rust1", since = "1.0.0")] pub u8,
+                       #[unstable(feature = "test_feature")] pub u8);
diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/auxiliary/static-methods-crate.rs
index d84ded25702..e61fb49add5 100644
--- a/src/test/auxiliary/static-methods-crate.rs
+++ b/src/test/auxiliary/static-methods-crate.rs
@@ -11,14 +11,12 @@
 #![crate_name="static_methods_crate"]
 #![crate_type = "lib"]
 
-use std::int;
-
 pub trait read {
     fn readMaybe(s: String) -> Option<Self>;
 }
 
-impl read for int {
-    fn readMaybe(s: String) -> Option<int> {
+impl read for isize {
+    fn readMaybe(s: String) -> Option<isize> {
         s.parse().ok()
     }
 }
diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs
index 6b412c47cd7..896b0ee57a0 100644
--- a/src/test/bench/task-perf-alloc-unwind.rs
+++ b/src/test/bench/task-perf-alloc-unwind.rs
@@ -40,9 +40,7 @@ fn run(repeat: int, depth: int) {
     }
 }
 
-// FIXME(#21721) used to be `List<()>` but that can cause
-// certain LLVM versions to abort during optimizations.
-type nillist = List<[u8; 0]>;
+type nillist = List<()>;
 
 // Filled with things that have to be unwound
 
@@ -83,11 +81,11 @@ fn recurse_or_panic(depth: int, st: Option<State>) {
             }
             Some(st) => {
                 let mut v = st.vec.clone();
-                v.push_all(&[box List::Cons([], st.vec.last().unwrap().clone())]);
+                v.push_all(&[box List::Cons((), st.vec.last().unwrap().clone())]);
                 State {
-                    unique: box List::Cons([], box *st.unique),
+                    unique: box List::Cons((), box *st.unique),
                     vec: v,
-                    res: r(box List::Cons([], st.res._l.clone())),
+                    res: r(box List::Cons((), st.res._l.clone())),
                 }
             }
         };
diff --git a/src/test/compile-fail/lint-stability-fields.rs b/src/test/compile-fail/lint-stability-fields.rs
new file mode 100644
index 00000000000..c43ff198925
--- /dev/null
+++ b/src/test/compile-fail/lint-stability-fields.rs
@@ -0,0 +1,346 @@
+// 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.
+
+// aux-build:lint_stability_fields.rs
+#![deny(deprecated)]
+#![allow(dead_code)]
+#![feature(staged_api)]
+#![staged_api]
+
+mod cross_crate {
+    extern crate lint_stability_fields;
+
+    use self::lint_stability_fields::*;
+
+    pub fn foo() {
+        let x = Stable {
+            inherit: 1,
+            override1: 2, //~ WARN use of unstable
+            override2: 3,
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+        };
+
+        let _ = x.inherit;
+        let _ = x.override1; //~ WARN use of unstable
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+
+        let Stable {
+            inherit: _,
+            override1: _, //~ WARN use of unstable
+            override2: _
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+        } = x;
+        // all fine
+        let Stable { .. } = x;
+
+        let x = Stable2(1, 2, 3);
+
+        let _ = x.0;
+        let _ = x.1; //~ WARN use of unstable
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+
+        let Stable2(_,
+                   _, //~ WARN use of unstable
+                   _)
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+            = x;
+        // all fine
+        let Stable2(..) = x;
+
+
+        let x = Unstable { //~ WARN use of unstable
+            inherit: 1, //~ WARN use of unstable
+            override1: 2,
+            override2: 3,
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+        };
+
+        let _ = x.inherit; //~ WARN use of unstable
+        let _ = x.override1;
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+
+        let Unstable { //~ WARN use of unstable
+            inherit: _, //~ WARN use of unstable
+            override1: _,
+            override2: _
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+        } = x;
+
+        let Unstable  //~ WARN use of unstable
+            // the patterns are all fine:
+            { .. } = x;
+
+
+        let x = Unstable2(1, 2, 3); //~ WARN use of unstable
+
+        let _ = x.0; //~ WARN use of unstable
+        let _ = x.1;
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+
+        let Unstable2  //~ WARN use of unstable
+            (_, //~ WARN use of unstable
+             _,
+             _)
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+            = x;
+        let Unstable2 //~ WARN use of unstable
+            // the patterns are all fine:
+            (..) = x;
+
+
+        let x = Deprecated {
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+            inherit: 1,
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+            override1: 2,
+            override2: 3, //~ WARN use of unstable
+        };
+
+        let _ = x.inherit;
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+        let _ = x.override1;
+        let _ = x.override2; //~ WARN use of unstable
+
+        let Deprecated {
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+            inherit: _,
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+            override1: _,
+            override2: _ //~ WARN use of unstable
+        } = x;
+
+        let Deprecated
+            //~^ ERROR use of deprecated item
+            //~^^ WARN use of unstable
+            // the patterns are all fine:
+            { .. } = x;
+
+        let x = Deprecated2(1, 2, 3);
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+
+        let _ = x.0;
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+        let _ = x.1;
+        let _ = x.2; //~ WARN use of unstable
+
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+            (_,
+             //~^ ERROR use of deprecated item
+             //~^^ WARN use of unstable
+             _,
+             _) //~ WARN use of unstable
+            = x;
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+        //~^^ WARN use of unstable
+            // the patterns are all fine:
+            (..) = x;
+    }
+}
+
+mod this_crate {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    struct Stable {
+        inherit: u8,
+        #[unstable(feature = "test_feature")]
+        override1: u8,
+        #[deprecated(since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        override2: u8,
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    struct Stable2(u8,
+                   #[stable(feature = "rust1", since = "1.0.0")] u8,
+                   #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] u8);
+
+    #[unstable(feature = "test_feature")]
+    struct Unstable {
+        inherit: u8,
+        #[stable(feature = "rust1", since = "1.0.0")]
+        override1: u8,
+        #[deprecated(since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        override2: u8,
+    }
+
+    #[unstable(feature = "test_feature")]
+    struct Unstable2(u8,
+                     #[stable(feature = "rust1", since = "1.0.0")] u8,
+                     #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] u8);
+
+    #[unstable(feature = "test_feature")]
+    #[deprecated(feature = "rust1", since = "1.0.0")]
+    struct Deprecated {
+        inherit: u8,
+        #[stable(feature = "rust1", since = "1.0.0")]
+        override1: u8,
+        #[unstable(feature = "test_feature")]
+        override2: u8,
+    }
+
+    #[unstable(feature = "test_feature")]
+    #[deprecated(feature = "rust1", since = "1.0.0")]
+    struct Deprecated2(u8,
+                       #[stable(feature = "rust1", since = "1.0.0")] u8,
+                       #[unstable(feature = "test_feature")] u8);
+
+    pub fn foo() {
+        let x = Stable {
+            inherit: 1,
+            override1: 2,
+            override2: 3,
+            //~^ ERROR use of deprecated item
+        };
+
+        let _ = x.inherit;
+        let _ = x.override1;
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+
+        let Stable {
+            inherit: _,
+            override1: _,
+            override2: _
+            //~^ ERROR use of deprecated item
+        } = x;
+        // all fine
+        let Stable { .. } = x;
+
+        let x = Stable2(1, 2, 3);
+
+        let _ = x.0;
+        let _ = x.1;
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+
+        let Stable2(_,
+                   _,
+                   _)
+            //~^ ERROR use of deprecated item
+            = x;
+        // all fine
+        let Stable2(..) = x;
+
+
+        let x = Unstable {
+            inherit: 1,
+            override1: 2,
+            override2: 3,
+            //~^ ERROR use of deprecated item
+        };
+
+        let _ = x.inherit;
+        let _ = x.override1;
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+
+        let Unstable {
+            inherit: _,
+            override1: _,
+            override2: _
+            //~^ ERROR use of deprecated item
+        } = x;
+
+        let Unstable
+            // the patterns are all fine:
+            { .. } = x;
+
+
+        let x = Unstable2(1, 2, 3);
+
+        let _ = x.0;
+        let _ = x.1;
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+
+        let Unstable2
+            (_,
+             _,
+             _)
+            //~^ ERROR use of deprecated item
+            = x;
+        let Unstable2
+            // the patterns are all fine:
+            (..) = x;
+
+
+        let x = Deprecated {
+            //~^ ERROR use of deprecated item
+            inherit: 1,
+            //~^ ERROR use of deprecated item
+            override1: 2,
+            override2: 3,
+        };
+
+        let _ = x.inherit;
+        //~^ ERROR use of deprecated item
+        let _ = x.override1;
+        let _ = x.override2;
+
+        let Deprecated {
+            //~^ ERROR use of deprecated item
+            inherit: _,
+            //~^ ERROR use of deprecated item
+            override1: _,
+            override2: _
+        } = x;
+
+        let Deprecated
+            //~^ ERROR use of deprecated item
+            // the patterns are all fine:
+            { .. } = x;
+
+        let x = Deprecated2(1, 2, 3);
+        //~^ ERROR use of deprecated item
+
+        let _ = x.0;
+        //~^ ERROR use of deprecated item
+        let _ = x.1;
+        let _ = x.2;
+
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+            (_,
+             //~^ ERROR use of deprecated item
+             _,
+             _)
+            = x;
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+            // the patterns are all fine:
+            (..) = x;
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index 90792848855..12548c45396 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -317,11 +317,17 @@ mod this_crate {
 
     #[unstable(feature = "test_feature")]
     #[deprecated(since = "1.0.0")]
-    pub struct DeprecatedStruct { i: isize }
+    pub struct DeprecatedStruct {
+        #[stable(feature = "test_feature", since = "1.0.0")] i: isize
+    }
     #[unstable(feature = "test_feature")]
-    pub struct UnstableStruct { i: isize }
+    pub struct UnstableStruct {
+        #[stable(feature = "test_feature", since = "1.0.0")] i: isize
+    }
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub struct StableStruct { i: isize }
+    pub struct StableStruct {
+        #[stable(feature = "test_feature", since = "1.0.0")] i: isize
+    }
 
     #[unstable(feature = "test_feature")]
     #[deprecated(since = "1.0.0")]
diff --git a/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs b/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs
new file mode 100644
index 00000000000..b868b79365d
--- /dev/null
+++ b/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs
@@ -0,0 +1,17 @@
+// 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.
+
+// Issue #21370
+
+macro_rules! test {
+    ($wrong:t_ty) => () //~ ERROR invalid fragment specifier `t_ty`
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/unused-macro-with-follow-violation.rs b/src/test/compile-fail/unused-macro-with-follow-violation.rs
new file mode 100644
index 00000000000..e9d09bb6ad9
--- /dev/null
+++ b/src/test/compile-fail/unused-macro-with-follow-violation.rs
@@ -0,0 +1,15 @@
+// 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.
+
+macro_rules! test {
+    ($e:expr +) => () //~ ERROR not allowed for `expr` fragments
+}
+
+fn main() { }
diff --git a/src/test/run-pass/deriving-primitive.rs b/src/test/run-pass/deriving-primitive.rs
index eb3cb30594e..6b365c348f7 100644
--- a/src/test/run-pass/deriving-primitive.rs
+++ b/src/test/run-pass/deriving-primitive.rs
@@ -9,18 +9,18 @@
 // except according to those terms.
 
 use std::num::FromPrimitive;
-use std::int;
+use std::isize;
 
 #[derive(PartialEq, FromPrimitive, Debug)]
 enum A {
-    Foo = int::MAX,
+    Foo = isize::MAX,
     Bar = 1,
     Baz = 3,
     Qux,
 }
 
 pub fn main() {
-    let x: Option<A> = FromPrimitive::from_int(int::MAX);
+    let x: Option<A> = FromPrimitive::from_int(isize::MAX);
     assert_eq!(x, Some(A::Foo));
 
     let x: Option<A> = FromPrimitive::from_int(1);
diff --git a/src/test/run-pass/issue-17216.rs b/src/test/run-pass/issue-17216.rs
index ce5a0aa96e3..aa53a7658e1 100644
--- a/src/test/run-pass/issue-17216.rs
+++ b/src/test/run-pass/issue-17216.rs
@@ -25,9 +25,7 @@ fn main() {
     let mut dropped = false;
     {
         let leak = Leak { dropped: &mut dropped };
-        // FIXME(#21721) "hack" used to be () but that can cause
-        // certain LLVM versions to abort during optimizations.
-        for (_, leaked) in Some(("hack", leak)).into_iter() {}
+        for ((), leaked) in Some(((), leak)).into_iter() {}
     }
 
     assert!(dropped);
diff --git a/src/test/run-pass/issue-21721.rs b/src/test/run-pass/issue-21721.rs
new file mode 100644
index 00000000000..fee14061c56
--- /dev/null
+++ b/src/test/run-pass/issue-21721.rs
@@ -0,0 +1,17 @@
+// 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.
+
+fn main() {
+    static NONE: Option<((), &'static u8)> = None;
+    let ptr = unsafe {
+        *(&NONE as *const _ as *const *const u8)
+    };
+    assert!(ptr.is_null());
+}
diff --git a/src/test/run-pass/issue-22536-copy-mustnt-zero.rs b/src/test/run-pass/issue-22536-copy-mustnt-zero.rs
new file mode 100644
index 00000000000..b3492180a58
--- /dev/null
+++ b/src/test/run-pass/issue-22536-copy-mustnt-zero.rs
@@ -0,0 +1,34 @@
+// 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.
+
+// Regression test for Issue #22536: If a type implements Copy, then
+// moving it must not zero the original memory.
+
+trait Resources {
+    type Buffer: Copy;
+    fn foo(&self) {}
+}
+
+struct BufferHandle<R: Resources> {
+    raw: <R as Resources>::Buffer,
+}
+impl<R: Resources> Copy for BufferHandle<R> {}
+
+enum Res {}
+impl Resources for Res {
+    type Buffer = u32;
+}
+impl Copy for Res { }
+
+fn main() {
+    let b: BufferHandle<Res> = BufferHandle { raw: 1 };
+    let c = b;
+    assert_eq!(c.raw, b.raw)
+}
diff --git a/src/test/run-pass/match-with-ret-arm.rs b/src/test/run-pass/match-with-ret-arm.rs
index 05c6aac90e3..d2e27fc822e 100644
--- a/src/test/run-pass/match-with-ret-arm.rs
+++ b/src/test/run-pass/match-with-ret-arm.rs
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::uint;
-
 pub fn main() {
     // sometimes we have had trouble finding
     // the right type for f, as we unified
     // bot and u32 here
-    let f = match "1234".parse::<uint>().ok() {
+    let f = match "1234".parse::<usize>().ok() {
         None => return (),
         Some(num) => num as u32
     };
diff --git a/src/test/run-pass/traits-issue-22655.rs b/src/test/run-pass/traits-issue-22655.rs
new file mode 100644
index 00000000000..18c7cfb0850
--- /dev/null
+++ b/src/test/run-pass/traits-issue-22655.rs
@@ -0,0 +1,29 @@
+// 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.
+
+// Regression test for issue #22655: This test should not lead to
+// infinite recursion.
+
+unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
+
+pub struct Unique<T:?Sized> {
+    pointer: *const T,
+}
+
+pub struct Node<V> {
+    vals: V,
+    edges: Unique<Node<V>>,
+}
+
+fn is_send<T: Send>() {}
+
+fn main() {
+    is_send::<Node<&'static ()>>();
+}