about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-12-16 12:16:43 +0000
committerbors <bors@rust-lang.org>2015-12-16 12:16:43 +0000
commit785a8a6681963ff389b5902e7d6bd30006fafe0a (patch)
tree60b51ca2c9f0efd343f24eb564f90b5697a74c87 /src
parentce7bc51933e2facb4eca029ac17b398f372f5b41 (diff)
parentf0361a05028ec9bf8ef256432c212f1d7f3bc115 (diff)
downloadrust-785a8a6681963ff389b5902e7d6bd30006fafe0a.tar.gz
rust-785a8a6681963ff389b5902e7d6bd30006fafe0a.zip
Auto merge of #30410 - Manishearth:rollup, r=Manishearth
- Successful merges: #30320, #30368, #30372, #30376, #30388, #30392
- Failed merges: #30354, #30389
Diffstat (limited to 'src')
-rw-r--r--src/libcollections/btree/set.rs11
-rw-r--r--src/librustc/middle/check_static_recursion.rs5
-rw-r--r--src/librustc/middle/def.rs6
-rw-r--r--src/librustc/middle/infer/region_inference/mod.rs12
-rw-r--r--src/librustc/middle/infer/unify_key.rs24
-rw-r--r--src/librustc/middle/mem_categorization.rs6
-rw-r--r--src/librustc/middle/resolve_lifetime.rs17
-rw-r--r--src/librustc/middle/ty/mod.rs3
-rw-r--r--src/librustc/session/mod.rs9
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/mod.rs6
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/restrictions.rs22
-rw-r--r--src/librustc_data_structures/unify/mod.rs21
-rw-r--r--src/librustc_metadata/astencode.rs3
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs3
-rw-r--r--src/librustc_resolve/lib.rs29
-rw-r--r--src/librustc_trans/save/dump_csv.rs3
-rw-r--r--src/librustc_trans/trans/callee.rs2
-rw-r--r--src/librustc_typeck/astconv.rs6
-rw-r--r--src/librustc_typeck/check/_match.rs73
-rw-r--r--src/librustc_typeck/check/callee.rs3
-rw-r--r--src/librustc_typeck/check/dropck.rs29
-rw-r--r--src/librustc_typeck/check/mod.rs231
-rw-r--r--src/librustc_typeck/check/writeback.rs6
-rw-r--r--src/librustc_typeck/coherence/orphan.rs3
-rw-r--r--src/librustc_typeck/lib.rs15
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/librustdoc/markdown.rs4
-rw-r--r--src/librustdoc/test.rs14
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs9
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs4
-rw-r--r--src/libsyntax/fold.rs3
-rw-r--r--src/libsyntax/parse/token.rs2
-rw-r--r--src/libsyntax/print/pprust.rs2
-rw-r--r--src/test/compile-fail-fulldeps/qquote.rs3
-rw-r--r--src/test/compile-fail/associated-types-coherence-failure.rs4
-rw-r--r--src/test/compile-fail/bogus-tag.rs8
-rw-r--r--src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs6
-rw-r--r--src/test/compile-fail/coherence-impls-copy.rs4
-rw-r--r--src/test/compile-fail/coherence-impls-sized.rs1
-rw-r--r--src/test/compile-fail/duplicate-type-parameter.rs1
-rw-r--r--src/test/compile-fail/inner-static-type-parameter.rs2
-rw-r--r--src/test/compile-fail/issue-12796.rs4
-rw-r--r--src/test/compile-fail/issue-14254.rs2
-rw-r--r--src/test/compile-fail/issue-19883.rs2
-rw-r--r--src/test/compile-fail/issue-20427.rs4
-rw-r--r--src/test/compile-fail/issue-23305.rs1
-rw-r--r--src/test/compile-fail/issue-2356.rs4
-rw-r--r--src/test/compile-fail/issue-28109.rs14
-rw-r--r--src/test/compile-fail/issue-3021-d.rs4
-rw-r--r--src/test/compile-fail/issue-3021.rs2
-rw-r--r--src/test/compile-fail/issue-3214.rs2
-rw-r--r--src/test/compile-fail/issue-3521.rs1
-rw-r--r--src/test/compile-fail/issue-3973.rs2
-rw-r--r--src/test/compile-fail/issue-5927.rs8
-rw-r--r--src/test/compile-fail/issue-9725.rs1
-rw-r--r--src/test/compile-fail/macro-parameter-span.rs23
-rw-r--r--src/test/compile-fail/mod_file_correct_spans.rs2
-rw-r--r--src/test/compile-fail/opt-in-copy.rs2
-rw-r--r--src/test/compile-fail/resolve-inconsistent-binding-mode.rs3
-rw-r--r--src/test/compile-fail/resolve-type-param-in-item-in-trait.rs3
-rw-r--r--src/test/compile-fail/syntax-extension-minor.rs2
-rw-r--r--src/test/compile-fail/trait-safety-trait-impl-cc.rs2
-rw-r--r--src/test/compile-fail/trait-safety-trait-impl.rs4
-rw-r--r--src/test/rustdoc/issue-30252.rs16
64 files changed, 455 insertions, 270 deletions
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index a2c09c36795..12d3465e518 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -26,12 +26,17 @@ use Bound;
 
 /// A set based on a B-Tree.
 ///
-/// See BTreeMap's documentation for a detailed discussion of this collection's performance
+/// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance
 /// benefits and drawbacks.
 ///
 /// It is a logic error for an item to be modified in such a way that the item's ordering relative
-/// to any other item, as determined by the `Ord` trait, changes while it is in the set. This is
-/// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
+/// to any other item, as determined by the [`Ord`] trait, changes while it is in the set. This is
+/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
+///
+/// [`BTreeMap`]: ../struct.BTreeMap.html
+/// [`Ord`]: ../../core/cmp/trait.Ord.html
+/// [`Cell`]: ../../std/cell/struct.Cell.html
+/// [`RefCell`]: ../../std/cell/struct.RefCell.html
 #[derive(Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BTreeSet<T> {
diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs
index 85a3117196a..0882f3f1137 100644
--- a/src/librustc/middle/check_static_recursion.rs
+++ b/src/librustc/middle/check_static_recursion.rs
@@ -99,8 +99,9 @@ pub fn check_crate<'ast>(sess: &Session,
         ast_map: ast_map,
         discriminant_map: RefCell::new(NodeMap()),
     };
-    krate.visit_all_items(&mut visitor);
-    sess.abort_if_errors();
+    sess.abort_if_new_errors(|| {
+        krate.visit_all_items(&mut visitor);
+    });
 }
 
 struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index b1d24187957..809c6084b76 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -52,6 +52,7 @@ pub enum Def {
     DefStruct(DefId),
     DefLabel(ast::NodeId),
     DefMethod(DefId),
+    DefErr,
 }
 
 /// The result of resolving a path.
@@ -124,7 +125,7 @@ impl Def {
             DefVariant(..) | DefTy(..) | DefAssociatedTy(..) |
             DefTyParam(..) | DefUse(..) | DefStruct(..) | DefTrait(..) |
             DefMethod(..) | DefConst(..) | DefAssociatedConst(..) |
-            DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) => {
+            DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) | DefErr => {
                 panic!("attempted .def_id() on invalid {:?}", self)
             }
         }
@@ -142,7 +143,8 @@ impl Def {
 
             DefLabel(..)  |
             DefPrimTy(..) |
-            DefSelfTy(..) => {
+            DefSelfTy(..) |
+            DefErr => {
                 panic!("attempted .def_id() on invalid def: {:?}", self)
             }
         }
diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index 30cf6344e23..e148aecd241 100644
--- a/src/librustc/middle/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -18,6 +18,7 @@ pub use self::RegionResolutionError::*;
 pub use self::VarValue::*;
 
 use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable};
+use super::unify_key;
 
 use rustc_data_structures::graph::{self, Direction, NodeIndex};
 use rustc_data_structures::unify::{self, UnificationTable};
@@ -345,10 +346,13 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     }
 
     pub fn new_region_var(&self, origin: RegionVariableOrigin) -> RegionVid {
-        let id = self.num_vars();
+        let vid = RegionVid { index: self.num_vars() };
         self.var_origins.borrow_mut().push(origin.clone());
-        let vid = self.unification_table.borrow_mut().new_key(());
-        assert_eq!(vid.index, id);
+
+        let u_vid = self.unification_table.borrow_mut().new_key(
+            unify_key::RegionVidKey { min_vid: vid }
+            );
+        assert_eq!(vid, u_vid);
         if self.in_snapshot() {
             self.undo_log.borrow_mut().push(AddVar(vid));
         }
@@ -581,7 +585,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     }
 
     pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> ty::Region {
-        ty::ReVar(self.unification_table.borrow_mut().find(rid))
+        ty::ReVar(self.unification_table.borrow_mut().find_value(rid).min_vid)
     }
 
     fn combine_map(&self, t: CombineMapType) -> &RefCell<CombineMap> {
diff --git a/src/librustc/middle/infer/unify_key.rs b/src/librustc/middle/infer/unify_key.rs
index 85d7d67a0e3..c83231930f5 100644
--- a/src/librustc/middle/infer/unify_key.rs
+++ b/src/librustc/middle/infer/unify_key.rs
@@ -10,7 +10,7 @@
 
 use syntax::ast;
 use middle::ty::{self, IntVarValue, Ty};
-use rustc_data_structures::unify::UnifyKey;
+use rustc_data_structures::unify::{Combine, UnifyKey};
 
 pub trait ToType<'tcx> {
     fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
@@ -23,8 +23,28 @@ impl UnifyKey for ty::IntVid {
     fn tag(_: Option<ty::IntVid>) -> &'static str { "IntVid" }
 }
 
+#[derive(PartialEq, Copy, Clone, Debug)]
+pub struct RegionVidKey {
+    /// The minimum region vid in the unification set. This is needed
+    /// to have a canonical name for a type to prevent infinite
+    /// recursion.
+    pub min_vid: ty::RegionVid
+}
+
+impl Combine for RegionVidKey {
+    fn combine(&self, other: &RegionVidKey) -> RegionVidKey {
+        let min_vid = if self.min_vid.index < other.min_vid.index {
+            self.min_vid
+        } else {
+            other.min_vid
+        };
+
+        RegionVidKey { min_vid: min_vid }
+    }
+}
+
 impl UnifyKey for ty::RegionVid {
-    type Value = ();
+    type Value = RegionVidKey;
     fn index(&self) -> u32 { self.index }
     fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid { index: i } }
     fn tag(_: Option<ty::RegionVid>) -> &'static str { "RegionVid" }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 70ef112efba..f869cac9236 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -609,6 +609,8 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
                 note: NoteNone
             }))
           }
+
+          def::DefErr => panic!("DefErr in memory categorization")
         }
     }
 
@@ -1196,7 +1198,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         (*op)(self, cmt.clone(), pat);
 
         let opt_def = if let Some(path_res) = self.tcx().def_map.borrow().get(&pat.id) {
-            if path_res.depth != 0 {
+            if path_res.depth != 0 || path_res.base_def == def::DefErr {
                 // Since patterns can be associated constants
                 // which are resolved during typeck, we might have
                 // some unresolved patterns reaching this stage
@@ -1261,7 +1263,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
                 _ => {
                     self.tcx().sess.span_bug(
                         pat.span,
-                        "enum pattern didn't resolve to enum or struct");
+                        &format!("enum pattern didn't resolve to enum or struct {:?}", opt_def));
                 }
             }
           }
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index b37b3070310..15d1546d2d5 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -95,15 +95,16 @@ static ROOT_SCOPE: ScopeChain<'static> = RootScope;
 
 pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap {
     let mut named_region_map = NodeMap();
-    krate.visit_all_items(&mut LifetimeContext {
-        sess: sess,
-        named_region_map: &mut named_region_map,
-        scope: &ROOT_SCOPE,
-        def_map: def_map,
-        trait_ref_hack: false,
-        labels_in_fn: vec![],
+    sess.abort_if_new_errors(|| {
+        krate.visit_all_items(&mut LifetimeContext {
+            sess: sess,
+            named_region_map: &mut named_region_map,
+            scope: &ROOT_SCOPE,
+            def_map: def_map,
+            trait_ref_hack: false,
+            labels_in_fn: vec![],
+        });
     });
-    sess.abort_if_errors();
     named_region_map
 }
 
diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs
index 7477c4dead0..5161a28ca31 100644
--- a/src/librustc/middle/ty/mod.rs
+++ b/src/librustc/middle/ty/mod.rs
@@ -2100,9 +2100,8 @@ impl<'tcx> ctxt<'tcx> {
                     }) => {
                         true
                     }
-
+                    Some(&def::PathResolution { base_def: def::DefErr, .. })=> true,
                     Some(..) => false,
-
                     None => self.sess.span_bug(expr.span, &format!(
                         "no def for path {}", expr.id))
                 }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 7bf96b41dce..b7bfc2f8db5 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -156,6 +156,15 @@ impl Session {
             _ => {}
         }
     }
+    pub fn abort_if_new_errors<F>(&self, mut f: F)
+        where F: FnMut()
+    {
+        let count = self.err_count();
+        f();
+        if self.err_count() > count {
+            self.abort_if_errors();
+        }
+    }
     pub fn span_warn(&self, sp: Span, msg: &str) {
         if self.can_print_warnings {
             self.diagnostic().span_warn(sp, msg)
diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
index 47f29a26db1..c07a27043c2 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
@@ -33,6 +33,8 @@ use rustc_front::hir::{Expr, FnDecl, Block, Pat};
 use rustc_front::intravisit;
 use rustc_front::intravisit::Visitor;
 
+use self::restrictions::RestrictionResult;
+
 mod lifetime;
 mod restrictions;
 mod gather_moves;
@@ -354,12 +356,12 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
 
         // Create the loan record (if needed).
         let loan = match restr {
-            restrictions::Safe => {
+            RestrictionResult::Safe => {
                 // No restrictions---no loan record necessary
                 return;
             }
 
-            restrictions::SafeIf(loan_path, restricted_paths) => {
+            RestrictionResult::SafeIf(loan_path, restricted_paths) => {
                 let loan_scope = match loan_region {
                     ty::ReScope(scope) => scope,
 
diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
index cb75180b474..2a0d8ef2766 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
@@ -10,8 +10,6 @@
 
 //! Computes the restrictions that result from a borrow.
 
-pub use self::RestrictionResult::*;
-
 use borrowck::*;
 use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
@@ -69,19 +67,19 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
                 // are inherently non-aliasable, they can only be
                 // accessed later through the borrow itself and hence
                 // must inherently comply with its terms.
-                Safe
+                RestrictionResult::Safe
             }
 
             Categorization::Local(local_id) => {
                 // R-Variable, locally declared
                 let lp = new_lp(LpVar(local_id));
-                SafeIf(lp.clone(), vec![lp])
+                RestrictionResult::SafeIf(lp.clone(), vec![lp])
             }
 
             Categorization::Upvar(mc::Upvar { id, .. }) => {
                 // R-Variable, captured into closure
                 let lp = new_lp(LpUpvar(id));
-                SafeIf(lp.clone(), vec![lp])
+                RestrictionResult::SafeIf(lp.clone(), vec![lp])
             }
 
             Categorization::Downcast(cmt_base, _) => {
@@ -106,7 +104,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
             }
 
             Categorization::StaticItem => {
-                Safe
+                RestrictionResult::Safe
             }
 
             Categorization::Deref(cmt_base, _, pk) => {
@@ -133,11 +131,11 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
                                     cmt: cmt_base,
                                     code: err_borrowed_pointer_too_short(
                                         self.loan_region, lt)});
-                            return Safe;
+                            return RestrictionResult::Safe;
                         }
 
                         match bk {
-                            ty::ImmBorrow => Safe,
+                            ty::ImmBorrow => RestrictionResult::Safe,
                             ty::MutBorrow | ty::UniqueImmBorrow => {
                                 // R-Deref-Mut-Borrowed
                                 //
@@ -150,7 +148,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
                         }
                     }
                     // Borrowck is not relevant for raw pointers
-                    mc::UnsafePtr(..) => Safe
+                    mc::UnsafePtr(..) => RestrictionResult::Safe
                 }
             }
         }
@@ -161,12 +159,12 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
               cmt: &mc::cmt<'tcx>,
               elem: LoanPathElem) -> RestrictionResult<'tcx> {
         match result {
-            Safe => Safe,
-            SafeIf(base_lp, mut base_vec) => {
+            RestrictionResult::Safe => RestrictionResult::Safe,
+            RestrictionResult::SafeIf(base_lp, mut base_vec) => {
                 let v = LpExtend(base_lp, cmt.mutbl, elem);
                 let lp = Rc::new(LoanPath::new(v, cmt.ty));
                 base_vec.push(lp.clone());
-                SafeIf(lp, base_vec)
+                RestrictionResult::SafeIf(lp, base_vec)
             }
         }
     }
diff --git a/src/librustc_data_structures/unify/mod.rs b/src/librustc_data_structures/unify/mod.rs
index 4d79b1a64c1..c6da70eef75 100644
--- a/src/librustc_data_structures/unify/mod.rs
+++ b/src/librustc_data_structures/unify/mod.rs
@@ -37,6 +37,16 @@ pub trait UnifyKey : Copy + Clone + Debug + PartialEq {
     fn tag(k: Option<Self>) -> &'static str;
 }
 
+/// This trait is implemented for unify values that can be
+/// combined. This relation should be a monoid.
+pub trait Combine {
+    fn combine(&self, other: &Self) -> Self;
+}
+
+impl Combine for () {
+    fn combine(&self, _other: &()) {}
+}
+
 /// Value of a unification key. We implement Tarjan's union-find
 /// algorithm: when two keys are unified, one of them is converted
 /// into a "redirect" pointing at the other. These redirects form a
@@ -243,8 +253,8 @@ impl<K:UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
 ///////////////////////////////////////////////////////////////////////////
 // Base union-find algorithm, where we are just making sets
 
-impl<'tcx,K> UnificationTable<K>
-    where K : UnifyKey<Value=()>,
+impl<'tcx,K:UnifyKey> UnificationTable<K>
+    where K::Value: Combine
 {
     pub fn union(&mut self, a_id: K, b_id: K) {
         let node_a = self.get(a_id);
@@ -252,7 +262,8 @@ impl<'tcx,K> UnificationTable<K>
         let a_id = node_a.key();
         let b_id = node_b.key();
         if a_id != b_id {
-            self.unify(node_a, node_b, ());
+            let new_value = node_a.value.combine(&node_b.value);
+            self.unify(node_a, node_b, new_value);
         }
     }
 
@@ -260,6 +271,10 @@ impl<'tcx,K> UnificationTable<K>
         self.get(id).key()
     }
 
+    pub fn find_value(&mut self, id: K) -> K::Value {
+        self.get(id).value
+    }
+
     pub fn unioned(&mut self, a_id: K, b_id: K) -> bool {
         self.find(a_id) == self.find(b_id)
     }
diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs
index 4c47d3ab990..d43ffb0fc3f 100644
--- a/src/librustc_metadata/astencode.rs
+++ b/src/librustc_metadata/astencode.rs
@@ -407,7 +407,8 @@ impl tr for def::Def {
               def::DefUpvar(did1, nid1, index, nid2)
           }
           def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
-          def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid))
+          def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid)),
+          def::DefErr => def::DefErr,
         }
     }
 }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 0deef91a0f6..8b5b6ff781e 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -709,7 +709,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             DefUse(..) |
             DefUpvar(..) |
             DefLabel(..) |
-            DefSelfTy(..) => {
+            DefSelfTy(..) |
+            DefErr => {
                 panic!("didn't expect `{:?}`", def);
             }
         }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index c32acb7bb26..4d5978f5560 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -566,6 +566,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
             Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
             Err(_) => {
                 // error already reported
+                self.record_def(tref.trait_ref.ref_id, err_path_resolution())
             }
         }
         intravisit::walk_poly_trait_ref(self, tref, m);
@@ -2005,6 +2006,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                                   prefix.span,
                                                   ResolutionError::FailedToResolve(
                                                       &path_names_to_string(prefix, 0)));
+                                    self.record_def(item.id, err_path_resolution());
                                 }
                             }
                         }
@@ -2164,6 +2166,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         resolve_error(self,
                                       eq_pred.span,
                                       ResolutionError::UndeclaredAssociatedType);
+                        self.record_def(eq_pred.id, err_path_resolution());
                     }
                 }
             }
@@ -2194,6 +2197,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 self.record_def(trait_ref.ref_id, path_res);
                 new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
                 new_id = Some(path_res.base_def.def_id());
+            } else {
+                self.record_def(trait_ref.ref_id, err_path_resolution());
             }
             intravisit::walk_trait_ref(self, trait_ref);
         }
@@ -2463,6 +2468,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         self.record_def(ty.id, def);
                     }
                     None => {
+                        self.record_def(ty.id, err_path_resolution());
+
                         // Keep reporting some errors even if they're ignored above.
                         self.resolve_path(ty.id, path, 0, TypeNS, true);
 
@@ -2545,6 +2552,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
                                     renamed)
                             );
+                            self.record_def(pattern.id, err_path_resolution());
                         }
                         FoundConst(def, lp, _) if const_ok => {
                             debug!("(resolving pattern) resolving `{}` to constant", renamed);
@@ -2564,6 +2572,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
                                                                                     name)
                             );
+                            self.record_def(pattern.id, err_path_resolution());
                         }
                         BareIdentifierPatternUnresolved => {
                             debug!("(resolving pattern) binding `{}`", renamed);
@@ -2647,6 +2656,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 resolve_error(&self,
                                               path.span,
                                               ResolutionError::StaticVariableReference);
+                                self.record_def(pattern.id, err_path_resolution());
                             }
                             _ => {
                                 // If anything ends up here entirely resolved,
@@ -2665,6 +2675,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                                  .name
                                                  .as_str())
                                     );
+                                    self.record_def(pattern.id, err_path_resolution());
                                 } else {
                                     let const_name = path.segments
                                                          .last()
@@ -2684,6 +2695,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             ResolutionError::UnresolvedEnumVariantStructOrConst(
                                 &path.segments.last().unwrap().identifier.name.as_str())
                         );
+                        self.record_def(pattern.id, err_path_resolution());
                     }
                     intravisit::walk_path(self, path);
                 }
@@ -2726,6 +2738,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                         &path.segments.last().unwrap().identifier.name.as_str()
                                     )
                                 );
+                                self.record_def(pattern.id, err_path_resolution());
                             }
                         }
                     } else {
@@ -2737,6 +2750,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                                                                       .identifier
                                                                                       .name
                                                                                       .as_str()));
+                        self.record_def(pattern.id, err_path_resolution());
                     }
                     intravisit::walk_pat(self, pattern);
                 }
@@ -2754,6 +2768,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 ResolutionError::DoesNotNameAStruct(
                                     &*path_names_to_string(path, 0))
                             );
+                            self.record_def(pattern.id, err_path_resolution());
                         }
                     }
                     intravisit::walk_path(self, path);
@@ -3430,6 +3445,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         } else {
                             self.session.span_help(expr.span, &msg);
                         }
+                        self.record_def(expr.id, err_path_resolution());
                     } else {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `{}`",
@@ -3454,6 +3470,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     let type_res = self.with_no_errors(|this| {
                         this.resolve_path(expr.id, path, 0, TypeNS, false)
                     });
+
+                    self.record_def(expr.id, err_path_resolution());
                     match type_res.map(|r| r.base_def) {
                         Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
                             resolve_error(
@@ -3540,6 +3558,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                       ResolutionError::DoesNotNameAStruct(
                                                                 &*path_names_to_string(path, 0))
                                      );
+                        self.record_def(expr.id, err_path_resolution());
                     }
                 }
 
@@ -3562,6 +3581,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
                 match self.search_label(label.node.name) {
                     None => {
+                        self.record_def(expr.id, err_path_resolution());
                         resolve_error(self,
                                       label.span,
                                       ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
@@ -3811,6 +3831,14 @@ fn module_to_string(module: &Module) -> String {
     names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
 }
 
+fn err_path_resolution() -> PathResolution {
+    PathResolution {
+        base_def: DefErr,
+        last_private: LastMod(AllPublic),
+        depth: 0,
+    }
+}
+
 
 pub struct CrateMap {
     pub def_map: RefCell<DefMap>,
@@ -3836,7 +3864,6 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
     let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
 
     resolver.resolve_crate(krate);
-    session.abort_if_errors();
 
     check_unused::check_crate(&mut resolver, krate);
 
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 2964d87ec1c..b3e7ed7ed5e 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -276,7 +276,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             def::DefTyParam(..) |
             def::DefUse(_) |
             def::DefMethod(..) |
-            def::DefPrimTy(_) => {
+            def::DefPrimTy(_) |
+            def::DefErr => {
                 self.sess.span_bug(span,
                                    &format!("lookup_def_kind for unexpected item: {:?}", def));
             }
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 4aa7c0ff587..a22c12588e5 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -216,7 +216,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
             def::DefMod(..) | def::DefForeignMod(..) | def::DefTrait(..) |
             def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) |
             def::DefUse(..) | def::DefLabel(..) | def::DefTyParam(..) |
-            def::DefSelfTy(..) => {
+            def::DefSelfTy(..) | def::DefErr => {
                 bcx.tcx().sess.span_bug(
                     ref_expr.span,
                     &format!("cannot translate def {:?} \
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index b83f0a5be6f..752dd6e57f6 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -719,6 +719,9 @@ fn trait_def_id<'tcx>(this: &AstConv<'tcx>, trait_ref: &hir::TraitRef) -> DefId
     let path = &trait_ref.path;
     match ::lookup_full_def(this.tcx(), path.span, trait_ref.ref_id) {
         def::DefTrait(trait_def_id) => trait_def_id,
+        def::DefErr => {
+            this.tcx().sess.fatal("cannot continue compilation due to previous error");
+        }
         _ => {
             span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
                         path);
@@ -1533,6 +1536,9 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
         def::DefPrimTy(prim_ty) => {
             prim_ty_to_ty(tcx, base_segments, prim_ty)
         }
+        def::DefErr => {
+            return this.tcx().types.err;
+        }
         _ => {
             let id_node = tcx.map.as_local_node_id(def.def_id()).unwrap();
             span_err!(tcx.sess, span, E0248,
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 38c714fa8f2..efcc08c69f8 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -142,20 +142,24 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                     return;
                 }
             }
-            let const_did = tcx.def_map.borrow().get(&pat.id).unwrap().def_id();
-            let const_scheme = tcx.lookup_item_type(const_did);
-            assert!(const_scheme.generics.is_empty());
-            let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
-                                                           &Substs::empty(),
-                                                           &const_scheme.ty);
-            fcx.write_ty(pat.id, const_ty);
-
-            // FIXME(#20489) -- we should limit the types here to scalars or something!
-
-            // As with PatLit, what we really want here is that there
-            // exist a LUB, but for the cases that can occur, subtype
-            // is good enough.
-            demand::suptype(fcx, pat.span, expected, const_ty);
+            if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) {
+                let const_did = pat_def.def_id();
+                let const_scheme = tcx.lookup_item_type(const_did);
+                assert!(const_scheme.generics.is_empty());
+                let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
+                                                               &Substs::empty(),
+                                                               &const_scheme.ty);
+                fcx.write_ty(pat.id, const_ty);
+
+                // FIXME(#20489) -- we should limit the types here to scalars or something!
+
+                // As with PatLit, what we really want here is that there
+                // exist a LUB, but for the cases that can occur, subtype
+                // is good enough.
+                demand::suptype(fcx, pat.span, expected, const_ty);
+            } else {
+                fcx.write_error(pat.id);
+            }
         }
         hir::PatIdent(bm, ref path, ref sub) if pat_is_binding(&tcx.def_map.borrow(), pat) => {
             let typ = fcx.local_ty(pat.span, pat.id);
@@ -186,14 +190,15 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
 
             // if there are multiple arms, make sure they all agree on
             // what the type of the binding `x` ought to be
-            let canon_id = *pcx.map.get(&path.node.name).unwrap();
-            if canon_id != pat.id {
-                let ct = fcx.local_ty(pat.span, canon_id);
-                demand::eqtype(fcx, pat.span, ct, typ);
-            }
+            if let Some(&canon_id) = pcx.map.get(&path.node.name) {
+                if canon_id != pat.id {
+                    let ct = fcx.local_ty(pat.span, canon_id);
+                    demand::eqtype(fcx, pat.span, ct, typ);
+                }
 
-            if let Some(ref p) = *sub {
-                check_pat(pcx, &**p, expected);
+                if let Some(ref p) = *sub {
+                    check_pat(pcx, &**p, expected);
+                }
             }
         }
         hir::PatIdent(_, ref path, _) => {
@@ -208,6 +213,10 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         hir::PatQPath(ref qself, ref path) => {
             let self_ty = fcx.to_ty(&qself.ty);
             let path_res = if let Some(&d) = tcx.def_map.borrow().get(&pat.id) {
+                if d.base_def == def::DefErr {
+                    fcx.write_error(pat.id);
+                    return;
+                }
                 d
             } else if qself.position == 0 {
                 // This is just a sentinel for finish_resolving_def_to_ty.
@@ -218,8 +227,9 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                     depth: path.segments.len()
                 }
             } else {
-                tcx.sess.span_bug(pat.span,
-                                  &format!("unbound path {:?}", pat))
+                debug!("unbound path {:?}", pat);
+                fcx.write_error(pat.id);
+                return;
             };
             if let Some((opt_ty, segments, def)) =
                     resolve_ty_and_def_ufcs(fcx, path_res, Some(self_ty),
@@ -597,7 +607,20 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
-    let path_res = *tcx.def_map.borrow().get(&pat.id).unwrap();
+    let path_res = match tcx.def_map.borrow().get(&pat.id) {
+        Some(&path_res) if path_res.base_def != def::DefErr => path_res,
+        _ => {
+            fcx.write_error(pat.id);
+
+            if let Some(subpats) = subpats {
+                for pat in subpats {
+                    check_pat(pcx, &**pat, tcx.types.err);
+                }
+            }
+
+            return;
+        }
+    };
 
     let (opt_ty, segments, def) = match resolve_ty_and_def_ufcs(fcx, path_res,
                                                                 None, path,
@@ -636,7 +659,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let report_bad_struct_kind = |is_warning| {
         bad_struct_kind_err(tcx.sess, pat.span, path, is_warning);
         if is_warning {
-            return
+            return;
         }
 
         fcx.write_error(pat.id);
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 6a23be682e9..1e20cd39854 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -26,6 +26,7 @@ use super::write_call;
 
 use CrateCtxt;
 use middle::cstore::LOCAL_CRATE;
+use middle::def;
 use middle::def_id::DefId;
 use middle::infer;
 use middle::ty::{self, LvaluePreference, Ty};
@@ -234,7 +235,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
             if let hir::ExprCall(ref expr, _) = call_expr.node {
                 let tcx = fcx.tcx();
                 if let Some(pr) = tcx.def_map.borrow().get(&expr.id) {
-                    if pr.depth == 0 {
+                    if pr.depth == 0 && pr.base_def != def::DefErr {
                         if let Some(span) = tcx.map.span_if_local(pr.def_id()) {
                             tcx.sess.span_note(span, "defined here")
                         }
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 0fbe8367493..59025346ce3 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -17,6 +17,7 @@ use middle::region;
 use middle::subst::{self, Subst};
 use middle::traits;
 use middle::ty::{self, Ty};
+use util::nodemap::FnvHashSet;
 
 use syntax::ast;
 use syntax::codemap::{self, Span};
@@ -279,7 +280,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
             rcx: rcx,
             span: span,
             parent_scope: parent_scope,
-            breadcrumbs: Vec::new(),
+            breadcrumbs: FnvHashSet()
         },
         TypeContext::Root,
         typ,
@@ -340,7 +341,7 @@ enum TypeContext {
 struct DropckContext<'a, 'b: 'a, 'tcx: 'b> {
     rcx: &'a mut Rcx<'b, 'tcx>,
     /// types that have already been traversed
-    breadcrumbs: Vec<Ty<'tcx>>,
+    breadcrumbs: FnvHashSet<Ty<'tcx>>,
     /// span for error reporting
     span: Span,
     /// the scope reachable dtorck types must outlive
@@ -355,8 +356,6 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
     depth: usize) -> Result<(), Error<'tcx>>
 {
     let tcx = cx.rcx.tcx();
-    let ty = cx.rcx.infcx().resolve_type_and_region_vars_if_possible(&ty);
-
     // Issue #22443: Watch out for overflow. While we are careful to
     // handle regular types properly, non-regular ones cause problems.
     let recursion_limit = tcx.sess.recursion_limit.get();
@@ -367,19 +366,17 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
         return Err(Error::Overflow(context, ty))
     }
 
-    for breadcrumb in &mut cx.breadcrumbs {
-        *breadcrumb =
-            cx.rcx.infcx().resolve_type_and_region_vars_if_possible(breadcrumb);
-        if *breadcrumb == ty {
-            debug!("iterate_over_potentially_unsafe_regions_in_type \
-                   {}ty: {} scope: {:?} - cached",
-                   (0..depth).map(|_| ' ').collect::<String>(),
-                   ty, cx.parent_scope);
-            return Ok(()); // we already visited this type
-        }
-    }
-    cx.breadcrumbs.push(ty);
+    // canoncialize the regions in `ty` before inserting - infinitely many
+    // region variables can refer to the same region.
+    let ty = cx.rcx.infcx().resolve_type_and_region_vars_if_possible(&ty);
 
+    if !cx.breadcrumbs.insert(ty) {
+        debug!("iterate_over_potentially_unsafe_regions_in_type \
+               {}ty: {} scope: {:?} - cached",
+               (0..depth).map(|_| ' ').collect::<String>(),
+               ty, cx.parent_scope);
+        return Ok(()); // we already visited this type
+    }
     debug!("iterate_over_potentially_unsafe_regions_in_type \
            {}ty: {} scope: {:?}",
            (0..depth).map(|_| ' ').collect::<String>(),
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f348d5411c3..1f3d8f55120 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -385,61 +385,60 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
 }
 
 pub fn check_wf_old(ccx: &CrateCtxt) {
-    // FIXME(#25759). The new code below is much more reliable but (for now)
-    // only generates warnings. So as to ensure that we continue
-    // getting errors where we used to get errors, we run the old wf
-    // code first and abort if it encounters any errors. If no abort
-    // comes, we run the new code and issue warnings.
-    let krate = ccx.tcx.map.krate();
-    let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
-    krate.visit_all_items(&mut visit);
-
     // If types are not well-formed, it leads to all manner of errors
     // downstream, so stop reporting errors at this point.
-    ccx.tcx.sess.abort_if_errors();
+    ccx.tcx.sess.abort_if_new_errors(|| {
+        // FIXME(#25759). The new code below is much more reliable but (for now)
+        // only generates warnings. So as to ensure that we continue
+        // getting errors where we used to get errors, we run the old wf
+        // code first and abort if it encounters any errors. If no abort
+        // comes, we run the new code and issue warnings.
+        let krate = ccx.tcx.map.krate();
+        let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
+        krate.visit_all_items(&mut visit);
+    });
 }
 
 pub fn check_wf_new(ccx: &CrateCtxt) {
-    let krate = ccx.tcx.map.krate();
-    let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
-    krate.visit_all_items(&mut visit);
-
-    // If types are not well-formed, it leads to all manner of errors
-    // downstream, so stop reporting errors at this point.
-    ccx.tcx.sess.abort_if_errors();
+    ccx.tcx.sess.abort_if_new_errors(|| {
+        let krate = ccx.tcx.map.krate();
+        let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
+        krate.visit_all_items(&mut visit);
+    });
 }
 
 pub fn check_item_types(ccx: &CrateCtxt) {
-    let krate = ccx.tcx.map.krate();
-    let mut visit = CheckItemTypesVisitor { ccx: ccx };
-    krate.visit_all_items(&mut visit);
-    ccx.tcx.sess.abort_if_errors();
+    ccx.tcx.sess.abort_if_new_errors(|| {
+        let krate = ccx.tcx.map.krate();
+        let mut visit = CheckItemTypesVisitor { ccx: ccx };
+        krate.visit_all_items(&mut visit);
+    });
 }
 
 pub fn check_item_bodies(ccx: &CrateCtxt) {
-    let krate = ccx.tcx.map.krate();
-    let mut visit = CheckItemBodiesVisitor { ccx: ccx };
-    krate.visit_all_items(&mut visit);
-
-    ccx.tcx.sess.abort_if_errors();
+    ccx.tcx.sess.abort_if_new_errors(|| {
+        let krate = ccx.tcx.map.krate();
+        let mut visit = CheckItemBodiesVisitor { ccx: ccx };
+        krate.visit_all_items(&mut visit);
+    });
 }
 
 pub fn check_drop_impls(ccx: &CrateCtxt) {
-    let drop_trait = match ccx.tcx.lang_items.drop_trait() {
-        Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
-    };
-    drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
-        if drop_impl_did.is_local() {
-            match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
-                Ok(()) => {}
-                Err(()) => {
-                    assert!(ccx.tcx.sess.has_errors());
+    ccx.tcx.sess.abort_if_new_errors(|| {
+        let drop_trait = match ccx.tcx.lang_items.drop_trait() {
+            Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
+        };
+        drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
+            if drop_impl_did.is_local() {
+                match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
+                    Ok(()) => {}
+                    Err(()) => {
+                        assert!(ccx.tcx.sess.has_errors());
+                    }
                 }
             }
-        }
+        });
     });
-
-    ccx.tcx.sess.abort_if_errors();
 }
 
 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@@ -891,75 +890,71 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     for impl_item in impl_items {
         let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
         let ty_trait_item = trait_items.iter()
-            .find(|ac| ac.name() == ty_impl_item.name())
-            .unwrap_or_else(|| {
-                // This is checked by resolve
-                tcx.sess.span_bug(impl_item.span,
-                                  &format!("impl-item `{}` is not a member of `{:?}`",
-                                           ty_impl_item.name(),
-                                           impl_trait_ref));
-            });
-        match impl_item.node {
-            hir::ImplItemKind::Const(..) => {
-                let impl_const = match ty_impl_item {
-                    ty::ConstTraitItem(ref cti) => cti,
-                    _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
-                };
+            .find(|ac| ac.name() == ty_impl_item.name());
 
-                // Find associated const definition.
-                if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
-                    compare_const_impl(ccx.tcx,
-                                       &impl_const,
-                                       impl_item.span,
-                                       trait_const,
-                                       &*impl_trait_ref);
-                } else {
-                    span_err!(tcx.sess, impl_item.span, E0323,
-                              "item `{}` is an associated const, \
-                              which doesn't match its trait `{:?}`",
-                              impl_const.name,
-                              impl_trait_ref)
+        if let Some(ty_trait_item) = ty_trait_item {
+            match impl_item.node {
+                hir::ImplItemKind::Const(..) => {
+                    let impl_const = match ty_impl_item {
+                        ty::ConstTraitItem(ref cti) => cti,
+                        _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
+                    };
+
+                    // Find associated const definition.
+                    if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
+                        compare_const_impl(ccx.tcx,
+                                           &impl_const,
+                                           impl_item.span,
+                                           trait_const,
+                                           &*impl_trait_ref);
+                    } else {
+                        span_err!(tcx.sess, impl_item.span, E0323,
+                                  "item `{}` is an associated const, \
+                                  which doesn't match its trait `{:?}`",
+                                  impl_const.name,
+                                  impl_trait_ref)
+                    }
                 }
-            }
-            hir::ImplItemKind::Method(ref sig, ref body) => {
-                check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
+                hir::ImplItemKind::Method(ref sig, ref body) => {
+                    check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
 
-                let impl_method = match ty_impl_item {
-                    ty::MethodTraitItem(ref mti) => mti,
-                    _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
-                };
+                    let impl_method = match ty_impl_item {
+                        ty::MethodTraitItem(ref mti) => mti,
+                        _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
+                    };
 
-                if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
-                    compare_impl_method(ccx.tcx,
-                                        &impl_method,
-                                        impl_item.span,
-                                        body.id,
-                                        &trait_method,
-                                        &impl_trait_ref);
-                } else {
-                    span_err!(tcx.sess, impl_item.span, E0324,
-                              "item `{}` is an associated method, \
-                              which doesn't match its trait `{:?}`",
-                              impl_method.name,
-                              impl_trait_ref)
+                    if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
+                        compare_impl_method(ccx.tcx,
+                                            &impl_method,
+                                            impl_item.span,
+                                            body.id,
+                                            &trait_method,
+                                            &impl_trait_ref);
+                    } else {
+                        span_err!(tcx.sess, impl_item.span, E0324,
+                                  "item `{}` is an associated method, \
+                                  which doesn't match its trait `{:?}`",
+                                  impl_method.name,
+                                  impl_trait_ref)
+                    }
                 }
-            }
-            hir::ImplItemKind::Type(_) => {
-                let impl_type = match ty_impl_item {
-                    ty::TypeTraitItem(ref tti) => tti,
-                    _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
-                };
+                hir::ImplItemKind::Type(_) => {
+                    let impl_type = match ty_impl_item {
+                        ty::TypeTraitItem(ref tti) => tti,
+                        _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
+                    };
 
-                if let &ty::TypeTraitItem(ref at) = ty_trait_item {
-                    if let Some(_) = at.ty {
-                        overridden_associated_type = Some(impl_item);
+                    if let &ty::TypeTraitItem(ref at) = ty_trait_item {
+                        if let Some(_) = at.ty {
+                            overridden_associated_type = Some(impl_item);
+                        }
+                    } else {
+                        span_err!(tcx.sess, impl_item.span, E0325,
+                                  "item `{}` is an associated type, \
+                                  which doesn't match its trait `{:?}`",
+                                  impl_type.name,
+                                  impl_trait_ref)
                     }
-                } else {
-                    span_err!(tcx.sess, impl_item.span, E0325,
-                              "item `{}` is an associated type, \
-                              which doesn't match its trait `{:?}`",
-                              impl_type.name,
-                              impl_trait_ref)
                 }
             }
         }
@@ -3193,6 +3188,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
         // Find the relevant variant
         let def = lookup_full_def(tcx, path.span, expr.id);
+        if def == def::DefErr {
+            check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
+            return;
+        }
         let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
             Some((adt, variant)) => (adt, variant),
             None => {
@@ -3371,17 +3370,21 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
           if let Some((opt_ty, segments, def)) =
                   resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
                                           expr.span, expr.id) {
-              let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
-                                                                            expr.span,
-                                                                            def);
-              instantiate_path(fcx,
-                               segments,
-                               scheme,
-                               &predicates,
-                               opt_ty,
-                               def,
-                               expr.span,
-                               id);
+              if def != def::DefErr {
+                  let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
+                                                                                expr.span,
+                                                                                def);
+                  instantiate_path(fcx,
+                                   segments,
+                                   scheme,
+                                   &predicates,
+                                   opt_ty,
+                                   def,
+                                   expr.span,
+                                   id);
+              } else {
+                  fcx.write_ty(id, fcx.tcx().types.err);
+              }
           }
 
           // We always require that the type provided as the value for
@@ -4326,7 +4329,8 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         def::DefForeignMod(..) |
         def::DefUse(..) |
         def::DefLabel(..) |
-        def::DefSelfTy(..) => {
+        def::DefSelfTy(..) |
+        def::DefErr => {
             fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
         }
     }
@@ -4496,7 +4500,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         def::DefLocal(..) |
         def::DefUse(..) |
         def::DefLabel(..) |
-        def::DefUpvar(..) => {
+        def::DefUpvar(..) |
+        def::DefErr => {
             segment_spaces = vec![None; segments.len()];
         }
     }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 984f227cebe..c24a416a010 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -122,10 +122,12 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 } else {
                     let tcx = self.tcx();
 
-                    if let hir::ExprAssignOp(..) = e.node {
+                    if let hir::ExprAssignOp(_, ref lhs, ref rhs) = e.node {
                         if
                             !tcx.sess.features.borrow().augmented_assignments &&
-                            !self.fcx.expr_ty(e).references_error()
+                            !self.fcx.expr_ty(e).references_error() &&
+                            !self.fcx.expr_ty(lhs).references_error() &&
+                            !self.fcx.expr_ty(rhs).references_error()
                         {
                             tcx.sess.span_err(
                                 e.span,
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index e6e31ba0819..b436a5ee524 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -205,6 +205,9 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                                                   "f64",
                                                   item.span);
                     }
+                    ty::TyError => {
+                        return;
+                    }
                     _ => {
                         span_err!(self.tcx.sess, item.span, E0118,
                                   "no base type found for inherent implementation; \
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 495b8995cee..02c1f3973c6 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -331,18 +331,21 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
         tcx: tcx
     };
 
-    time(time_passes, "type collecting", ||
-         collect::collect_item_types(tcx));
-
     // this ensures that later parts of type checking can assume that items
     // have valid types and not error
-    tcx.sess.abort_if_errors();
+    tcx.sess.abort_if_new_errors(|| {
+        time(time_passes, "type collecting", ||
+             collect::collect_item_types(tcx));
+
+    });
 
     time(time_passes, "variance inference", ||
          variance::infer_variance(tcx));
 
-    time(time_passes, "coherence checking", ||
-        coherence::check_coherence(&ccx));
+    tcx.sess.abort_if_new_errors(|| {
+      time(time_passes, "coherence checking", ||
+          coherence::check_coherence(&ccx));
+    });
 
     time(time_passes, "wf checking (old)", ||
         check::check_wf_old(&ccx));
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1b450092dbd..af6510cb387 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -261,7 +261,7 @@ pub fn main_args(args: &[String]) -> isize {
 
     match (should_test, markdown_input) {
         (true, true) => {
-            return markdown::test(input, libs, externs, test_args)
+            return markdown::test(input, cfgs, libs, externs, test_args)
         }
         (true, false) => {
             return test::run(input, cfgs, libs, externs, test_args, crate_name)
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index ac64fd3bec0..03d2c1a1b4d 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -142,13 +142,13 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
 }
 
 /// Run any tests/code examples in the markdown file `input`.
-pub fn test(input: &str, libs: SearchPaths, externs: core::Externs,
+pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: core::Externs,
             mut test_args: Vec<String>) -> isize {
     let input_str = load_or_return!(input, 1, 2);
 
     let mut opts = TestOptions::default();
     opts.no_crate_inject = true;
-    let mut collector = Collector::new(input.to_string(), libs, externs,
+    let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
                                        true, opts);
     find_testable_code(&input_str, &mut collector);
     test_args.insert(0, "rustdoctest".to_string());
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 3e303b29d5c..3322794c778 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -85,7 +85,7 @@ pub fn run(input: &str,
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let mut cfg = config::build_configuration(&sess);
-    cfg.extend(config::parse_cfgspecs(cfgs));
+    cfg.extend(config::parse_cfgspecs(cfgs.clone()));
     let krate = driver::phase_1_parse_input(&sess, cfg, &input);
     let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate,
                                                      "rustdoc-test", None)
@@ -122,6 +122,7 @@ pub fn run(input: &str,
     let (krate, _) = passes::unindent_comments(krate);
 
     let mut collector = Collector::new(krate.name.to_string(),
+                                       cfgs,
                                        libs,
                                        externs,
                                        false,
@@ -168,7 +169,7 @@ fn scrape_test_config(krate: &::rustc_front::hir::Crate) -> TestOptions {
     return opts;
 }
 
-fn runtest(test: &str, cratename: &str, libs: SearchPaths,
+fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
            externs: core::Externs,
            should_panic: bool, no_run: bool, as_test_harness: bool,
            opts: &TestOptions) {
@@ -239,7 +240,8 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
 
     let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
     let out = Some(outdir.path().to_path_buf());
-    let cfg = config::build_configuration(&sess);
+    let mut cfg = config::build_configuration(&sess);
+    cfg.extend(config::parse_cfgspecs(cfgs));
     let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
     let mut control = driver::CompileController::basic();
     if no_run {
@@ -349,6 +351,7 @@ fn partition_source(s: &str) -> (String, String) {
 pub struct Collector {
     pub tests: Vec<testing::TestDescAndFn>,
     names: Vec<String>,
+    cfgs: Vec<String>,
     libs: SearchPaths,
     externs: core::Externs,
     cnt: usize,
@@ -359,11 +362,12 @@ pub struct Collector {
 }
 
 impl Collector {
-    pub fn new(cratename: String, libs: SearchPaths, externs: core::Externs,
+    pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: core::Externs,
                use_headers: bool, opts: TestOptions) -> Collector {
         Collector {
             tests: Vec::new(),
             names: Vec::new(),
+            cfgs: cfgs,
             libs: libs,
             externs: externs,
             cnt: 0,
@@ -384,6 +388,7 @@ impl Collector {
             format!("{}_{}", self.names.join("::"), self.cnt)
         };
         self.cnt += 1;
+        let cfgs = self.cfgs.clone();
         let libs = self.libs.clone();
         let externs = self.externs.clone();
         let cratename = self.cratename.to_string();
@@ -399,6 +404,7 @@ impl Collector {
             testfn: testing::DynTestFn(Box::new(move|| {
                 runtest(&test,
                         &cratename,
+                        cfgs,
                         libs,
                         externs,
                         should_panic,
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 5b8307eb6c6..16764e5af5c 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -79,8 +79,8 @@ pub use self::ParseResult::*;
 use self::TokenTreeOrTokenTreeVec::*;
 
 use ast;
-use ast::{TokenTree, Name};
-use codemap::{BytePos, mk_sp, Span};
+use ast::{TokenTree, Name, Ident};
+use codemap::{BytePos, mk_sp, Span, Spanned};
 use codemap;
 use parse::lexer::*; //resolve bug?
 use parse::ParseSess;
@@ -526,7 +526,10 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
         "ty" => token::NtTy(panictry!(p.parse_ty())),
         // this could be handled like a token, since it is one
         "ident" => match p.token {
-            token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(Box::new(sn),b) }
+            token::Ident(sn,b) => {
+                panictry!(p.bump());
+                token::NtIdent(Box::new(Spanned::<Ident>{node: sn, span: p.span}),b)
+            }
             _ => {
                 let token_str = pprust::token_to_string(&p.token);
                 panic!(p.fatal(&format!("expected ident, found {}",
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 0fc31f3fd08..ba781ae3cc2 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -293,8 +293,8 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                             // (a) idents can be in lots of places, so it'd be a pain
                             // (b) we actually can, since it's a token.
                             MatchedNonterminal(NtIdent(ref sn, b)) => {
-                                r.cur_span = sp;
-                                r.cur_tok = token::Ident(**sn, b);
+                                r.cur_span = sn.span;
+                                r.cur_tok = token::Ident(sn.node, b);
                                 return ret_val;
                             }
                             MatchedNonterminal(ref other_whole_nt) => {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index c637813f07e..cd976884d2f 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -663,7 +663,8 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
         token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
         token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
         token::NtIdent(id, is_mod_name) =>
-            token::NtIdent(Box::new(fld.fold_ident(*id)), is_mod_name),
+            token::NtIdent(Box::new(Spanned::<Ident>{node: fld.fold_ident(id.node), .. *id}),
+                           is_mod_name),
         token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
         token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))),
         token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&tt))),
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 17b7d8dbaec..b942954c187 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -377,7 +377,7 @@ pub enum Nonterminal {
     NtPat(P<ast::Pat>),
     NtExpr(P<ast::Expr>),
     NtTy(P<ast::Ty>),
-    NtIdent(Box<ast::Ident>, IdentStyle),
+    NtIdent(Box<ast::SpannedIdent>, IdentStyle),
     /// Stuff inside brackets for attributes
     NtMeta(P<ast::MetaItem>),
     NtPath(Box<ast::Path>),
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 0be62bc0a7f..4e2289cb7f4 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -295,7 +295,7 @@ pub fn token_to_string(tok: &Token) -> String {
             token::NtBlock(ref e)       => block_to_string(&**e),
             token::NtStmt(ref e)        => stmt_to_string(&**e),
             token::NtPat(ref e)         => pat_to_string(&**e),
-            token::NtIdent(ref e, _)    => ident_to_string(**e),
+            token::NtIdent(ref e, _)    => ident_to_string(e.node),
             token::NtTT(ref e)          => tt_to_string(&**e),
             token::NtArm(ref e)         => arm_to_string(&*e),
             token::NtImplItem(ref e)    => impl_item_to_string(&**e),
diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/compile-fail-fulldeps/qquote.rs
index 7ffbbe69c3d..3e153a21e5d 100644
--- a/src/test/compile-fail-fulldeps/qquote.rs
+++ b/src/test/compile-fail-fulldeps/qquote.rs
@@ -23,7 +23,8 @@ fn main() {
     let ps = syntax::parse::ParseSess::new();
     let mut cx = syntax::ext::base::ExtCtxt::new(
         &ps, vec![],
-        syntax::ext::expand::ExpansionConfig::default("qquote".to_string()));
+        syntax::ext::expand::ExpansionConfig::default("qquote".to_string()),
+        &mut Vec::new());
     cx.bt_push(syntax::codemap::ExpnInfo {
         call_site: DUMMY_SP,
         callee: syntax::codemap::NameAndSpan {
diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs
index 915cb077787..6d68da54112 100644
--- a/src/test/compile-fail/associated-types-coherence-failure.rs
+++ b/src/test/compile-fail/associated-types-coherence-failure.rs
@@ -32,13 +32,13 @@ impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
 impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
 //~^ ERROR E0119
     fn into_cow(self) -> Cow<'a, B> {
-        Cow
+        Cow(PhantomData)
     }
 }
 
 impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned {
     fn into_cow(self) -> Cow<'a, B> {
-        Cow
+        Cow(PhantomData)
     }
 }
 
diff --git a/src/test/compile-fail/bogus-tag.rs b/src/test/compile-fail/bogus-tag.rs
index 704d856f106..a1021500be3 100644
--- a/src/test/compile-fail/bogus-tag.rs
+++ b/src/test/compile-fail/bogus-tag.rs
@@ -9,14 +9,12 @@
 // except according to those terms.
 
 
-// error-pattern: unresolved
-
 enum color { rgb(isize, isize, isize), rgba(isize, isize, isize, isize), }
 
 fn main() {
-    let red: color = rgb(255, 0, 0);
+    let red: color = color::rgb(255, 0, 0);
     match red {
-      rgb(r, g, b) => { println!("rgb"); }
-      hsl(h, s, l) => { println!("hsl"); }
+      color::rgb(r, g, b) => { println!("rgb"); }
+      color::hsl(h, s, l) => { println!("hsl"); }  //~ ERROR no associated
     }
 }
diff --git a/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs b/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs
index ce6baeb204c..b08e4bad1e9 100644
--- a/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs
+++ b/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs
@@ -13,7 +13,9 @@
 
 // If the trait is not object-safe, we give a more tailored message
 // because we're such schnuckels:
-trait NotObjectSafe { fn eq(&self, other: Self); }
-impl NotObjectSafe for NotObjectSafe { } //~ ERROR E0372
+trait NotObjectSafe { fn eq(&self, other: &Self); }
+impl NotObjectSafe for NotObjectSafe {  //~ ERROR E0372
+    fn eq(&self, other: &Self) { panic!(); }
+}
 
 fn main() { }
diff --git a/src/test/compile-fail/coherence-impls-copy.rs b/src/test/compile-fail/coherence-impls-copy.rs
index 1be606c3546..9c210c132a3 100644
--- a/src/test/compile-fail/coherence-impls-copy.rs
+++ b/src/test/compile-fail/coherence-impls-copy.rs
@@ -28,8 +28,6 @@ impl Copy for MyType {}
 
 impl Copy for &'static mut MyType {}
 //~^ ERROR E0206
-//~| ERROR E0277
-//~| ERROR E0277
 impl Clone for MyType { fn clone(&self) -> Self { *self } }
 
 impl Copy for (MyType, MyType) {}
@@ -42,8 +40,6 @@ impl Copy for &'static NotSync {}
 impl Copy for [MyType] {}
 //~^ ERROR E0206
 //~| ERROR E0117
-//~| ERROR E0277
-//~| ERROR E0277
 
 impl Copy for &'static [NotSync] {}
 //~^ ERROR E0206
diff --git a/src/test/compile-fail/coherence-impls-sized.rs b/src/test/compile-fail/coherence-impls-sized.rs
index 2ac4bb0492b..167067cb5fc 100644
--- a/src/test/compile-fail/coherence-impls-sized.rs
+++ b/src/test/compile-fail/coherence-impls-sized.rs
@@ -30,7 +30,6 @@ impl Sized for (MyType, MyType) {} //~ ERROR E0117
 impl Sized for &'static NotSync {} //~ ERROR E0322
 
 impl Sized for [MyType] {} //~ ERROR E0117
-//~^ ERROR E0277
 
 impl Sized for &'static [NotSync] {} //~ ERROR E0117
 
diff --git a/src/test/compile-fail/duplicate-type-parameter.rs b/src/test/compile-fail/duplicate-type-parameter.rs
index 42b67337c64..3b0f8ee5bda 100644
--- a/src/test/compile-fail/duplicate-type-parameter.rs
+++ b/src/test/compile-fail/duplicate-type-parameter.rs
@@ -33,6 +33,7 @@ trait Qux<T,T> {}
 
 impl<T,T> Qux<T,T> for Option<T> {}
 //~^ ERROR the name `T` is already used
+//~^^ ERROR the type parameter `T` is not constrained
 
 fn main() {
 }
diff --git a/src/test/compile-fail/inner-static-type-parameter.rs b/src/test/compile-fail/inner-static-type-parameter.rs
index cf2a70deee5..56b681378cc 100644
--- a/src/test/compile-fail/inner-static-type-parameter.rs
+++ b/src/test/compile-fail/inner-static-type-parameter.rs
@@ -10,7 +10,7 @@
 
 // see #9186
 
-enum Bar<T> { What }
+enum Bar<T> { What } //~ ERROR parameter `T` is never used
 
 fn foo<T>() {
     static a: Bar<T> = Bar::What;
diff --git a/src/test/compile-fail/issue-12796.rs b/src/test/compile-fail/issue-12796.rs
index 2249741cdaa..33fbdce4ee2 100644
--- a/src/test/compile-fail/issue-12796.rs
+++ b/src/test/compile-fail/issue-12796.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 trait Trait {
-    fn outer(self) {
-        fn inner(_: Self) {
+    fn outer(&self) {
+        fn inner(_: &Self) {
             //~^ ERROR can't use type parameters from outer function
             //~^^ ERROR use of `Self` outside of an impl or trait
         }
diff --git a/src/test/compile-fail/issue-14254.rs b/src/test/compile-fail/issue-14254.rs
index ce5fa1f1fe1..5f8ccd0b063 100644
--- a/src/test/compile-fail/issue-14254.rs
+++ b/src/test/compile-fail/issue-14254.rs
@@ -11,7 +11,7 @@
 trait Foo {
     fn bar(&self);
     fn baz(&self) { }
-    fn bah(_: Option<Self>) { }
+    fn bah(_: Option<&Self>) { }
 }
 
 struct BarTy {
diff --git a/src/test/compile-fail/issue-19883.rs b/src/test/compile-fail/issue-19883.rs
index c6ff82364b3..7ec3093a6e0 100644
--- a/src/test/compile-fail/issue-19883.rs
+++ b/src/test/compile-fail/issue-19883.rs
@@ -14,7 +14,7 @@ trait From<Src> {
     fn from(src: Src) -> <Self as From<Src>>::Output;
 }
 
-trait To {
+trait To: Sized {
     fn to<Dst: From<Self>>(self) ->
         <Dst as From<Self>>::Dst
         //~^ ERROR use of undeclared associated type `From::Dst`
diff --git a/src/test/compile-fail/issue-20427.rs b/src/test/compile-fail/issue-20427.rs
index a4b25ab9e56..99dd22a888c 100644
--- a/src/test/compile-fail/issue-20427.rs
+++ b/src/test/compile-fail/issue-20427.rs
@@ -62,7 +62,7 @@ fn usize<'usize>(usize: &'usize usize) -> &'usize usize { usize }
 fn main() {
     let bool = true;
     match bool {
-        str @ true => if str { i32 as i64 } else { 0 },
+        str @ true => if str { i32 as i64 } else { i64 },
         false => i64,
-    }
+    };
 }
diff --git a/src/test/compile-fail/issue-23305.rs b/src/test/compile-fail/issue-23305.rs
index 4b1010781ff..68f053c357b 100644
--- a/src/test/compile-fail/issue-23305.rs
+++ b/src/test/compile-fail/issue-23305.rs
@@ -13,5 +13,6 @@ pub trait ToNbt<T> {
 }
 
 impl ToNbt<Self> {} //~ ERROR use of `Self` outside of an impl or trait
+//~^ WARNING the trait `ToNbt` cannot be made into an object
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-2356.rs b/src/test/compile-fail/issue-2356.rs
index 48cc27e2289..6b81afe13c6 100644
--- a/src/test/compile-fail/issue-2356.rs
+++ b/src/test/compile-fail/issue-2356.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 trait Groom {
-    fn shave();
+    fn shave(other: usize);
 }
 
 pub struct cat {
@@ -30,7 +30,7 @@ impl MaybeDog {
 }
 
 impl Groom for cat {
-  fn shave(&self, other: usize) {
+  fn shave(other: usize) {
     whiskers -= other;
     //~^ ERROR: unresolved name `whiskers`. Did you mean `self.whiskers`?
     shave(4);
diff --git a/src/test/compile-fail/issue-28109.rs b/src/test/compile-fail/issue-28109.rs
index 73163caa455..0d372d30015 100644
--- a/src/test/compile-fail/issue-28109.rs
+++ b/src/test/compile-fail/issue-28109.rs
@@ -11,10 +11,12 @@
 // Make sure that label for continue and break is spanned correctly
 
 fn main() {
-    continue
-    'b //~ ERROR use of undeclared label
-    ;
-    break
-    'c //~ ERROR use of undeclared label
-    ;
+    loop {
+        continue
+        'b //~ ERROR use of undeclared label
+        ;
+        break
+        'c //~ ERROR use of undeclared label
+        ;
+    }
 }
diff --git a/src/test/compile-fail/issue-3021-d.rs b/src/test/compile-fail/issue-3021-d.rs
index 594f68e1812..ecc8ac34ecf 100644
--- a/src/test/compile-fail/issue-3021-d.rs
+++ b/src/test/compile-fail/issue-3021-d.rs
@@ -13,13 +13,13 @@ trait siphash {
     fn reset(&self);
 }
 
-fn siphash(k0 : u64, k1 : u64) -> siphash {
+fn siphash(k0 : u64, k1 : u64) {
     struct SipState {
         v0: u64,
         v1: u64,
     }
 
-    fn mk_result(st : SipState) -> u64 {
+    fn mk_result(st : &SipState) -> u64 {
 
         let v0 = st.v0;
         let v1 = st.v1;
diff --git a/src/test/compile-fail/issue-3021.rs b/src/test/compile-fail/issue-3021.rs
index 719eef1b63d..7cf772b0728 100644
--- a/src/test/compile-fail/issue-3021.rs
+++ b/src/test/compile-fail/issue-3021.rs
@@ -12,7 +12,7 @@ trait SipHash {
     fn reset(&self);
 }
 
-fn siphash(k0 : u64) -> SipHash {
+fn siphash(k0 : u64) {
     struct SipState {
         v0: u64,
     }
diff --git a/src/test/compile-fail/issue-3214.rs b/src/test/compile-fail/issue-3214.rs
index be49ca1fe06..27b7fb75275 100644
--- a/src/test/compile-fail/issue-3214.rs
+++ b/src/test/compile-fail/issue-3214.rs
@@ -15,6 +15,8 @@ fn foo<T>() {
     }
 
     impl<T> Drop for foo<T> {
+        //~^ ERROR wrong number of type arguments
+        //~^^ ERROR the type parameter `T` is not constrained
         fn drop(&mut self) {}
     }
 }
diff --git a/src/test/compile-fail/issue-3521.rs b/src/test/compile-fail/issue-3521.rs
index f06aa45ac38..34cd8cae2de 100644
--- a/src/test/compile-fail/issue-3521.rs
+++ b/src/test/compile-fail/issue-3521.rs
@@ -16,6 +16,7 @@ fn main() {
         Bar = foo
         //~^ ERROR attempt to use a non-constant value in a constant
         //~| ERROR unresolved name `foo`
+        //~^^^ ERROR constant evaluation error: non-constant path in constant expression
     }
 
     println!("{}", Stuff::Bar);
diff --git a/src/test/compile-fail/issue-3973.rs b/src/test/compile-fail/issue-3973.rs
index 2652fb5dfc2..1fda423e9ee 100644
--- a/src/test/compile-fail/issue-3973.rs
+++ b/src/test/compile-fail/issue-3973.rs
@@ -30,5 +30,7 @@ impl ToString_ for Point {
 
 fn main() {
     let p = Point::new(0.0, 0.0);
+    //~^ ERROR no associated item named `new` found for type `Point` in the current scope
     println!("{}", p.to_string());
+    //~^ ERROR the type of this value must be known in this context
 }
diff --git a/src/test/compile-fail/issue-5927.rs b/src/test/compile-fail/issue-5927.rs
index 0359248b36a..e5f091d873d 100644
--- a/src/test/compile-fail/issue-5927.rs
+++ b/src/test/compile-fail/issue-5927.rs
@@ -9,12 +9,10 @@
 // except according to those terms.
 
 
-
-// error-pattern:unresolved enum variant
-
 fn main() {
     let z = match 3 {
-        x(1) => x(1)
+        x(1) => x(1) //~ ERROR unresolved enum variant
+        //~^ ERROR unresolved name `x`
     };
-    assert_eq!(z,3);
+    assert!(z == 3);
 }
diff --git a/src/test/compile-fail/issue-9725.rs b/src/test/compile-fail/issue-9725.rs
index 1a3c926ba38..f53122d19c1 100644
--- a/src/test/compile-fail/issue-9725.rs
+++ b/src/test/compile-fail/issue-9725.rs
@@ -13,4 +13,5 @@ struct A { foo: isize }
 fn main() {
     let A { foo, foo } = A { foo: 3 };
     //~^ ERROR: identifier `foo` is bound more than once in the same pattern
+    //~^^ ERROR: field `foo` bound multiple times
 }
diff --git a/src/test/compile-fail/macro-parameter-span.rs b/src/test/compile-fail/macro-parameter-span.rs
new file mode 100644
index 00000000000..2ef69759128
--- /dev/null
+++ b/src/test/compile-fail/macro-parameter-span.rs
@@ -0,0 +1,23 @@
+// 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! foo {
+    ($id: ident) => {
+        $id
+    }
+}
+
+// Testing that the error span points to the parameter 'x' in the callsite,
+// not to the macro variable '$id'
+fn main() {
+    foo!(
+        x //~ ERROR unresolved name `x`
+        );
+}
diff --git a/src/test/compile-fail/mod_file_correct_spans.rs b/src/test/compile-fail/mod_file_correct_spans.rs
index 3b794da1053..f8ea5dda183 100644
--- a/src/test/compile-fail/mod_file_correct_spans.rs
+++ b/src/test/compile-fail/mod_file_correct_spans.rs
@@ -13,5 +13,5 @@
 mod mod_file_aux;
 
 fn main() {
-    assert_eq!(mod_file_aux::bar(), 10); //~ ERROR unresolved name
+    assert!(mod_file_aux::bar() == 10); //~ ERROR unresolved name
 }
diff --git a/src/test/compile-fail/opt-in-copy.rs b/src/test/compile-fail/opt-in-copy.rs
index be321b62903..bc18b52a0c1 100644
--- a/src/test/compile-fail/opt-in-copy.rs
+++ b/src/test/compile-fail/opt-in-copy.rs
@@ -16,7 +16,6 @@ struct IWantToCopyThis {
 
 impl Copy for IWantToCopyThis {}
 //~^ ERROR the trait `Copy` may not be implemented for this type
-//~| ERROR E0277
 
 enum CantCopyThisEither {
     A,
@@ -29,6 +28,5 @@ enum IWantToCopyThisToo {
 
 impl Copy for IWantToCopyThisToo {}
 //~^ ERROR the trait `Copy` may not be implemented for this type
-//~| ERROR E0277
 
 fn main() {}
diff --git a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs
index cdb81279048..284c08ef09b 100644
--- a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs
+++ b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs
@@ -16,6 +16,7 @@ fn matcher1(x: opts) {
     match x {
       opts::a(ref i) | opts::b(i) => {}
       //~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
+      //~^^ ERROR mismatched types
       opts::c(_) => {}
     }
 }
@@ -24,6 +25,7 @@ fn matcher2(x: opts) {
     match x {
       opts::a(ref i) | opts::b(i) => {}
       //~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
+      //~^^ ERROR mismatched types
       opts::c(_) => {}
     }
 }
@@ -32,6 +34,7 @@ fn matcher4(x: opts) {
     match x {
       opts::a(ref mut i) | opts::b(ref i) => {}
       //~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
+      //~^^ ERROR mismatched types
       opts::c(_) => {}
     }
 }
diff --git a/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs
index 341fe173a03..88f09233d10 100644
--- a/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs
+++ b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs
@@ -15,6 +15,7 @@
 trait TraitA<A> {
     fn outer(self) {
         enum Foo<B> {
+            //~^ ERROR parameter `B` is never used
             Variance(A)
                 //~^ ERROR can't use type parameters from outer function
                 //~^^ ERROR use of undeclared type name `A`
@@ -27,6 +28,7 @@ trait TraitB<A> {
         struct Foo<B>(A);
                 //~^ ERROR can't use type parameters from outer function
                 //~^^ ERROR use of undeclared type name `A`
+                //~^^^ ERROR parameter `B` is never used
     }
 }
 
@@ -35,6 +37,7 @@ trait TraitC<A> {
         struct Foo<B> { a: A }
                 //~^ ERROR can't use type parameters from outer function
                 //~^^ ERROR use of undeclared type name `A`
+                //~^^^ ERROR parameter `B` is never used
     }
 }
 
diff --git a/src/test/compile-fail/syntax-extension-minor.rs b/src/test/compile-fail/syntax-extension-minor.rs
index 506aed6b2ee..38a6834a9c4 100644
--- a/src/test/compile-fail/syntax-extension-minor.rs
+++ b/src/test/compile-fail/syntax-extension-minor.rs
@@ -14,7 +14,7 @@
 
 pub fn main() {
     let asdf_fdsa = "<.<".to_string();
-    assert_eq!(concat_idents!(asd, f_f, dsa), "<.<".to_string());
+    assert!(concat_idents!(asd, f_f, dsa) == "<.<".to_string());
     //~^ ERROR: unresolved name `asdf_fdsa`
 
     assert_eq!(stringify!(use_mention_distinction), "use_mention_distinction");
diff --git a/src/test/compile-fail/trait-safety-trait-impl-cc.rs b/src/test/compile-fail/trait-safety-trait-impl-cc.rs
index 6050b549b65..f30c8f521bd 100644
--- a/src/test/compile-fail/trait-safety-trait-impl-cc.rs
+++ b/src/test/compile-fail/trait-safety-trait-impl-cc.rs
@@ -18,7 +18,7 @@ extern crate trait_safety_lib as lib;
 struct Bar;
 impl lib::Foo for Bar { //~ ERROR requires an `unsafe impl` declaration
     fn foo(&self) -> isize {
-        *self as isize
+        panic!();
     }
 }
 
diff --git a/src/test/compile-fail/trait-safety-trait-impl.rs b/src/test/compile-fail/trait-safety-trait-impl.rs
index 1bd6d763607..e846b660c2a 100644
--- a/src/test/compile-fail/trait-safety-trait-impl.rs
+++ b/src/test/compile-fail/trait-safety-trait-impl.rs
@@ -12,11 +12,11 @@
 // impls cannot be unsafe.
 
 trait SafeTrait {
-    fn foo(self) { }
+    fn foo(&self) { }
 }
 
 unsafe trait UnsafeTrait {
-    fn foo(self) { }
+    fn foo(&self) { }
 }
 
 unsafe impl UnsafeTrait for u8 { } // OK
diff --git a/src/test/rustdoc/issue-30252.rs b/src/test/rustdoc/issue-30252.rs
new file mode 100644
index 00000000000..11d161fe188
--- /dev/null
+++ b/src/test/rustdoc/issue-30252.rs
@@ -0,0 +1,16 @@
+// 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.
+
+// compile-flags:--test --cfg feature="bar"
+
+/// ```rust
+/// assert_eq!(cfg!(feature = "bar"), true);
+/// ```
+pub fn foo() {}