about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark-Simulacrum <mark.simulacrum@gmail.com>2016-11-13 19:42:15 -0700
committerMark-Simulacrum <mark.simulacrum@gmail.com>2016-11-28 06:37:08 -0700
commit64e97d9b33ac7a38ec9f0ae1575771cdad4afac0 (patch)
tree5553e369ac533cba86775a2e24e0358ed316e33a
parent607af7218b31ed00c8f613deedf8f4f7ae59cd13 (diff)
downloadrust-64e97d9b33ac7a38ec9f0ae1575771cdad4afac0.tar.gz
rust-64e97d9b33ac7a38ec9f0ae1575771cdad4afac0.zip
Remove BuiltinBound and BuiltinBounds.
-rw-r--r--src/librustc/infer/mod.rs6
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/lang_items.rs25
-rw-r--r--src/librustc/traits/error_reporting.rs10
-rw-r--r--src/librustc/traits/fulfill.rs21
-rw-r--r--src/librustc/traits/mod.rs45
-rw-r--r--src/librustc/traits/select.rs16
-rw-r--r--src/librustc/traits/structural_impls.rs5
-rw-r--r--src/librustc/traits/util.rs31
-rw-r--r--src/librustc/ty/error.rs14
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc/ty/relate.rs17
-rw-r--r--src/librustc/ty/structural_impls.rs11
-rw-r--r--src/librustc/ty/sty.rs70
-rw-r--r--src/librustc/ty/util.rs16
-rw-r--r--src/librustc/ty/wf.rs16
-rw-r--r--src/librustc/util/ppaux.rs13
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs7
-rw-r--r--src/librustc_typeck/check/cast.rs5
-rw-r--r--src/librustc_typeck/check/closure.rs3
-rw-r--r--src/librustc_typeck/check/method/suggest.rs3
-rw-r--r--src/librustc_typeck/check/mod.rs21
-rw-r--r--src/librustc_typeck/check/wfcheck.rs19
-rw-r--r--src/librustc_typeck/coherence/overlap.rs6
-rw-r--r--src/librustc_typeck/variance/constraints.rs3
-rw-r--r--src/librustdoc/clean/mod.rs57
-rw-r--r--src/test/compile-fail/bad-sized.rs4
-rw-r--r--src/test/compile-fail/const-unsized.rs8
-rw-r--r--src/test/compile-fail/issue-32963.rs2
-rw-r--r--src/test/compile-fail/trait-bounds-cant-coerce.rs8
-rw-r--r--src/test/compile-fail/trait-bounds-not-on-bare-trait.rs2
31 files changed, 138 insertions, 333 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 6ae104d7912..9c63eac34e4 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -24,6 +24,7 @@ use middle::free_region::FreeRegionMap;
 use middle::mem_categorization as mc;
 use middle::mem_categorization::McResult;
 use middle::region::CodeExtent;
+use middle::lang_items;
 use mir::tcx::LvalueTy;
 use ty::subst::{Kind, Subst, Substs};
 use ty::adjustment;
@@ -1492,11 +1493,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
         }
 
+        let copy_def_id = self.tcx.lang_items.require(lang_items::CopyTraitLangItem)
+            .unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
+
         // this can get called from typeck (by euv), and moves_by_default
         // rightly refuses to work with inference variables, but
         // moves_by_default has a cache, which we want to use in other
         // cases.
-        !traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
+        !traits::type_known_to_meet_bound(self, ty, copy_def_id, span)
     }
 
     pub fn node_method_ty(&self, method_call: ty::MethodCall)
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 0942ce79a6b..c0ea8d6b1e3 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -32,7 +32,6 @@
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![cfg_attr(stage0, feature(dotdot_in_tuple_patterns))]
-#![feature(enumset)]
 #![cfg_attr(stage0, feature(item_like_imports))]
 #![feature(libc)]
 #![feature(nonzero)]
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 5af9a2f0274..8d02d63e3a4 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -90,31 +90,6 @@ impl LanguageItems {
         self.require(OwnedBoxLangItem)
     }
 
-    pub fn from_builtin_kind(&self, bound: ty::BuiltinBound)
-                             -> Result<DefId, String>
-    {
-        match bound {
-            ty::BoundSend => self.require(SendTraitLangItem),
-            ty::BoundSized => self.require(SizedTraitLangItem),
-            ty::BoundCopy => self.require(CopyTraitLangItem),
-            ty::BoundSync => self.require(SyncTraitLangItem),
-        }
-    }
-
-    pub fn to_builtin_kind(&self, id: DefId) -> Option<ty::BuiltinBound> {
-        if Some(id) == self.send_trait() {
-            Some(ty::BoundSend)
-        } else if Some(id) == self.sized_trait() {
-            Some(ty::BoundSized)
-        } else if Some(id) == self.copy_trait() {
-            Some(ty::BoundCopy)
-        } else if Some(id) == self.sync_trait() {
-            Some(ty::BoundSync)
-        } else {
-            None
-        }
-    }
-
     pub fn fn_trait_kind(&self, id: DefId) -> Option<ty::ClosureKind> {
         let def_id_kinds = [
             (self.fn_trait(), ty::ClosureKind::Fn),
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 21009711cb1..4ac4c31386e 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -905,16 +905,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             ObligationCauseCode::StructInitializerSized => {
                 err.note("structs must have a statically known size to be initialized");
             }
-            ObligationCauseCode::ClosureCapture(var_id, _, builtin_bound) => {
-                let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap();
-                let trait_name = tcx.item_path_str(def_id);
-                let name = tcx.local_var_name_str(var_id);
-                err.note(
-                    &format!("the closure that captures `{}` requires that all captured variables \
-                              implement the trait `{}`",
-                             name,
-                             trait_name));
-            }
             ObligationCauseCode::FieldSized => {
                 err.note("only the last field of a struct may have a dynamically sized type");
             }
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index f406580286d..9ff4048f73e 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -17,8 +17,8 @@ use rustc_data_structures::obligation_forest::{ForestObligation, ObligationProce
 use std::marker::PhantomData;
 use std::mem;
 use syntax::ast;
-use util::common::ErrorReported;
 use util::nodemap::{FxHashSet, NodeMap};
+use hir::def_id::DefId;
 
 use super::CodeAmbiguity;
 use super::CodeProjectionError;
@@ -230,18 +230,21 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
         normalized.value
     }
 
-    pub fn register_builtin_bound(&mut self,
+    pub fn register_bound(&mut self,
                                   infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                                   ty: Ty<'tcx>,
-                                  builtin_bound: ty::BuiltinBound,
+                                  def_id: DefId,
                                   cause: ObligationCause<'tcx>)
     {
-        match infcx.tcx.predicate_for_builtin_bound(cause, builtin_bound, 0, ty) {
-            Ok(predicate) => {
-                self.register_predicate_obligation(infcx, predicate);
-            }
-            Err(ErrorReported) => { }
-        }
+        let trait_ref = ty::TraitRef {
+            def_id: def_id,
+            substs: infcx.tcx.mk_substs_trait(ty, &[]),
+        };
+        self.register_predicate_obligation(infcx, Obligation {
+            cause: cause,
+            recursion_depth: 0,
+            predicate: trait_ref.to_predicate()
+        });
     }
 
     pub fn register_region_obligation(&mut self,
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index a5fdaed9712..bdd0ee75eb1 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -19,7 +19,7 @@ use hir;
 use hir::def_id::DefId;
 use middle::free_region::FreeRegionMap;
 use ty::subst::Substs;
-use ty::{self, Ty, TyCtxt, TypeFoldable};
+use ty::{self, Ty, TyCtxt, TypeFoldable, ToPredicate};
 use infer::InferCtxt;
 
 use std::rc::Rc;
@@ -125,10 +125,6 @@ pub enum ObligationCauseCode<'tcx> {
     ReturnType,                // Return type must be Sized
     RepeatVec,                 // [T,..n] --> T must be Copy
 
-    // Captures of variable the given id by a closure (span is the
-    // span of the closure)
-    ClosureCapture(ast::NodeId, Span, ty::BuiltinBound),
-
     // Types of fields (other than the last) in a struct must be sized.
     FieldSized,
 
@@ -369,27 +365,30 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
 /// `bound` or is not known to meet bound (note that this is
 /// conservative towards *no impl*, which is the opposite of the
 /// `evaluate` methods).
-pub fn type_known_to_meet_builtin_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                                                         ty: Ty<'tcx>,
-                                                        bound: ty::BuiltinBound,
+                                                        def_id: DefId,
                                                         span: Span)
                                                         -> bool
 {
-    debug!("type_known_to_meet_builtin_bound(ty={:?}, bound={:?})",
+    debug!("type_known_to_meet_bound(ty={:?}, bound={:?})",
            ty,
-           bound);
-
-    let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID);
-    let obligation =
-        infcx.tcx.predicate_for_builtin_bound(cause, bound, 0, ty);
-    let obligation = match obligation {
-        Ok(o) => o,
-        Err(..) => return false
+           infcx.tcx.item_path_str(def_id));
+
+    let trait_ref = ty::TraitRef {
+        def_id: def_id,
+        substs: infcx.tcx.mk_substs_trait(ty, &[]),
     };
+    let obligation = Obligation {
+        cause: ObligationCause::misc(span, ast::DUMMY_NODE_ID),
+        recursion_depth: 0,
+        predicate: trait_ref.to_predicate(),
+    };
+
     let result = SelectionContext::new(infcx)
         .evaluate_obligation_conservatively(&obligation);
-    debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} => {:?}",
-           ty, bound, result);
+    debug!("type_known_to_meet_ty={:?} bound={} => {:?}",
+           ty, infcx.tcx.item_path_str(def_id), result);
 
     if result && (ty.has_infer_types() || ty.has_closure_types()) {
         // Because of inference "guessing", selection can sometimes claim
@@ -404,22 +403,22 @@ pub fn type_known_to_meet_builtin_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'g
         // anyhow).
         let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID);
 
-        fulfill_cx.register_builtin_bound(infcx, ty, bound, cause);
+        fulfill_cx.register_bound(infcx, ty, def_id, cause);
 
         // Note: we only assume something is `Copy` if we can
         // *definitively* show that it implements `Copy`. Otherwise,
         // assume it is move; linear is always ok.
         match fulfill_cx.select_all_or_error(infcx) {
             Ok(()) => {
-                debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} success",
+                debug!("type_known_to_meet_bound: ty={:?} bound={} success",
                        ty,
-                       bound);
+                       infcx.tcx.item_path_str(def_id));
                 true
             }
             Err(e) => {
-                debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} errors={:?}",
+                debug!("type_known_to_meet_bound: ty={:?} bound={} errors={:?}",
                        ty,
-                       bound,
+                       infcx.tcx.item_path_str(def_id),
                        e);
                 false
             }
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 3ae0252e990..11b23d699de 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -1093,8 +1093,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         // Other bounds. Consider both in-scope bounds from fn decl
         // and applicable impls. There is a certain set of precedence rules here.
 
-        match self.tcx().lang_items.to_builtin_kind(obligation.predicate.def_id()) {
-            Some(ty::BoundCopy) => {
+        let def_id = obligation.predicate.def_id();
+        match obligation.predicate.def_id() {
+            _ if self.tcx().lang_items.copy_trait() == Some(def_id) => {
                 debug!("obligation self ty is {:?}",
                        obligation.predicate.0.self_ty());
 
@@ -1106,7 +1107,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 let copy_conditions = self.copy_conditions(obligation);
                 self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates)?;
             }
-            Some(ty::BoundSized) => {
+            _ if self.tcx().lang_items.sized_trait() == Some(def_id) => {
                 // Sized is never implementable by end-users, it is
                 // always automatically computed.
                 let sized_conditions = self.sized_conditions(obligation);
@@ -1114,14 +1115,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                                                        &mut candidates)?;
             }
 
-            None if self.tcx().lang_items.unsize_trait() ==
-                    Some(obligation.predicate.def_id()) => {
+            _ if self.tcx().lang_items.unsize_trait() == Some(def_id) => {
                 self.assemble_candidates_for_unsizing(obligation, &mut candidates);
             }
 
-            Some(ty::BoundSend) |
-            Some(ty::BoundSync) |
-            None => {
+            // For non-builtins and Send/Sync
+            _ => {
                 self.assemble_closure_candidates(obligation, &mut candidates)?;
                 self.assemble_fn_pointer_candidates(obligation, &mut candidates)?;
                 self.assemble_candidates_from_impls(obligation, &mut candidates)?;
@@ -2483,7 +2482,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     data_b.auto_traits().collect(),
                     data_a.projection_bounds.clone(),
                 ));
-                let origin = TypeOrigin::Misc(obligation.cause.span);
                 let InferOk { obligations, .. } =
                     self.infcx.sub_types(false, &obligation.cause, new_trait, target)
                     .map_err(|_| Unimplemented)?;
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index d03ba5b0a31..dedb126d7ff 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -190,9 +190,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             super::VariableType(id) => Some(super::VariableType(id)),
             super::ReturnType => Some(super::ReturnType),
             super::RepeatVec => Some(super::RepeatVec),
-            super::ClosureCapture(node_id, span, bound) => {
-                Some(super::ClosureCapture(node_id, span, bound))
-            }
             super::FieldSized => Some(super::FieldSized),
             super::ConstSized => Some(super::ConstSized),
             super::SharedStatic => Some(super::SharedStatic),
@@ -507,7 +504,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
             super::VariableType(_) |
             super::ReturnType |
             super::RepeatVec |
-            super::ClosureCapture(..) |
             super::FieldSized |
             super::ConstSized |
             super::SharedStatic |
@@ -552,7 +548,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
             super::VariableType(_) |
             super::ReturnType |
             super::RepeatVec |
-            super::ClosureCapture(..) |
             super::FieldSized |
             super::ConstSized |
             super::SharedStatic |
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index b94597d4759..321936fe54b 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -12,7 +12,6 @@ use hir::def_id::DefId;
 use ty::subst::{Subst, Substs};
 use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
 use ty::outlives::Component;
-use util::common::ErrorReported;
 use util::nodemap::FxHashSet;
 
 use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
@@ -408,25 +407,6 @@ pub fn predicate_for_trait_ref<'tcx>(
 }
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-    pub fn trait_ref_for_builtin_bound(self,
-        builtin_bound: ty::BuiltinBound,
-        param_ty: Ty<'tcx>)
-        -> Result<ty::TraitRef<'tcx>, ErrorReported>
-    {
-        match self.lang_items.from_builtin_kind(builtin_bound) {
-            Ok(def_id) => {
-                Ok(ty::TraitRef {
-                    def_id: def_id,
-                    substs: self.mk_substs_trait(param_ty, &[])
-                })
-            }
-            Err(e) => {
-                self.sess.err(&e);
-                Err(ErrorReported)
-            }
-        }
-    }
-
     pub fn predicate_for_trait_def(self,
         cause: ObligationCause<'tcx>,
         trait_def_id: DefId,
@@ -442,17 +422,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         predicate_for_trait_ref(cause, trait_ref, recursion_depth)
     }
 
-    pub fn predicate_for_builtin_bound(self,
-        cause: ObligationCause<'tcx>,
-        builtin_bound: ty::BuiltinBound,
-        recursion_depth: usize,
-        param_ty: Ty<'tcx>)
-        -> Result<PredicateObligation<'tcx>, ErrorReported>
-    {
-        let trait_ref = self.trait_ref_for_builtin_bound(builtin_bound, param_ty)?;
-        Ok(predicate_for_trait_ref(cause, trait_ref, recursion_depth))
-    }
-
     /// Cast a trait reference into a reference to one of its super
     /// traits; returns `None` if `target_trait_def_id` is not a
     /// supertrait.
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 8bdcc93fa21..8ef13e62901 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -45,7 +45,6 @@ pub enum TypeError<'tcx> {
     IntMismatch(ExpectedFound<ty::IntVarValue>),
     FloatMismatch(ExpectedFound<ast::FloatTy>),
     Traits(ExpectedFound<DefId>),
-    BuiltinBoundsMismatch(ExpectedFound<ty::BuiltinBounds>),
     VariadicMismatch(ExpectedFound<bool>),
     CyclicTy,
     ProjectionNameMismatched(ExpectedFound<Name>),
@@ -135,19 +134,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
                                        format!("trait `{}`",
                                                tcx.item_path_str(values.found)))
             }),
-            BuiltinBoundsMismatch(values) => {
-                if values.expected.is_empty() {
-                    write!(f, "expected no bounds, found `{}`",
-                           values.found)
-                } else if values.found.is_empty() {
-                    write!(f, "expected bounds `{}`, found no bounds",
-                           values.expected)
-                } else {
-                    write!(f, "expected bounds `{}`, found bounds `{}`",
-                           values.expected,
-                           values.found)
-                }
-            }
             IntMismatch(ref values) => {
                 write!(f, "expected `{:?}`, found `{:?}`",
                        values.expected,
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 844fc58cec3..4544cda0ae9 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -53,7 +53,6 @@ use hir;
 use hir::itemlikevisit::ItemLikeVisitor;
 
 pub use self::sty::{Binder, DebruijnIndex};
-pub use self::sty::{BuiltinBound, BuiltinBounds};
 pub use self::sty::{BareFnTy, FnSig, PolyFnSig};
 pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, TraitObject};
 pub use self::sty::{ClosureSubsts, TypeAndMut};
@@ -68,11 +67,6 @@ pub use self::sty::InferTy::*;
 pub use self::sty::Region::*;
 pub use self::sty::TypeVariants::*;
 
-pub use self::sty::BuiltinBound::Send as BoundSend;
-pub use self::sty::BuiltinBound::Sized as BoundSized;
-pub use self::sty::BuiltinBound::Copy as BoundCopy;
-pub use self::sty::BuiltinBound::Sync as BoundSync;
-
 pub use self::contents::TypeContents;
 pub use self::context::{TyCtxt, tls};
 pub use self::context::{CtxtArenas, Lift, Tables};
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 569791a0776..02704e94fee 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -302,23 +302,6 @@ impl<'tcx> Relate<'tcx> for Vec<ty::PolyExistentialProjection<'tcx>> {
     }
 }
 
-impl<'tcx> Relate<'tcx> for ty::BuiltinBounds {
-    fn relate<'a, 'gcx, R>(relation: &mut R,
-                           a: &ty::BuiltinBounds,
-                           b: &ty::BuiltinBounds)
-                           -> RelateResult<'tcx, ty::BuiltinBounds>
-        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
-    {
-        // Two sets of builtin bounds are only relatable if they are
-        // precisely the same (but see the coercion code).
-        if a != b {
-            Err(TypeError::BuiltinBoundsMismatch(expected_found(relation, a, b)))
-        } else {
-            Ok(*a)
-        }
-    }
-}
-
 impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
     fn relate<'a, 'gcx, R>(relation: &mut R,
                            a: &ty::TraitRef<'tcx>,
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 3064e337039..e890d750a7b 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -315,7 +315,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
             Traits(x) => Traits(x),
-            BuiltinBoundsMismatch(x) => BuiltinBoundsMismatch(x),
             VariadicMismatch(x) => VariadicMismatch(x),
             CyclicTy => CyclicTy,
             ProjectionNameMismatched(x) => ProjectionNameMismatched(x),
@@ -703,16 +702,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::BuiltinBounds {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
-        *self
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
-        false
-    }
-}
-
 impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         ty::TypeParameterDef {
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 22a7423b177..e6411ca1e4f 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -14,13 +14,10 @@ use hir::def_id::DefId;
 
 use middle::region;
 use ty::subst::Substs;
-use ty::{self, AdtDef, ToPredicate, TypeFlags, Ty, TyCtxt, TypeFoldable};
+use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
 use ty::{Slice, TyS};
-use util::common::ErrorReported;
 
-use collections::enum_set::{self, EnumSet, CLike};
 use std::fmt;
-use std::ops;
 use syntax::abi;
 use syntax::ast::{self, Name, NodeId};
 use syntax::symbol::{keywords, InternedString};
@@ -770,71 +767,6 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct BuiltinBounds(EnumSet<BuiltinBound>);
-
-impl<'a, 'gcx, 'tcx> BuiltinBounds {
-    pub fn empty() -> BuiltinBounds {
-        BuiltinBounds(EnumSet::new())
-    }
-
-    pub fn iter(&self) -> enum_set::Iter<BuiltinBound> {
-        self.into_iter()
-    }
-
-    pub fn to_predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                         self_ty: Ty<'tcx>)
-                         -> Vec<ty::Predicate<'tcx>> {
-        self.iter().filter_map(|builtin_bound|
-            match tcx.trait_ref_for_builtin_bound(builtin_bound, self_ty) {
-                Ok(trait_ref) => Some(trait_ref.to_predicate()),
-                Err(ErrorReported) => { None }
-            }
-        ).collect()
-    }
-}
-
-impl ops::Deref for BuiltinBounds {
-    type Target = EnumSet<BuiltinBound>;
-    fn deref(&self) -> &Self::Target { &self.0 }
-}
-
-impl ops::DerefMut for BuiltinBounds {
-    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
-}
-
-impl<'a> IntoIterator for &'a BuiltinBounds {
-    type Item = BuiltinBound;
-    type IntoIter = enum_set::Iter<BuiltinBound>;
-    fn into_iter(self) -> Self::IntoIter {
-        (**self).into_iter()
-    }
-}
-
-#[derive(Clone, RustcEncodable, PartialEq, Eq, RustcDecodable, Hash,
-           Debug, Copy)]
-pub enum BuiltinBound {
-    Send = 0,
-    Sized = 1,
-    Copy = 2,
-    Sync = 3,
-}
-
-impl CLike for BuiltinBound {
-    fn to_usize(&self) -> usize {
-        *self as usize
-    }
-    fn from_usize(v: usize) -> BuiltinBound {
-        match v {
-            0 => BuiltinBound::Send,
-            1 => BuiltinBound::Sized,
-            2 => BuiltinBound::Copy,
-            3 => BuiltinBound::Sync,
-            _ => bug!("{} is not a valid BuiltinBound", v)
-        }
-    }
-}
-
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn try_add_builtin_trait(self,
                                  id: DefId,
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 7253b88981f..350426e7f3e 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -21,6 +21,7 @@ use ty::fold::TypeVisitor;
 use ty::layout::{Layout, LayoutError};
 use ty::TypeVariants::*;
 use util::nodemap::FxHashMap;
+use middle::lang_items;
 
 use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
 
@@ -599,7 +600,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
 impl<'a, 'tcx> ty::TyS<'tcx> {
     fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                    param_env: &ParameterEnvironment<'tcx>,
-                   bound: ty::BuiltinBound,
+                   def_id: DefId,
                    cache: &RefCell<FxHashMap<Ty<'tcx>, bool>>,
                    span: Span) -> bool
     {
@@ -611,7 +612,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
         let result =
             tcx.infer_ctxt(None, Some(param_env.clone()), Reveal::ExactMatch)
             .enter(|infcx| {
-                traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span)
+                traits::type_known_to_meet_bound(&infcx, self, def_id, span)
             });
         if self.has_param_types() || self.has_self_ty() {
             cache.borrow_mut().insert(self, result);
@@ -644,8 +645,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
             TyClosure(..) | TyAdt(..) | TyAnon(..) |
             TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
         }.unwrap_or_else(|| {
-            !self.impls_bound(tcx, param_env, ty::BoundCopy, &param_env.is_copy_cache, span)
-        });
+            !self.impls_bound(tcx, param_env,
+                              tcx.lang_items.require(lang_items::CopyTraitLangItem)
+                                .unwrap_or_else(|msg| tcx.sess.fatal(&msg[..])),
+                              &param_env.is_copy_cache, span) });
 
         if !self.has_param_types() && !self.has_self_ty() {
             self.flags.set(self.flags.get() | if result {
@@ -686,8 +689,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
             TyAdt(..) | TyProjection(..) | TyParam(..) |
             TyInfer(..) | TyAnon(..) | TyError => None
         }.unwrap_or_else(|| {
-            self.impls_bound(tcx, param_env, ty::BoundSized, &param_env.is_sized_cache, span)
-        });
+            self.impls_bound(tcx, param_env, tcx.lang_items.require(lang_items::SizedTraitLangItem)
+                              .unwrap_or_else(|msg| tcx.sess.fatal(&msg[..])),
+                              &param_env.is_copy_cache, span) });
 
         if !self.has_param_types() && !self.has_self_ty() {
             self.flags.set(self.flags.get() | if result {
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index b31046abf86..d0bc2f07977 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -17,7 +17,7 @@ use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use std::iter::once;
 use syntax::ast;
 use syntax_pos::Span;
-use util::common::ErrorReported;
+use middle::lang_items;
 
 /// Returns the set of obligations needed to make `ty` well-formed.
 /// If `ty` contains unresolved inference variables, this may include
@@ -282,14 +282,12 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
     fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
         if !subty.has_escaping_regions() {
             let cause = self.cause(cause);
-            match self.infcx.tcx.trait_ref_for_builtin_bound(ty::BoundSized, subty) {
-                Ok(trait_ref) => {
-                    self.out.push(
-                        traits::Obligation::new(cause,
-                                                trait_ref.to_predicate()));
-                }
-                Err(ErrorReported) => { }
-            }
+            let trait_ref = ty::TraitRef {
+                def_id: self.infcx.tcx.lang_items.require(lang_items::SizedTraitLangItem)
+                    .unwrap_or_else(|msg| self.infcx.tcx.sess.fatal(&msg[..])),
+                substs: self.infcx.tcx.mk_substs_trait(subty, &[]),
+            };
+            self.out.push(traits::Obligation::new(cause, trait_ref.to_predicate()));
         }
     }
 
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index a3fa805699c..242342a7f93 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -683,19 +683,6 @@ impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
     }
 }
 
-impl fmt::Display for ty::BuiltinBounds {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let mut bounds = self.iter();
-        if let Some(bound) = bounds.next() {
-            write!(f, "{:?}", bound)?;
-            for bound in bounds {
-                write!(f, " + {:?}", bound)?;
-            }
-        }
-        Ok(())
-    }
-}
-
 impl fmt::Debug for ty::TyVid {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "_#{}t", self.index)
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 4ff2beb3fdb..9cd92cf1fdc 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -29,6 +29,7 @@ use rustc::mir::traversal::ReversePostorder;
 use rustc::mir::transform::{Pass, MirPass, MirSource};
 use rustc::mir::visit::{LvalueContext, Visitor};
 use rustc::util::nodemap::DefIdMap;
+use rustc::middle::lang_items;
 use syntax::abi::Abi;
 use syntax::feature_gate::UnstableFeatures;
 use syntax_pos::Span;
@@ -1046,7 +1047,11 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
             tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
                 let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
                 let mut fulfillment_cx = traits::FulfillmentContext::new();
-                fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
+                fulfillment_cx.register_bound(&infcx, ty,
+                                              tcx.lang_items
+                                                .require(lang_items::SyncTraitLangItem)
+                                                .unwrap_or_else(|msg| tcx.sess.fatal(&msg[..])),
+                                              cause);
                 if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
                     infcx.report_fulfillment_errors(&err);
                 }
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 3e1a3c870ca..197e7793f4b 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -46,6 +46,7 @@ use rustc::hir;
 use rustc::traits;
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::cast::{CastKind, CastTy};
+use rustc::middle::lang_items;
 use syntax::ast;
 use syntax_pos::Span;
 use util::common::ErrorReported;
@@ -543,6 +544,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn type_is_known_to_be_sized(&self, ty: Ty<'tcx>, span: Span) -> bool {
-        traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundSized, span)
+        let lang_item = self.tcx.lang_items.require(lang_items::SizedTraitLangItem)
+                            .unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
+        traits::type_known_to_meet_bound(self, ty, lang_item, span)
     }
 }
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 4627c166fc6..be6d65bf511 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -119,7 +119,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         self.deduce_sig_from_projection(&pb)
                     })
                     .next();
-                let kind = self.tcx.lang_items.fn_trait_kind(object_type.principal().unwrap().def_id());
+                let kind =
+                    self.tcx.lang_items.fn_trait_kind(object_type.principal().unwrap().def_id());
                 (sig, kind)
             }
             ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index eb6e84c7922..508b0e820ce 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -379,7 +379,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             match ty.sty {
                 ty::TyAdt(def, _) => def.did.is_local(),
 
-                ty::TyTrait(ref tr) => tr.principal().map(|p| p.def_id().is_local()).unwrap_or(false),
+                ty::TyTrait(ref tr) => tr.principal().map(|p|
+                                                          p.def_id().is_local()).unwrap_or(false),
 
                 ty::TyParam(_) => true,
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 2babb81bc40..c921936800b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -123,6 +123,7 @@ use rustc::hir::intravisit::{self, Visitor};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::{self, PatKind};
 use rustc::hir::print as pprust;
+use rustc::middle::lang_items;
 use rustc_back::slice;
 use rustc_const_eval::eval_length;
 
@@ -1805,11 +1806,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                               ty: Ty<'tcx>,
                               span: Span,
                               code: traits::ObligationCauseCode<'tcx>,
-                              bound: ty::BuiltinBound)
+                              def_id: DefId)
     {
-        self.register_builtin_bound(
+        self.register_bound(
             ty,
-            bound,
+            def_id,
             traits::ObligationCause::new(span, self.body_id, code));
     }
 
@@ -1818,16 +1819,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                  span: Span,
                                  code: traits::ObligationCauseCode<'tcx>)
     {
-        self.require_type_meets(ty, span, code, ty::BoundSized);
+        let lang_item = self.tcx.lang_items.require(lang_items::SizedTraitLangItem)
+                            .unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
+        self.require_type_meets(ty, span, code, lang_item);
     }
 
-    pub fn register_builtin_bound(&self,
+    pub fn register_bound(&self,
                                   ty: Ty<'tcx>,
-                                  builtin_bound: ty::BuiltinBound,
+                                  def_id: DefId,
                                   cause: traits::ObligationCause<'tcx>)
     {
         self.fulfillment_cx.borrow_mut()
-            .register_builtin_bound(self, ty, builtin_bound, cause);
+            .register_bound(self, ty, def_id, cause);
     }
 
     pub fn register_predicate(&self,
@@ -3899,7 +3902,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             if count > 1 {
                 // For [foo, ..n] where n > 1, `foo` must have
                 // Copy type:
-                self.require_type_meets(t, expr.span, traits::RepeatVec, ty::BoundCopy);
+                let lang_item = self.tcx.lang_items.require(lang_items::CopyTraitLangItem)
+                            .unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
+                self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
             }
 
             if element_ty.references_error() {
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 1ad81660f83..57859f9c84c 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -18,6 +18,7 @@ use middle::region::{CodeExtent};
 use rustc::traits::{self, ObligationCauseCode};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
+use rustc::middle::lang_items;
 
 use syntax::ast;
 use syntax_pos::Span;
@@ -118,12 +119,13 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
 
                 let trait_ref = ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(item.id)).unwrap();
                 ccx.tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id);
-                match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
-                    Some(ty::BoundSend) | Some(ty::BoundSync) => {}
-                    Some(_) | None => {
-                        if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) {
-                            error_192(ccx, item.span);
-                        }
+                let sync_trait = ccx.tcx.lang_items.require(lang_items::SyncTraitLangItem)
+                    .unwrap_or_else(|msg| ccx.tcx.sess.fatal(&msg[..]));
+                let send_trait = ccx.tcx.lang_items.require(lang_items::SendTraitLangItem)
+                    .unwrap_or_else(|msg| ccx.tcx.sess.fatal(&msg[..]));
+                if trait_ref.def_id != sync_trait && trait_ref.def_id != send_trait {
+                    if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) {
+                        error_192(ccx, item.span);
                     }
                 }
             }
@@ -241,9 +243,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
                 // For DST, all intermediate types must be sized.
                 let unsized_len = if all_sized || variant.fields.is_empty() { 0 } else { 1 };
                 for field in &variant.fields[..variant.fields.len() - unsized_len] {
-                    fcx.register_builtin_bound(
+                    fcx.register_bound(
                         field.ty,
-                        ty::BoundSized,
+                        fcx.tcx.lang_items.require(lang_items::SizedTraitLangItem)
+                            .unwrap_or_else(|msg| fcx.tcx.sess.fatal(&msg[..])),
                         traits::ObligationCause::new(field.span,
                                                      fcx.body_id,
                                                      traits::FieldSized));
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index 305b15caa69..5ae233f6479 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -182,14 +182,16 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> {
                     // This is something like impl Trait1 for Trait2. Illegal
                     // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
 
-                    if data.principal().is_none() || !self.tcx.is_object_safe(data.principal().unwrap().def_id()) {
+                    if data.principal().is_none() ||
+                        !self.tcx.is_object_safe(data.principal().unwrap().def_id()) {
                         // This is an error, but it will be
                         // reported by wfcheck.  Ignore it
                         // here. This is tested by
                         // `coherence-impl-trait-for-trait-object-safe.rs`.
                     } else {
                         let mut supertrait_def_ids =
-                            traits::supertrait_def_ids(self.tcx, data.principal().unwrap().def_id());
+                            traits::supertrait_def_ids(self.tcx,
+                                                       data.principal().unwrap().def_id());
                         if supertrait_def_ids.any(|d| d == trait_def_id) {
                             span_err!(self.tcx.sess,
                                       item.span,
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 77ade466069..076d024c1e1 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -376,7 +376,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(generics, data.region_bound, contra);
 
-                let poly_trait_ref = data.principal().unwrap().with_self_ty(self.tcx(), self.tcx().types.err);
+                let poly_trait_ref = data.principal().unwrap().with_self_ty(self.tcx(),
+                    self.tcx().types.err);
                 self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance);
 
                 for projection in &data.projection_bounds {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6b0f0ae1297..9d98cdd3f03 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -30,6 +30,7 @@ use syntax_pos::{self, DUMMY_SP, Pos};
 use rustc_trans::back::link;
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::resolve_lifetime::DefRegion::*;
+use rustc::middle::lang_items;
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::def_id::{self, DefId, DefIndex, CRATE_DEF_INDEX};
 use rustc::hir::print as pprust;
@@ -593,12 +594,21 @@ pub enum TyParamBound {
 
 impl TyParamBound {
     fn maybe_sized(cx: &DocContext) -> TyParamBound {
-        use rustc::hir::TraitBoundModifier as TBM;
-        let mut sized_bound = ty::BoundSized.clean(cx);
-        if let TyParamBound::TraitBound(_, ref mut tbm) = sized_bound {
-            *tbm = TBM::Maybe
-        };
-        sized_bound
+        let did = cx.tcx().lang_items.require(lang_items::SizedTraitLangItem)
+            .unwrap_or_else(|msg| cx.tcx().sess.fatal(&msg[..]));
+        let empty = cx.tcx().intern_substs(&[]);
+        let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
+            Some(did), false, vec![], empty);
+        inline::record_extern_fqn(cx, did, TypeKind::Trait);
+        TraitBound(PolyTrait {
+            trait_: ResolvedPath {
+                path: path,
+                typarams: None,
+                did: did,
+                is_generic: false,
+            },
+            lifetimes: vec![]
+        }, hir::TraitBoundModifier::Maybe)
     }
 
     fn is_sized_bound(&self, cx: &DocContext) -> bool {
@@ -675,37 +685,6 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self
     }
 }
 
-impl Clean<TyParamBound> for ty::BuiltinBound {
-    fn clean(&self, cx: &DocContext) -> TyParamBound {
-        let tcx = cx.tcx;
-        let empty = tcx.intern_substs(&[]);
-        let (did, path) = match *self {
-            ty::BoundSend =>
-                (tcx.lang_items.send_trait().unwrap(),
-                 external_path(cx, "Send", None, false, vec![], empty)),
-            ty::BoundSized =>
-                (tcx.lang_items.sized_trait().unwrap(),
-                 external_path(cx, "Sized", None, false, vec![], empty)),
-            ty::BoundCopy =>
-                (tcx.lang_items.copy_trait().unwrap(),
-                 external_path(cx, "Copy", None, false, vec![], empty)),
-            ty::BoundSync =>
-                (tcx.lang_items.sync_trait().unwrap(),
-                 external_path(cx, "Sync", None, false, vec![], empty)),
-        };
-        inline::record_extern_fqn(cx, did, TypeKind::Trait);
-        TraitBound(PolyTrait {
-            trait_: ResolvedPath {
-                path: path,
-                typarams: None,
-                did: did,
-                is_generic: false,
-            },
-            lifetimes: vec![]
-        }, hir::TraitBoundModifier::None)
-    }
-}
-
 impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
     fn clean(&self, cx: &DocContext) -> TyParamBound {
         inline::record_extern_fqn(cx, self.def_id, TypeKind::Trait);
@@ -1915,8 +1894,8 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
                         });
                     }
 
-                    let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
-                                             Some(did), false, bindings, obj.principal.0.substs);
+                    let path = external_path(cx, &cx.tcx().item_name(did).as_str(), Some(did),
+                        false, bindings, principal.0.substs);
                     ResolvedPath {
                         path: path,
                         typarams: Some(typarams),
diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs
index e9d0b986c11..59a039057f3 100644
--- a/src/test/compile-fail/bad-sized.rs
+++ b/src/test/compile-fail/bad-sized.rs
@@ -12,8 +12,8 @@ trait Trait {}
 
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
-    //~^ ERROR `Trait + Sized: std::marker::Sized` is not satisfied
+    //~^ ERROR the trait bound `Trait + std::marker::Sized: std::marker::Sized` is not satisfied
     //~| ERROR the trait `std::marker::Sized` cannot be made into an object
-    //~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied
+    //~| ERROR the trait bound `Trait + std::marker::Sized: std::marker::Sized` is not satisfied
     //~| ERROR the trait `std::marker::Sized` cannot be made into an object
 }
diff --git a/src/test/compile-fail/const-unsized.rs b/src/test/compile-fail/const-unsized.rs
index 226b567c546..23cff4ac6ad 100644
--- a/src/test/compile-fail/const-unsized.rs
+++ b/src/test/compile-fail/const-unsized.rs
@@ -11,8 +11,8 @@
 use std::fmt::Debug;
 
 const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
-//~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
-//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + Sync + 'static`
+//~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
+//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Syn
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
@@ -23,8 +23,8 @@ const CONST_FOO: str = *"foo";
 //~| NOTE constant expressions must have a statically known size
 
 static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
-//~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
-//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + Sync + 'static`
+//~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
+//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Syn
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
diff --git a/src/test/compile-fail/issue-32963.rs b/src/test/compile-fail/issue-32963.rs
index 8ba95d14931..14ab0dd5f63 100644
--- a/src/test/compile-fail/issue-32963.rs
+++ b/src/test/compile-fail/issue-32963.rs
@@ -16,6 +16,6 @@ fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
 
 fn main() {
     size_of_copy::<Misc+Copy>();
-    //~^ ERROR `Misc + Copy: std::marker::Copy` is not satisfied
+    //~^ ERROR the trait bound `Misc + std::marker::Copy: std::marker::Copy` is not satisfied
     //~| ERROR the trait `std::marker::Copy` cannot be made into an object
 }
diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs
index 1fff812af5b..0bfa328751a 100644
--- a/src/test/compile-fail/trait-bounds-cant-coerce.rs
+++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs
@@ -21,10 +21,10 @@ fn c(x: Box<Foo+Sync+Send>) {
 }
 
 fn d(x: Box<Foo>) {
-    a(x); //~  ERROR mismatched types
-          //~| expected type `Box<Foo + Send + 'static>`
-          //~| found type `Box<Foo + 'static>`
-          //~| expected bounds `Send`, found no bounds
+    a(x); //~ ERROR mismatched types [E0308]
+          //~| NOTE expected type `Box<Foo + std::marker::Send + 'static>`
+          //~| NOTE found type `Box<Foo + 'static>`
+          //~| NOTE expected trait Foo, found a different trait Foo
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
index fd46d1a6296..983c66ec1c4 100644
--- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
+++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
@@ -15,7 +15,7 @@ trait Foo {
 // This should emit the less confusing error, not the more confusing one.
 
 fn foo(_x: Foo + Send) {
-    //~^ ERROR `Foo + Send + 'static: std::marker::Sized` is not satisfied
+    //~^ ERROR the trait bound `Foo + std::marker::Send + 'static: std::marker::Sized` is not
 }
 
 fn main() { }