about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-09-27 11:01:11 +0000
committerbors <bors@rust-lang.org>2015-09-27 11:01:11 +0000
commit638b2608a70171593471b45fb344741a37230b0d (patch)
treedc53b7eac13b589e6e4135493bf24892cd09eb06
parent219eca11b044de3644b3e9101124513c1a842b09 (diff)
parentc34f3eaebc2f805864d3de9c7ce257eb41a6def2 (diff)
downloadrust-638b2608a70171593471b45fb344741a37230b0d.tar.gz
rust-638b2608a70171593471b45fb344741a37230b0d.zip
Auto merge of #28689 - Manishearth:rollup, r=Manishearth
- Successful merges: #28664, #28673, #28681, #28682, #28688
- Failed merges: 
-rw-r--r--src/libcollections/enum_set.rs11
-rw-r--r--src/libcollections/str.rs2
-rw-r--r--src/libcollections/vec.rs2
-rw-r--r--src/libcollections/vec_deque.rs13
-rw-r--r--src/libcollectionstest/lib.rs5
-rw-r--r--src/librustc/middle/infer/mod.rs7
-rw-r--r--src/librustc/middle/reachable.rs14
-rw-r--r--src/librustc/middle/traits/error_reporting.rs36
-rw-r--r--src/librustc/middle/traits/fulfill.rs6
-rw-r--r--src/librustc/middle/traits/mod.rs2
-rw-r--r--src/librustc/middle/traits/object_safety.rs2
-rw-r--r--src/librustc/middle/ty/context.rs4
-rw-r--r--src/librustc/middle/ty/mod.rs20
-rw-r--r--src/librustc_front/lib.rs1
-rw-r--r--src/librustc_lint/builtin.rs19
-rw-r--r--src/librustc_trans/back/archive.rs7
-rw-r--r--src/librustc_trans/back/link.rs4
-rw-r--r--src/librustc_typeck/check/method/confirm.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs10
-rw-r--r--src/librustc_typeck/coherence/mod.rs7
-rw-r--r--src/librustdoc/html/static/main.js7
-rw-r--r--src/libstd/lib.rs4
-rw-r--r--src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs1
-rw-r--r--src/test/compile-fail/associated-types-path-2.rs1
-rw-r--r--src/test/compile-fail/coerce-unsafe-to-closure.rs1
-rw-r--r--src/test/compile-fail/const-eval-overflow-4b.rs2
-rw-r--r--src/test/compile-fail/fn-variance-1.rs2
-rw-r--r--src/test/compile-fail/for-loop-bogosity.rs3
-rw-r--r--src/test/compile-fail/indexing-requires-a-uint.rs1
-rw-r--r--src/test/compile-fail/integral-indexing.rs8
-rw-r--r--src/test/compile-fail/issue-11771.rs2
-rw-r--r--src/test/compile-fail/issue-13352.rs1
-rw-r--r--src/test/compile-fail/issue-14084.rs1
-rw-r--r--src/test/compile-fail/issue-20605.rs3
-rw-r--r--src/test/compile-fail/issue-20692.rs23
-rw-r--r--src/test/compile-fail/issue-2149.rs1
-rw-r--r--src/test/compile-fail/issue-22645.rs4
-rw-r--r--src/test/compile-fail/issue-24352.rs1
-rw-r--r--src/test/compile-fail/issue-28098.rs35
-rw-r--r--src/test/compile-fail/issue-28568.rs23
-rw-r--r--src/test/compile-fail/shift-various-bad-types.rs3
-rw-r--r--src/test/compile-fail/str-idx.rs1
-rw-r--r--src/test/compile-fail/str-mut-idx.rs1
-rw-r--r--src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs1
-rw-r--r--src/test/compile-fail/unboxed-closures-wrong-abi.rs1
-rw-r--r--src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs1
-rw-r--r--src/test/run-make/invalid-staticlib/Makefile5
47 files changed, 195 insertions, 122 deletions
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index 7e7e8ba2356..32cd4193d88 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -49,16 +49,7 @@ impl<E> Clone for EnumSet<E> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<E:CLike + fmt::Debug> fmt::Debug for EnumSet<E> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(fmt, "{{"));
-        let mut first = true;
-        for e in self {
-            if !first {
-                try!(write!(fmt, ", "));
-            }
-            try!(write!(fmt, "{:?}", e));
-            first = false;
-        }
-        write!(fmt, "}}")
+        fmt.debug_set().entries(self).finish()
     }
 }
 
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index a3d38bdd1b3..124fe3fab56 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -506,8 +506,6 @@ impl str {
     ///
     /// # Examples
     /// ```
-    /// #![feature(str_split_at)]
-    ///
     /// let s = "Löwe 老虎 Léopard";
     /// let first_space = s.find(' ').unwrap_or(s.len());
     /// let (a, b) = s.split_at(first_space);
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index a145393e0e3..d645de028ce 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -753,8 +753,6 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(split_off)]
-    ///
     /// let mut vec = vec![1,2,3];
     /// let vec2 = vec.split_off(1);
     /// assert_eq!(vec, [1]);
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 4ee9787c9ec..f7efe9a38df 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -1319,8 +1319,6 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(split_off)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
@@ -1406,8 +1404,6 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(vec_deque_retain)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -1787,14 +1783,7 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for VecDeque<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "["));
-
-        for (i, e) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}", *e));
-        }
-
-        write!(f, "]")
+        f.debug_list().entries(self).finish()
     }
 }
 
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index d84f5bdf107..63c7bc15c8f 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(ascii)]
-#![feature(append)]
 #![feature(binary_heap_extras)]
 #![feature(box_syntax)]
 #![feature(btree_range)]
@@ -29,18 +28,14 @@
 #![feature(set_recovery)]
 #![feature(slice_bytes)]
 #![feature(slice_splits)]
-#![feature(split_off)]
 #![feature(step_by)]
 #![feature(str_char)]
 #![feature(str_escape)]
 #![feature(str_match_indices)]
-#![feature(str_split_at)]
 #![feature(str_utf16)]
-#![feature(box_str)]
 #![feature(test)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
-#![feature(vec_deque_retain)]
 #![feature(vec_push_all)]
 
 #[macro_use] extern crate log;
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 917727907ba..3def56f94a1 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -43,7 +43,7 @@ use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap;
 use syntax::codemap::{Span, DUMMY_SP};
-use util::nodemap::{FnvHashMap, NodeMap};
+use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
 
 use self::combine::CombineFields;
 use self::region_inference::{RegionVarBindings, RegionSnapshot};
@@ -92,6 +92,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
 
     pub fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
 
+    // the set of predicates on which errors have been reported, to
+    // avoid reporting the same error twice.
+    pub reported_trait_errors: RefCell<FnvHashSet<traits::TraitErrorKey<'tcx>>>,
+
     // This is a temporary field used for toggling on normalization in the inference context,
     // as we move towards the approach described here:
     // https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
@@ -374,6 +378,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
         region_vars: RegionVarBindings::new(tcx),
         parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
         fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
+        reported_trait_errors: RefCell::new(FnvHashSet()),
         normalize: false,
         err_count_on_creation: tcx.sess.err_count()
     }
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 3fb3d575f93..017c8f1e42b 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -348,13 +348,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
     // this properly would result in the necessity of computing *type*
     // reachability, which might result in a compile time loss.
     fn mark_destructors_reachable(&mut self) {
-        for adt in self.tcx.adt_defs() {
-            if let Some(destructor_def_id) = adt.destructor() {
-                if destructor_def_id.is_local() {
-                    self.reachable_symbols.insert(destructor_def_id.node);
+        let drop_trait = match self.tcx.lang_items.drop_trait() {
+            Some(id) => self.tcx.lookup_trait_def(id), None => { return }
+        };
+        drop_trait.for_each_impl(self.tcx, |drop_impl| {
+            for destructor in &self.tcx.impl_items.borrow()[&drop_impl] {
+                let destructor_did = destructor.def_id();
+                if destructor_did.is_local() {
+                    self.reachable_symbols.insert(destructor_did.node);
                 }
             }
-        }
+        })
     }
 }
 
diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs
index 25e6036e85a..43b3831604b 100644
--- a/src/librustc/middle/traits/error_reporting.rs
+++ b/src/librustc/middle/traits/error_reporting.rs
@@ -28,11 +28,32 @@ use middle::def_id::DefId;
 use middle::infer::InferCtxt;
 use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty};
 use middle::ty::fold::TypeFoldable;
-use std::collections::HashMap;
+use util::nodemap::{FnvHashMap, FnvHashSet};
+
 use std::fmt;
 use syntax::codemap::Span;
 use syntax::attr::{AttributeMethods, AttrMetaMethods};
 
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct TraitErrorKey<'tcx> {
+    is_warning: bool,
+    span: Span,
+    predicate: ty::Predicate<'tcx>
+}
+
+impl<'tcx> TraitErrorKey<'tcx> {
+    fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>,
+                      e: &FulfillmentError<'tcx>) -> Self {
+        let predicate =
+            infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
+        TraitErrorKey {
+            is_warning: is_warning(&e.obligation),
+            span: e.obligation.cause.span,
+            predicate: infcx.tcx.erase_regions(&predicate)
+        }
+    }
+}
+
 pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                            errors: &Vec<FulfillmentError<'tcx>>) {
     for error in errors {
@@ -42,6 +63,13 @@ pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 
 fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                       error: &FulfillmentError<'tcx>) {
+    let error_key = TraitErrorKey::from_error(infcx, error);
+    debug!("report_fulfillment_errors({:?}) - key={:?}",
+           error, error_key);
+    if !infcx.reported_trait_errors.borrow_mut().insert(error_key) {
+        debug!("report_fulfillment_errors: skipping duplicate");
+        return;
+    }
     match error.code {
         FulfillmentErrorCode::CodeSelectionError(ref e) => {
             report_selection_error(infcx, &error.obligation, e);
@@ -97,7 +125,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                                (gen.name.as_str().to_string(),
                                                 trait_ref.substs.types.get(param, i)
                                                          .to_string())
-                                              }).collect::<HashMap<String, String>>();
+                                              }).collect::<FnvHashMap<String, String>>();
                 generic_map.insert("Self".to_string(),
                                    trait_ref.self_ty().to_string());
                 let parser = Parser::new(&istring);
@@ -308,7 +336,11 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
         "the trait `{}` cannot be made into an object",
         tcx.item_path_str(trait_def_id));
 
+    let mut reported_violations = FnvHashSet();
     for violation in violations {
+        if !reported_violations.insert(violation.clone()) {
+            continue;
+        }
         match violation {
             ObjectSafetyViolation::SizedSelf => {
                 tcx.sess.fileline_note(
diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs
index 29032f0c471..d4e6f693d96 100644
--- a/src/librustc/middle/traits/fulfill.rs
+++ b/src/librustc/middle/traits/fulfill.rs
@@ -49,6 +49,12 @@ pub struct FulfillmentContext<'tcx> {
     // than the `SelectionCache`: it avoids duplicate errors and
     // permits recursive obligations, which are often generated from
     // traits like `Send` et al.
+    //
+    // Note that because of type inference, a predicate can still
+    // occur twice in the predicates list, for example when 2
+    // initially-distinct type variables are unified after being
+    // inserted. Deduplicating the predicate set on selection had a
+    // significant performance cost the last time I checked.
     duplicate_set: FulfilledPredicates<'tcx>,
 
     // A list of all obligations that have been registered with this
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 5dc6f9454a8..a037621f5c0 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -21,10 +21,12 @@ use middle::subst;
 use middle::ty::{self, HasTypeFlags, Ty};
 use middle::ty::fold::TypeFoldable;
 use middle::infer::{self, fixup_err_to_string, InferCtxt};
+
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::{Span, DUMMY_SP};
 
+pub use self::error_reporting::TraitErrorKey;
 pub use self::error_reporting::report_fulfillment_errors;
 pub use self::error_reporting::report_overflow_error;
 pub use self::error_reporting::report_selection_error;
diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs
index 1762233b044..5768e13c5bf 100644
--- a/src/librustc/middle/traits/object_safety.rs
+++ b/src/librustc/middle/traits/object_safety.rs
@@ -27,7 +27,7 @@ use middle::ty::{self, ToPolyTraitRef, Ty};
 use std::rc::Rc;
 use syntax::ast;
 
-#[derive(Debug)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObjectSafetyViolation<'tcx> {
     /// Self : Sized declared on the trait
     SizedSelf,
diff --git a/src/librustc/middle/ty/context.rs b/src/librustc/middle/ty/context.rs
index 31e4765aaaa..f32e86e276c 100644
--- a/src/librustc/middle/ty/context.rs
+++ b/src/librustc/middle/ty/context.rs
@@ -245,9 +245,6 @@ pub struct ctxt<'tcx> {
     /// True if the variance has been computed yet; false otherwise.
     pub variance_computed: Cell<bool>,
 
-    /// A method will be in this list if and only if it is a destructor.
-    pub destructors: RefCell<DefIdSet>,
-
     /// Maps a DefId of a type to a list of its inherent impls.
     /// Contains implementations of methods that are inherent to a type.
     /// Methods in these implementations don't need to be exported.
@@ -475,7 +472,6 @@ impl<'tcx> ctxt<'tcx> {
             normalized_cache: RefCell::new(FnvHashMap()),
             lang_items: lang_items,
             provided_method_sources: RefCell::new(DefIdMap()),
-            destructors: RefCell::new(DefIdSet()),
             inherent_impls: RefCell::new(DefIdMap()),
             impl_items: RefCell::new(DefIdMap()),
             used_unsafe: RefCell::new(NodeSet()),
diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs
index 972f7242808..c3e7fd4ceca 100644
--- a/src/librustc/middle/ty/mod.rs
+++ b/src/librustc/middle/ty/mod.rs
@@ -272,6 +272,20 @@ impl<'tcx> Method<'tcx> {
     }
 }
 
+impl<'tcx> PartialEq for Method<'tcx> {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool { self.def_id == other.def_id }
+}
+
+impl<'tcx> Eq for Method<'tcx> {}
+
+impl<'tcx> Hash for Method<'tcx> {
+    #[inline]
+    fn hash<H: Hasher>(&self, s: &mut H) {
+        self.def_id.hash(s)
+    }
+}
+
 #[derive(Clone, Copy, Debug)]
 pub struct AssociatedConst<'tcx> {
     pub name: Name,
@@ -1681,7 +1695,6 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     }
 
     pub fn set_destructor(&self, dtor: DefId) {
-        assert!(self.destructor.get().is_none());
         self.destructor.set(Some(dtor));
     }
 
@@ -2315,11 +2328,6 @@ impl<'tcx> ctxt<'tcx> {
         self.lookup_adt_def_master(did)
     }
 
-    /// Return the list of all interned ADT definitions
-    pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
-        self.adt_defs.borrow().values().cloned().collect()
-    }
-
     /// Given the did of an item, returns its full set of predicates.
     pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
         lookup_locally_or_in_crate_store(
diff --git a/src/librustc_front/lib.rs b/src/librustc_front/lib.rs
index 4c6d8505c81..fa2c098e2cf 100644
--- a/src/librustc_front/lib.rs
+++ b/src/librustc_front/lib.rs
@@ -36,7 +36,6 @@
 #![feature(staged_api)]
 #![feature(str_char)]
 #![feature(filling_drop)]
-#![cfg_attr(test, feature(test))]
 
 extern crate serialize;
 #[macro_use] extern crate log;
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index d12cd082cab..90f877b29a1 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1210,15 +1210,14 @@ impl LintPass for DropWithReprExtern {
 
 impl LateLintPass for DropWithReprExtern {
     fn check_crate(&mut self, ctx: &LateContext, _: &hir::Crate) {
-        for dtor_did in ctx.tcx.destructors.borrow().iter() {
-            let (drop_impl_did, dtor_self_type) =
-                if dtor_did.is_local() {
-                    let impl_did = ctx.tcx.map.get_parent_did(dtor_did.node);
-                    let ty = ctx.tcx.lookup_item_type(impl_did).ty;
-                    (impl_did, ty)
-                } else {
-                    continue;
-                };
+        let drop_trait = match ctx.tcx.lang_items.drop_trait() {
+            Some(id) => ctx.tcx.lookup_trait_def(id), None => { return }
+        };
+        drop_trait.for_each_impl(ctx.tcx, |drop_impl_did| {
+            if !drop_impl_did.is_local() {
+                return;
+            }
+            let dtor_self_type = ctx.tcx.lookup_item_type(drop_impl_did).ty;
 
             match dtor_self_type.sty {
                 ty::TyEnum(self_type_def, _) |
@@ -1244,6 +1243,6 @@ impl LateLintPass for DropWithReprExtern {
                 }
                 _ => {}
             }
-        }
+        })
     }
 }
diff --git a/src/librustc_trans/back/archive.rs b/src/librustc_trans/back/archive.rs
index 76bbce00f19..1b3242eb97d 100644
--- a/src/librustc_trans/back/archive.rs
+++ b/src/librustc_trans/back/archive.rs
@@ -145,10 +145,13 @@ impl<'a> ArchiveBuilder<'a> {
 
     /// Adds all of the contents of a native library to this archive. This will
     /// search in the relevant locations for a library named `name`.
-    pub fn add_native_library(&mut self, name: &str) -> io::Result<()> {
+    pub fn add_native_library(&mut self, name: &str) {
         let location = find_library(name, &self.config.lib_search_paths,
                                     self.config.sess);
-        self.add_archive(&location, name, |_| false)
+        self.add_archive(&location, name, |_| false).unwrap_or_else(|e| {
+            self.config.sess.fatal(&format!("failed to add native library {}: {}",
+                                            location.to_string_lossy(), e));
+        });
     }
 
     /// Adds all of the contents of the rlib at the specified path to this
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index f25132e1856..4e493e6779c 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -616,7 +616,7 @@ fn link_rlib<'a>(sess: &'a Session,
 
     for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
         match kind {
-            cstore::NativeStatic => ab.add_native_library(&l).unwrap(),
+            cstore::NativeStatic => ab.add_native_library(&l),
             cstore::NativeFramework | cstore::NativeUnknown => {}
         }
     }
@@ -792,7 +792,7 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
         ab.build();
     }
     if !sess.target.target.options.no_compiler_rt {
-        ab.add_native_library("compiler-rt").unwrap();
+        ab.add_native_library("compiler-rt");
     }
 
     let mut all_native_libs = vec![];
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index abdcbf099a5..b0e81803ba7 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -620,13 +620,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
             ty::TraitContainer(trait_def_id) => {
                 callee::check_legal_trait_for_method_call(self.fcx.ccx, self.span, trait_def_id)
             }
-            ty::ImplContainer(..) => {
-                // Since `drop` is a trait method, we expect that any
-                // potential calls to it will wind up in the other
-                // arm. But just to be sure, check that the method id
-                // does not appear in the list of destructors.
-                assert!(!self.tcx().destructors.borrow().contains(&pick.item.def_id()));
-            }
+            ty::ImplContainer(..) => {}
         }
     }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 419fb7aea6c..2003d7eea59 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -431,9 +431,11 @@ pub fn check_item_bodies(ccx: &CrateCtxt) {
 }
 
 pub fn check_drop_impls(ccx: &CrateCtxt) {
-    for drop_method_did in ccx.tcx.destructors.borrow().iter() {
-        if drop_method_did.is_local() {
-            let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node);
+    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(()) => {
@@ -441,7 +443,7 @@ pub fn check_drop_impls(ccx: &CrateCtxt) {
                 }
             }
         }
-    }
+    });
 
     ccx.tcx.sess.abort_if_errors();
 }
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 228f1f0fe44..0c152a419d2 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -126,7 +126,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
         // Populate the table of destructors. It might seem a bit strange to
         // do this here, but it's actually the most convenient place, since
         // the coherence tables contain the trait -> type mappings.
-        self.populate_destructor_table();
+        self.populate_destructors();
 
         // Check to make sure implementations of `Copy` are legal.
         self.check_implementations_of_copy();
@@ -286,7 +286,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
     // Destructors
     //
 
-    fn populate_destructor_table(&self) {
+    fn populate_destructors(&self) {
         let tcx = self.crate_context.tcx;
         let drop_trait = match tcx.lang_items.drop_trait() {
             Some(id) => id, None => { return }
@@ -309,9 +309,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
                 ty::TyEnum(type_def, _) |
                 ty::TyStruct(type_def, _) => {
                     type_def.set_destructor(method_def_id.def_id());
-                    tcx.destructors
-                       .borrow_mut()
-                       .insert(method_def_id.def_id());
                 }
                 _ => {
                     // Destructors only work on nominal types.
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 5b0b19b95af..9dce1b28c97 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -386,6 +386,9 @@
                 if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) {
                     return -1;
                 }
+                if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) {
+                    return 1;
+                }
 
                 // sort by description (no description goes later)
                 a = (aaa.item.desc === '');
@@ -572,6 +575,10 @@
                         displayPath = item.path + '::';
                         href = rootPath + item.path.replace(/::/g, '/') +
                                '/index.html';
+                    } else if (type === "primitive") {
+                        displayPath = "";
+                        href = rootPath + item.path.replace(/::/g, '/') +
+                               '/' + type + '.' + name + '.html';
                     } else if (item.parent !== undefined) {
                         var myparent = item.parent;
                         var anchor = '#' + type + '.' + name;
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 9129ffcc211..10c7190ca0c 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -249,8 +249,8 @@
 #![feature(wrapping)]
 #![feature(zero_one)]
 #![cfg_attr(windows, feature(str_utf16))]
-#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras, hash_default))]
-#![cfg_attr(test, feature(test, rustc_private, float_consts))]
+#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))]
+#![cfg_attr(test, feature(test, rustc_private))]
 #![cfg_attr(target_env = "msvc", feature(link_args))]
 
 // Don't link to std. We are std.
diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
index 4aad828590a..c5a47f3e535 100644
--- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
+++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
@@ -32,5 +32,4 @@ fn ice<A>(a: A) {
     let r = loop {};
     r = r + a;
     //~^ ERROR not implemented
-    //~| ERROR not implemented
 }
diff --git a/src/test/compile-fail/associated-types-path-2.rs b/src/test/compile-fail/associated-types-path-2.rs
index e603cca7f38..c9374d42938 100644
--- a/src/test/compile-fail/associated-types-path-2.rs
+++ b/src/test/compile-fail/associated-types-path-2.rs
@@ -39,7 +39,6 @@ pub fn f1_int_uint() {
 pub fn f1_uint_uint() {
     f1(2u32, 4u32);
     //~^ ERROR the trait `Foo` is not implemented
-    //~| ERROR the trait `Foo` is not implemented
 }
 
 pub fn f1_uint_int() {
diff --git a/src/test/compile-fail/coerce-unsafe-to-closure.rs b/src/test/compile-fail/coerce-unsafe-to-closure.rs
index 27b4a04054f..90cbbf242aa 100644
--- a/src/test/compile-fail/coerce-unsafe-to-closure.rs
+++ b/src/test/compile-fail/coerce-unsafe-to-closure.rs
@@ -11,5 +11,4 @@
 fn main() {
     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
     //~^ ERROR E0277
-    //~| ERROR E0277
 }
diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs
index 6322b56a82f..a8f47ab92e5 100644
--- a/src/test/compile-fail/const-eval-overflow-4b.rs
+++ b/src/test/compile-fail/const-eval-overflow-4b.rs
@@ -23,7 +23,6 @@ const A_I8_T
     : [u32; (i8::MAX as i8 + 1u8) as usize]
     //~^ ERROR mismatched types
     //~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
-    //~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
     = [0; (i8::MAX as usize) + 1];
 
 fn main() {
@@ -33,4 +32,3 @@ fn main() {
 fn foo<T:fmt::Debug>(x: T) {
     println!("{:?}", x);
 }
-
diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs
index 8e1e88a92e4..e9dd1cb719d 100644
--- a/src/test/compile-fail/fn-variance-1.rs
+++ b/src/test/compile-fail/fn-variance-1.rs
@@ -20,10 +20,8 @@ fn main() {
     apply(&3, takes_imm);
     apply(&3, takes_mut);
     //~^ ERROR (values differ in mutability)
-    //~| ERROR (values differ in mutability)
 
     apply(&mut 3, takes_mut);
     apply(&mut 3, takes_imm);
     //~^ ERROR (values differ in mutability)
-    //~| ERROR (values differ in mutability)
 }
diff --git a/src/test/compile-fail/for-loop-bogosity.rs b/src/test/compile-fail/for-loop-bogosity.rs
index 6bc0e74a2eb..c7768304517 100644
--- a/src/test/compile-fail/for-loop-bogosity.rs
+++ b/src/test/compile-fail/for-loop-bogosity.rs
@@ -25,9 +25,6 @@ pub fn main() {
         y: 2,
     };
     for x in bogus { //~ ERROR `core::iter::Iterator` is not implemented for the type `MyStruct`
-    //~^ ERROR
-    //~^^ ERROR
-    // FIXME(#21528) not fulfilled obligation error should be reported once, not thrice
         drop(x);
     }
 }
diff --git a/src/test/compile-fail/indexing-requires-a-uint.rs b/src/test/compile-fail/indexing-requires-a-uint.rs
index 3ca00fcb66a..3d3b7bc1bcb 100644
--- a/src/test/compile-fail/indexing-requires-a-uint.rs
+++ b/src/test/compile-fail/indexing-requires-a-uint.rs
@@ -14,7 +14,6 @@
 fn main() {
     fn bar<T>(_: T) {}
     [0][0u8]; //~ ERROR: the trait `core::ops::Index<u8>` is not implemented
-    //~^ ERROR: the trait `core::ops::Index<u8>` is not implemented
 
     [0][0]; // should infer to be a usize
 
diff --git a/src/test/compile-fail/integral-indexing.rs b/src/test/compile-fail/integral-indexing.rs
index e2fb0fa4f2f..f78d677679b 100644
--- a/src/test/compile-fail/integral-indexing.rs
+++ b/src/test/compile-fail/integral-indexing.rs
@@ -14,21 +14,13 @@ pub fn main() {
     v[3_usize];
     v[3];
     v[3u8];  //~ERROR the trait `core::ops::Index<u8>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<u8>` is not implemented
     v[3i8];  //~ERROR the trait `core::ops::Index<i8>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<i8>` is not implemented
     v[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<u32>` is not implemented
     v[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<i32>` is not implemented
     s.as_bytes()[3_usize];
     s.as_bytes()[3];
     s.as_bytes()[3u8];  //~ERROR the trait `core::ops::Index<u8>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<u8>` is not implemented
     s.as_bytes()[3i8];  //~ERROR the trait `core::ops::Index<i8>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<i8>` is not implemented
     s.as_bytes()[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<u32>` is not implemented
     s.as_bytes()[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<i32>` is not implemented
 }
diff --git a/src/test/compile-fail/issue-11771.rs b/src/test/compile-fail/issue-11771.rs
index 40fc6b1ed6a..69899105bc3 100644
--- a/src/test/compile-fail/issue-11771.rs
+++ b/src/test/compile-fail/issue-11771.rs
@@ -12,12 +12,10 @@ fn main() {
     let x = ();
     1 +
     x //~^ ERROR E0277
-      //~| ERROR E0277
     ;
 
     let x: () = ();
     1 +
     x //~^ ERROR E0277
-      //~| ERROR E0277
     ;
 }
diff --git a/src/test/compile-fail/issue-13352.rs b/src/test/compile-fail/issue-13352.rs
index 14128a0e6f7..13e677d72bc 100644
--- a/src/test/compile-fail/issue-13352.rs
+++ b/src/test/compile-fail/issue-13352.rs
@@ -18,5 +18,4 @@ fn main() {
     });
     2_usize + (loop {});
     //~^ ERROR E0277
-    //~| ERROR E0277
 }
diff --git a/src/test/compile-fail/issue-14084.rs b/src/test/compile-fail/issue-14084.rs
index b2863202ef0..6b19cb0b68f 100644
--- a/src/test/compile-fail/issue-14084.rs
+++ b/src/test/compile-fail/issue-14084.rs
@@ -14,5 +14,4 @@
 fn main() {
     in () { 0 };
     //~^ ERROR: the trait `core::ops::Placer<_>` is not implemented
-    //~| ERROR: the trait `core::ops::Placer<_>` is not implemented
 }
diff --git a/src/test/compile-fail/issue-20605.rs b/src/test/compile-fail/issue-20605.rs
index 87b7616db8e..f2d65af9cdf 100644
--- a/src/test/compile-fail/issue-20605.rs
+++ b/src/test/compile-fail/issue-20605.rs
@@ -11,9 +11,6 @@
 fn changer<'a>(mut things: Box<Iterator<Item=&'a mut u8>>) {
     for item in *things { *item = 0 }
 //~^ ERROR the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator
-//~^^ ERROR
-//~^^^ ERROR
-// FIXME(#21528) error should be reported once, not thrice
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-20692.rs b/src/test/compile-fail/issue-20692.rs
new file mode 100644
index 00000000000..62d775adac3
--- /dev/null
+++ b/src/test/compile-fail/issue-20692.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.
+
+trait Array: Sized {}
+
+fn f<T: Array>(x: &T) {
+    let _ = x
+    //~^ ERROR `Array` cannot be made into an object
+    //~| NOTE the trait cannot require that `Self : Sized`
+    as
+    &Array;
+    //~^ ERROR `Array` cannot be made into an object
+    //~| NOTE the trait cannot require that `Self : Sized`
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs
index bb170ef7d00..256c5d8e6f7 100644
--- a/src/test/compile-fail/issue-2149.rs
+++ b/src/test/compile-fail/issue-2149.rs
@@ -17,7 +17,6 @@ impl<A> vec_monad<A> for Vec<A> {
         let mut r = panic!();
         for elt in self { r = r + f(*elt); }
         //~^ ERROR E0277
-        //~| ERROR E0277
    }
 }
 fn main() {
diff --git a/src/test/compile-fail/issue-22645.rs b/src/test/compile-fail/issue-22645.rs
index 8677934fd64..aa7fa82fa29 100644
--- a/src/test/compile-fail/issue-22645.rs
+++ b/src/test/compile-fail/issue-22645.rs
@@ -23,7 +23,5 @@ impl<RHS: Scalar> Add <RHS> for Bob {
 fn main() {
   let b = Bob + 3.5;
   b + 3 //~ ERROR: is not implemented
-  //~^ ERROR: is not implemented
-  //~^^ ERROR: is not implemented
-  //~^^^ ERROR: mismatched types
+  //~^ ERROR: mismatched types
 }
diff --git a/src/test/compile-fail/issue-24352.rs b/src/test/compile-fail/issue-24352.rs
index 0fbc634826b..9936f67b3af 100644
--- a/src/test/compile-fail/issue-24352.rs
+++ b/src/test/compile-fail/issue-24352.rs
@@ -11,5 +11,4 @@
 fn main() {
     1.0f64 - 1.0;
     1.0f64 - 1 //~ ERROR: is not implemented
-    //~^ ERROR: is not implemented
 }
diff --git a/src/test/compile-fail/issue-28098.rs b/src/test/compile-fail/issue-28098.rs
new file mode 100644
index 00000000000..f565d24e1fd
--- /dev/null
+++ b/src/test/compile-fail/issue-28098.rs
@@ -0,0 +1,35 @@
+// 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() {
+    let _ = Iterator::next(&mut ());
+    //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+    for _ in false {}
+    //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+    let _ = Iterator::next(&mut ());
+    //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+    other()
+}
+
+pub fn other() {
+    // check errors are still reported globally
+
+    let _ = Iterator::next(&mut ());
+    //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+    let _ = Iterator::next(&mut ());
+    //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+    for _ in false {}
+    //~^ ERROR the trait `core::iter::Iterator` is not implemented
+}
diff --git a/src/test/compile-fail/issue-28568.rs b/src/test/compile-fail/issue-28568.rs
new file mode 100644
index 00000000000..36b4a57eb11
--- /dev/null
+++ b/src/test/compile-fail/issue-28568.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.
+
+struct MyStruct;
+
+impl Drop for MyStruct {
+//~^ ERROR conflicting implementations for trait
+    fn drop(&mut self) { }
+}
+
+impl Drop for MyStruct {
+//~^ NOTE conflicting implementation here
+    fn drop(&mut self) { }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/shift-various-bad-types.rs b/src/test/compile-fail/shift-various-bad-types.rs
index 24b66213b39..c980572fa15 100644
--- a/src/test/compile-fail/shift-various-bad-types.rs
+++ b/src/test/compile-fail/shift-various-bad-types.rs
@@ -18,15 +18,12 @@ struct Panolpy {
 fn foo(p: &Panolpy) {
     22 >> p.char;
     //~^ ERROR E0277
-    //~| ERROR E0277
 
     22 >> p.str;
     //~^ ERROR E0277
-    //~| ERROR E0277
 
     22 >> p;
     //~^ ERROR E0277
-    //~| ERROR E0277
 
     let x;
     22 >> x; // ambiguity error winds up being suppressed
diff --git a/src/test/compile-fail/str-idx.rs b/src/test/compile-fail/str-idx.rs
index ddd2a4eeedf..6e48ae20d09 100644
--- a/src/test/compile-fail/str-idx.rs
+++ b/src/test/compile-fail/str-idx.rs
@@ -11,5 +11,4 @@
 pub fn main() {
     let s: &str = "hello";
     let c: u8 = s[4]; //~ ERROR the trait `core::ops::Index<_>` is not implemented
-    //~^ ERROR the trait `core::ops::Index<_>` is not implemented
 }
diff --git a/src/test/compile-fail/str-mut-idx.rs b/src/test/compile-fail/str-mut-idx.rs
index 73abe6cb59d..ec6a14778a4 100644
--- a/src/test/compile-fail/str-mut-idx.rs
+++ b/src/test/compile-fail/str-mut-idx.rs
@@ -17,7 +17,6 @@ fn mutate(s: &mut str) {
     s[1usize] = bot();
     //~^ ERROR `core::ops::Index<usize>` is not implemented for the type `str`
     //~| ERROR `core::ops::IndexMut<usize>` is not implemented for the type `str`
-    //~| ERROR `core::ops::Index<usize>` is not implemented for the type `str`
 }
 
 pub fn main() {}
diff --git a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
index dc7c70ba649..361df93a716 100644
--- a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
+++ b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
@@ -35,7 +35,6 @@ fn b() {
 fn c() {
     let z = call_it_once(square, 22);
     //~^ ERROR not implemented
-    //~| ERROR not implemented
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/unboxed-closures-wrong-abi.rs b/src/test/compile-fail/unboxed-closures-wrong-abi.rs
index cdcb435b65a..ca15d1bb5ee 100644
--- a/src/test/compile-fail/unboxed-closures-wrong-abi.rs
+++ b/src/test/compile-fail/unboxed-closures-wrong-abi.rs
@@ -35,7 +35,6 @@ fn b() {
 fn c() {
     let z = call_it_once(square, 22);
     //~^ ERROR not implemented
-    //~| ERROR not implemented
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs
index 150bf36dcc2..b960362aad7 100644
--- a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs
+++ b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs
@@ -36,7 +36,6 @@ fn b() {
 fn c() {
     let z = call_it_once(square, 22);
     //~^ ERROR not implemented
-    //~| ERROR not implemented
 }
 
 fn main() { }
diff --git a/src/test/run-make/invalid-staticlib/Makefile b/src/test/run-make/invalid-staticlib/Makefile
new file mode 100644
index 00000000000..d4aa6d5e720
--- /dev/null
+++ b/src/test/run-make/invalid-staticlib/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all:
+	touch $(TMPDIR)/libfoo.a
+	echo | $(RUSTC) - --crate-type=rlib -lstatic=foo 2>&1 | grep "failed to add native library"