about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-04-21 18:59:58 +0300
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-04-30 15:09:11 +0300
commitbd1f73420ab22faa8087a6cf1618225d09d64f9e (patch)
tree21bd33c08808c31875ccd333e769ea66b695a1eb
parentf0bd14f7b15b978f8bf32bb368f63faa0f26c02e (diff)
downloadrust-bd1f73420ab22faa8087a6cf1618225d09d64f9e.tar.gz
rust-bd1f73420ab22faa8087a6cf1618225d09d64f9e.zip
Stop using Rc in TraitRef and TraitDef
The former stopped making sense when we started interning substs and made
TraitRef a 2-word copy type, and I'm moving the latter into an arena as
they live as long as the type context.
-rw-r--r--src/librustc/metadata/csearch.rs2
-rw-r--r--src/librustc/metadata/decoder.rs6
-rw-r--r--src/librustc/metadata/encoder.rs10
-rw-r--r--src/librustc/metadata/tydecode.rs9
-rw-r--r--src/librustc/metadata/tyencode.rs12
-rw-r--r--src/librustc/middle/astencode.rs11
-rw-r--r--src/librustc/middle/const_eval.rs4
-rw-r--r--src/librustc/middle/implicator.rs5
-rw-r--r--src/librustc/middle/infer/error_reporting.rs11
-rw-r--r--src/librustc/middle/infer/mod.rs13
-rw-r--r--src/librustc/middle/traits/coherence.rs5
-rw-r--r--src/librustc/middle/traits/error_reporting.rs2
-rw-r--r--src/librustc/middle/traits/project.rs11
-rw-r--r--src/librustc/middle/traits/select.rs6
-rw-r--r--src/librustc/middle/traits/util.rs19
-rw-r--r--src/librustc/middle/ty.rs58
-rw-r--r--src/librustc/middle/ty_relate/mod.rs5
-rw-r--r--src/librustc/util/ppaux.rs2
-rw-r--r--src/librustc_trans/trans/callee.rs2
-rw-r--r--src/librustc_trans/trans/expr.rs5
-rw-r--r--src/librustc_trans/trans/meth.rs5
-rw-r--r--src/librustc_typeck/astconv.rs21
-rw-r--r--src/librustc_typeck/check/method/confirm.rs3
-rw-r--r--src/librustc_typeck/check/method/mod.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs9
-rw-r--r--src/librustc_typeck/check/wf.rs2
-rw-r--r--src/librustc_typeck/coherence/mod.rs2
-rw-r--r--src/librustc_typeck/collect.rs26
-rw-r--r--src/librustc_typeck/constrained_type_params.rs5
-rw-r--r--src/librustc_typeck/variance.rs6
31 files changed, 137 insertions, 144 deletions
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 93056d949db..7132ac4895a 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -283,7 +283,7 @@ pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
 // if there is one.
 pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
                             def: ast::DefId)
-                            -> Option<Rc<ty::TraitRef<'tcx>>> {
+                            -> Option<ty::TraitRef<'tcx>> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_impl_trait(&*cdata, def.node, tcx)
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index f03a2d342d7..467919bcaca 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -247,13 +247,13 @@ pub fn item_type<'tcx>(_item_id: ast::DefId, item: rbml::Doc,
 }
 
 fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-                       -> Rc<ty::TraitRef<'tcx>> {
+                       -> ty::TraitRef<'tcx> {
     parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx,
                          |_, did| translate_def_id(cdata, did))
 }
 
 fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-                        -> Rc<ty::TraitRef<'tcx>> {
+                        -> ty::TraitRef<'tcx> {
     let tp = reader::get_doc(doc, tag_item_trait_ref);
     doc_trait_ref(tp, tcx, cdata)
 }
@@ -490,7 +490,7 @@ pub fn get_impl_polarity<'tcx>(cdata: Cmd,
 pub fn get_impl_trait<'tcx>(cdata: Cmd,
                             id: ast::NodeId,
                             tcx: &ty::ctxt<'tcx>)
-                            -> Option<Rc<ty::TraitRef<'tcx>>>
+                            -> Option<ty::TraitRef<'tcx>>
 {
     let item_doc = lookup_item(id, cdata.data());
     let fam = item_family(item_doc);
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index bcbb350fc34..4862497b325 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -103,7 +103,7 @@ struct entry<T> {
 
 fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
                               ecx: &EncodeContext<'a, 'tcx>,
-                              trait_ref: &ty::TraitRef<'tcx>,
+                              trait_ref: ty::TraitRef<'tcx>,
                               tag: usize) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
@@ -191,7 +191,7 @@ pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
-    tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
+    tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, *trait_ref);
 }
 
 pub fn write_region(ecx: &EncodeContext,
@@ -1201,7 +1201,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
           encode_unsafety(rbml_w, unsafety);
 
           let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
-          encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
+          encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
           rbml_w.end_tag();
       }
       ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => {
@@ -1246,7 +1246,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         }
         if opt_trait.is_some() {
             let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
-            encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
+            encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
         }
         encode_path(rbml_w, path.clone());
         encode_stability(rbml_w, stab);
@@ -1314,7 +1314,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                         tag_item_generics);
         encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id),
                           tag_item_super_predicates);
-        encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
+        encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
         encode_name(rbml_w, item.ident.name);
         encode_attributes(rbml_w, &item.attrs);
         encode_visibility(rbml_w, vis);
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 955905ee263..223a5eef614 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -23,7 +23,6 @@ use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::{self, AsPredicate, Ty};
 
-use std::rc::Rc;
 use std::str;
 use syntax::abi;
 use syntax::ast;
@@ -182,7 +181,7 @@ pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos
 
 pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize,
                                      tcx: &ty::ctxt<'tcx>, conv: F)
-                                     -> Rc<ty::TraitRef<'tcx>> where
+                                     -> ty::TraitRef<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
     debug!("parse_trait_ref_data {}", data_log_string(data, pos));
@@ -434,19 +433,19 @@ fn parse_str(st: &mut PState, term: char) -> String {
 }
 
 fn parse_trait_ref<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-                                -> Rc<ty::TraitRef<'tcx>> where
+                                -> ty::TraitRef<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
     parse_trait_ref_(st, &mut conv)
 }
 
 fn parse_trait_ref_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-                              -> Rc<ty::TraitRef<'tcx>> where
+                              -> ty::TraitRef<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
     let def = parse_def_(st, NominalType, conv);
     let substs = st.tcx.mk_substs(parse_substs_(st, conv));
-    Rc::new(ty::TraitRef {def_id: def, substs: substs})
+    ty::TraitRef {def_id: def, substs: substs}
 }
 
 fn parse_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) -> Ty<'tcx> where
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 8a278811282..f5f520720c6 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -94,7 +94,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
         ty::ty_trait(box ty::TyTrait { ref principal,
                                        ref bounds }) => {
             mywrite!(w, "x[");
-            enc_trait_ref(w, cx, &*principal.0);
+            enc_trait_ref(w, cx, principal.0);
             enc_existential_bounds(w, cx, bounds);
             mywrite!(w, "]");
         }
@@ -149,7 +149,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
         }
         ty::ty_projection(ref data) => {
             mywrite!(w, "P[");
-            enc_trait_ref(w, cx, &*data.trait_ref);
+            enc_trait_ref(w, cx, data.trait_ref);
             mywrite!(w, "{}]", token::get_name(data.item_name));
         }
         ty::ty_err => {
@@ -309,7 +309,7 @@ fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
 }
 
 pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
-                               s: &ty::TraitRef<'tcx>) {
+                               s: ty::TraitRef<'tcx>) {
     mywrite!(w, "{}|", (cx.ds)(s.def_id));
     enc_substs(w, cx, s.substs);
 }
@@ -394,7 +394,7 @@ pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
 
     for tp in &bs.trait_bounds {
         mywrite!(w, "I");
-        enc_trait_ref(w, cx, &*tp.0);
+        enc_trait_ref(w, cx, tp.0);
     }
 
     for tp in &bs.projection_bounds {
@@ -446,7 +446,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
     match *p {
         ty::Predicate::Trait(ref trait_ref) => {
             mywrite!(w, "t");
-            enc_trait_ref(w, cx, &*trait_ref.0.trait_ref);
+            enc_trait_ref(w, cx, trait_ref.0.trait_ref);
         }
         ty::Predicate::Equate(ty::Binder(ty::EquatePredicate(a, b))) => {
             mywrite!(w, "e");
@@ -473,7 +473,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
 fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder,
                                       cx: &ctxt<'a, 'tcx>,
                                       data: &ty::ProjectionPredicate<'tcx>) {
-    enc_trait_ref(w, cx, &*data.projection_ty.trait_ref);
+    enc_trait_ref(w, cx, data.projection_ty.trait_ref);
     mywrite!(w, "{}|", token::get_name(data.projection_ty.item_name));
     enc_ty(w, cx, data.ty);
 }
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 3ef22ba8158..4bfc4c5b850 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -41,7 +41,6 @@ use syntax;
 use std::cell::Cell;
 use std::io::SeekFrom;
 use std::io::prelude::*;
-use std::rc::Rc;
 use std::fmt::Debug;
 
 use rbml::reader;
@@ -890,7 +889,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
                     this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
                         this.emit_struct("MethodParam", 2, |this| {
                             try!(this.emit_struct_field("trait_ref", 0, |this| {
-                                Ok(this.emit_trait_ref(ecx, &*p.trait_ref))
+                                Ok(this.emit_trait_ref(ecx, &p.trait_ref))
                             }));
                             try!(this.emit_struct_field("method_num", 0, |this| {
                                 this.emit_uint(p.method_num)
@@ -914,7 +913,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
                     this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
                         this.emit_struct("MethodObject", 2, |this| {
                             try!(this.emit_struct_field("trait_ref", 0, |this| {
-                                Ok(this.emit_trait_ref(ecx, &*o.trait_ref))
+                                Ok(this.emit_trait_ref(ecx, &o.trait_ref))
                             }));
                             try!(this.emit_struct_field("object_trait_id", 0, |this| {
                                 Ok(this.emit_def_id(o.object_trait_id))
@@ -1208,7 +1207,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
     if let Some(trait_ref) = tcx.object_cast_map.borrow().get(&id) {
         rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
+            rbml_w.emit_trait_ref(ecx, &trait_ref.0);
         })
     }
 
@@ -1275,7 +1274,7 @@ trait rbml_decoder_decoder_helpers<'tcx> {
     fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>;
     fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
     fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-                              -> Rc<ty::TraitRef<'tcx>>;
+                              -> ty::TraitRef<'tcx>;
     fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                    -> ty::PolyTraitRef<'tcx>;
     fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -1469,7 +1468,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
     }
 
     fn read_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-                              -> Rc<ty::TraitRef<'tcx>> {
+                              -> ty::TraitRef<'tcx> {
         self.read_opaque(|this, doc| {
             let ty = tydecode::parse_trait_ref_data(
                 doc.data,
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 916874f1c51..091092e3b60 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -942,8 +942,8 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
     let trait_substs = tcx.mk_substs(trait_substs);
     debug!("resolve_trait_associated_const: trait_substs={}",
            trait_substs.repr(tcx));
-    let trait_ref = ty::Binder(Rc::new(ty::TraitRef { def_id: trait_id,
-                                                      substs: trait_substs }));
+    let trait_ref = ty::Binder(ty::TraitRef { def_id: trait_id,
+                                              substs: trait_substs });
 
     ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
     let infcx = infer::new_infer_ctxt(tcx);
diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs
index 0d6a1df7237..86deca0c144 100644
--- a/src/librustc/middle/implicator.rs
+++ b/src/librustc/middle/implicator.rs
@@ -16,7 +16,6 @@ use middle::traits;
 use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
 use middle::ty_fold::{TypeFoldable, TypeFolder};
 
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::Span;
 
@@ -324,7 +323,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
     }
 
     fn accumulate_from_assoc_types(&mut self,
-                                   trait_ref: Rc<ty::TraitRef<'tcx>>)
+                                   trait_ref: ty::TraitRef<'tcx>)
     {
         debug!("accumulate_from_assoc_types({})",
                trait_ref.repr(self.tcx()));
@@ -442,7 +441,7 @@ pub fn object_region_bounds<'tcx>(
     // Note that we preserve the overall binding levels here.
     assert!(!open_ty.has_escaping_regions());
     let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
-    let trait_refs = vec!(ty::Binder(Rc::new(ty::TraitRef::new(principal.0.def_id, substs))));
+    let trait_refs = vec!(ty::Binder(ty::TraitRef::new(principal.0.def_id, substs)));
 
     let param_bounds = ty::ParamBounds {
         region_bounds: Vec::new(),
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 22e3376e09e..8aca64484bf 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -79,7 +79,6 @@ use middle::ty::{self, Ty};
 use middle::ty::{Region, ReFree};
 use std::cell::{Cell, RefCell};
 use std::char::from_u32;
-use std::rc::Rc;
 use std::string::String;
 use syntax::ast;
 use syntax::ast_map;
@@ -1680,13 +1679,13 @@ impl<'tcx> Resolvable<'tcx> for Ty<'tcx> {
     }
 }
 
-impl<'tcx> Resolvable<'tcx> for Rc<ty::TraitRef<'tcx>> {
+impl<'tcx> Resolvable<'tcx> for ty::TraitRef<'tcx> {
     fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>)
-                   -> Rc<ty::TraitRef<'tcx>> {
-        Rc::new(infcx.resolve_type_vars_if_possible(&**self))
+                   -> ty::TraitRef<'tcx> {
+        infcx.resolve_type_vars_if_possible(self)
     }
     fn contains_error(&self) -> bool {
-        ty::trait_ref_contains_error(&**self)
+        ty::trait_ref_contains_error(self)
     }
 }
 
@@ -1699,7 +1698,7 @@ impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> {
     }
 
     fn contains_error(&self) -> bool {
-        ty::trait_ref_contains_error(&*self.0)
+        ty::trait_ref_contains_error(&self.0)
     }
 }
 
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 63e4a5c8a2a..b802f46e285 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -33,7 +33,6 @@ use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use rustc_data_structures::unify::{self, UnificationTable};
 use std::cell::{RefCell};
 use std::fmt;
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap;
 use syntax::codemap::Span;
@@ -155,7 +154,7 @@ impl fmt::Display for TypeOrigin {
 #[derive(Clone, Debug)]
 pub enum ValuePairs<'tcx> {
     Types(ty::expected_found<Ty<'tcx>>),
-    TraitRefs(ty::expected_found<Rc<ty::TraitRef<'tcx>>>),
+    TraitRefs(ty::expected_found<ty::TraitRef<'tcx>>),
     PolyTraitRefs(ty::expected_found<ty::PolyTraitRef<'tcx>>),
 }
 
@@ -663,8 +662,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn sub_trait_refs(&self,
                           a_is_expected: bool,
                           origin: TypeOrigin,
-                          a: Rc<ty::TraitRef<'tcx>>,
-                          b: Rc<ty::TraitRef<'tcx>>)
+                          a: ty::TraitRef<'tcx>,
+                          b: ty::TraitRef<'tcx>)
                           -> UnitResult<'tcx>
     {
         debug!("sub_trait_refs({} <: {})",
@@ -675,7 +674,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 origin: origin,
                 values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
             };
-            self.sub(a_is_expected, trace).relate(&*a, &*b).map(|_| ())
+            self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
         })
     }
 
@@ -873,8 +872,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         format!("({})", tstrs.connect(", "))
     }
 
-    pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>) -> String {
-        let t = self.resolve_type_vars_if_possible(&**t);
+    pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
+        let t = self.resolve_type_vars_if_possible(t);
         t.user_string(self.tcx)
     }
 
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index d21891ab23f..d9f8a88fddc 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -20,7 +20,6 @@ use super::util;
 use middle::subst::{Subst, Substs, TypeSpace};
 use middle::ty::{self, ToPolyTraitRef, Ty};
 use middle::infer::{self, InferCtxt};
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::{DUMMY_SP, Span};
 use util::ppaux::Repr;
@@ -139,7 +138,7 @@ type SubstsFn = for<'a,'tcx> fn(infcx: &InferCtxt<'a, 'tcx>,
 fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
                                      impl_def_id: ast::DefId,
                                      substs_fn: SubstsFn)
-                                     -> (Rc<ty::TraitRef<'tcx>>,
+                                     -> (ty::TraitRef<'tcx>,
                                          Vec<PredicateObligation<'tcx>>)
 {
     let impl_substs =
@@ -341,5 +340,3 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
         }
     }
 }
-
-
diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs
index d10ff060418..1b5719d3d42 100644
--- a/src/librustc/middle/traits/error_reporting.rs
+++ b/src/librustc/middle/traits/error_reporting.rs
@@ -191,7 +191,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                         trait_ref.self_ty().user_string(infcx.tcx));
                                 // Check if it has a custom "#[rustc_on_unimplemented]"
                                 // error message, report with that message if it does
-                                let custom_note = report_on_unimplemented(infcx, &*trait_ref.0,
+                                let custom_note = report_on_unimplemented(infcx, &trait_ref.0,
                                                                           obligation.cause.span);
                                 if let Some(s) = custom_note {
                                     infcx.tcx.sess.span_note(obligation.cause.span,
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs
index 9cdae21868e..8ae7ad029ac 100644
--- a/src/librustc/middle/traits/project.rs
+++ b/src/librustc/middle/traits/project.rs
@@ -25,7 +25,6 @@ use middle::subst::{Subst, Substs};
 use middle::ty::{self, AsPredicate, ReferencesError, RegionEscape,
                  HasProjectionTypes, ToPolyTraitRef, Ty};
 use middle::ty_fold::{self, TypeFoldable, TypeFolder};
-use std::rc::Rc;
 use syntax::ast;
 use syntax::parse::token;
 use util::common::FN_OUTPUT_NAME;
@@ -525,7 +524,7 @@ fn project_type<'cx,'tcx>(
 fn assemble_candidates_from_param_env<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
+    obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
 {
     let env_predicates = selcx.param_env().caller_bounds.clone();
@@ -546,7 +545,7 @@ fn assemble_candidates_from_param_env<'cx,'tcx>(
 fn assemble_candidates_from_trait_def<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
+    obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
 {
     // Check whether the self-type is itself a projection.
@@ -571,7 +570,7 @@ fn assemble_candidates_from_trait_def<'cx,'tcx>(
 fn assemble_candidates_from_predicates<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
+    obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
     env_predicates: Vec<ty::Predicate<'tcx>>)
 {
@@ -614,7 +613,7 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
 fn assemble_candidates_from_object_type<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
     obligation:  &ProjectionTyObligation<'tcx>,
-    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
+    obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
     object_ty: Ty<'tcx>)
 {
@@ -641,7 +640,7 @@ fn assemble_candidates_from_object_type<'cx,'tcx>(
 fn assemble_candidates_from_impls<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
+    obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
     -> Result<(), SelectionError<'tcx>>
 {
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 153ec0ab2b3..f0390a6f5f0 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -89,7 +89,7 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {
 
 #[derive(Clone)]
 pub struct SelectionCache<'tcx> {
-    hashmap: RefCell<FnvHashMap<Rc<ty::TraitRef<'tcx>>,
+    hashmap: RefCell<FnvHashMap<ty::TraitRef<'tcx>,
                                 SelectionResult<'tcx, SelectionCandidate<'tcx>>>>,
 }
 
@@ -988,7 +988,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn match_projection(&mut self,
                         obligation: &TraitObligation<'tcx>,
                         trait_bound: ty::PolyTraitRef<'tcx>,
-                        skol_trait_ref: Rc<ty::TraitRef<'tcx>>,
+                        skol_trait_ref: ty::TraitRef<'tcx>,
                         skol_map: &infer::SkolemizationMap,
                         snapshot: &infer::CombinedSnapshot)
                         -> bool
@@ -2324,7 +2324,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // Before we create the substitutions and everything, first
         // consider a "quick reject". This avoids creating more types
         // and so forth that we need to.
-        if self.fast_reject_trait_refs(obligation, &*impl_trait_ref) {
+        if self.fast_reject_trait_refs(obligation, &impl_trait_ref) {
             return Err(());
         }
 
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index 6ecff3b7faa..a6b2359c2b8 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -12,7 +12,6 @@ use middle::subst::{Substs, VecPerParamSpace};
 use middle::infer::InferCtxt;
 use middle::ty::{self, Ty, AsPredicate, ToPolyTraitRef};
 use std::fmt;
-use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::Span;
 use util::common::ErrorReported;
@@ -336,14 +335,14 @@ pub fn trait_ref_for_builtin_bound<'tcx>(
     tcx: &ty::ctxt<'tcx>,
     builtin_bound: ty::BuiltinBound,
     param_ty: Ty<'tcx>)
-    -> Result<Rc<ty::TraitRef<'tcx>>, ErrorReported>
+    -> Result<ty::TraitRef<'tcx>, ErrorReported>
 {
     match tcx.lang_items.from_builtin_kind(builtin_bound) {
         Ok(def_id) => {
-            Ok(Rc::new(ty::TraitRef {
+            Ok(ty::TraitRef {
                 def_id: def_id,
                 substs: tcx.mk_substs(Substs::empty().with_self_ty(param_ty))
-            }))
+            })
         }
         Err(e) => {
             tcx.sess.err(&e);
@@ -355,7 +354,7 @@ pub fn trait_ref_for_builtin_bound<'tcx>(
 
 pub fn predicate_for_trait_ref<'tcx>(
     cause: ObligationCause<'tcx>,
-    trait_ref: Rc<ty::TraitRef<'tcx>>,
+    trait_ref: ty::TraitRef<'tcx>,
     recursion_depth: usize)
     -> Result<PredicateObligation<'tcx>, ErrorReported>
 {
@@ -374,10 +373,10 @@ pub fn predicate_for_trait_def<'tcx>(
     param_ty: Ty<'tcx>)
     -> Result<PredicateObligation<'tcx>, ErrorReported>
 {
-    let trait_ref = Rc::new(ty::TraitRef {
+    let trait_ref = ty::TraitRef {
         def_id: trait_def_id,
         substs: tcx.mk_substs(Substs::empty().with_self_ty(param_ty))
-    });
+    };
     predicate_for_trait_ref(cause, trait_ref, recursion_depth)
 }
 
@@ -466,17 +465,17 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
     self_ty: Ty<'tcx>,
     sig: &ty::PolyFnSig<'tcx>,
     tuple_arguments: TupleArgumentsFlag)
-    -> ty::Binder<(Rc<ty::TraitRef<'tcx>>, Ty<'tcx>)>
+    -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)>
 {
     let arguments_tuple = match tuple_arguments {
         TupleArgumentsFlag::No => sig.0.inputs[0],
         TupleArgumentsFlag::Yes => ty::mk_tup(tcx, sig.0.inputs.to_vec()),
     };
     let trait_substs = Substs::new_trait(vec![arguments_tuple], vec![], self_ty);
-    let trait_ref = Rc::new(ty::TraitRef {
+    let trait_ref = ty::TraitRef {
         def_id: fn_trait_def_id,
         substs: tcx.mk_substs(trait_substs),
-    });
+    };
     ty::Binder((trait_ref, sig.0.output.unwrap_or(ty::mk_nil(tcx))))
 }
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 33ba21bc7b1..f38bd40456b 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -433,7 +433,7 @@ pub struct MethodParam<'tcx> {
     // be a supertrait of what the user actually typed. Note that it
     // never contains bound regions; those regions should have been
     // instantiated with fresh variables at this point.
-    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+    pub trait_ref: ty::TraitRef<'tcx>,
 
     // index of usize in the list of trait items. Note that this is NOT
     // the index into the vtable, because the list of trait items
@@ -451,7 +451,7 @@ pub struct MethodParam<'tcx> {
 #[derive(Clone, Debug)]
 pub struct MethodObject<'tcx> {
     // the (super)trait containing the method to be invoked
-    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+    pub trait_ref: TraitRef<'tcx>,
 
     // the actual base trait id of the object
     pub object_trait_id: ast::DefId,
@@ -588,10 +588,14 @@ pub struct TransmuteRestriction<'tcx> {
 
 /// Internal storage
 pub struct CtxtArenas<'tcx> {
+    // internings
     type_: TypedArena<TyS<'tcx>>,
     substs: TypedArena<Substs<'tcx>>,
     bare_fn: TypedArena<BareFnTy<'tcx>>,
     region: TypedArena<Region>,
+
+    // references
+    trait_defs: TypedArena<TraitDef<'tcx>>
 }
 
 impl<'tcx> CtxtArenas<'tcx> {
@@ -601,6 +605,8 @@ impl<'tcx> CtxtArenas<'tcx> {
             substs: TypedArena::new(),
             bare_fn: TypedArena::new(),
             region: TypedArena::new(),
+
+            trait_defs: TypedArena::new()
         }
     }
 }
@@ -678,10 +684,10 @@ pub struct ctxt<'tcx> {
     /// A cache for the trait_items() routine
     pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem<'tcx>>>>>,
 
-    pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef<'tcx>>>>>,
+    pub impl_trait_cache: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
 
-    pub impl_trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
-    pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
+    pub impl_trait_refs: RefCell<NodeMap<TraitRef<'tcx>>>,
+    pub trait_defs: RefCell<DefIdMap<&'tcx TraitDef<'tcx>>>,
 
     /// Maps from the def-id of an item (trait/struct/enum/fn) to its
     /// associated predicates.
@@ -832,6 +838,13 @@ impl<'tcx> ctxt<'tcx> {
         self.node_types.borrow_mut().insert(id, ty);
     }
 
+    pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
+        let did = def.trait_ref.def_id;
+        let interned = self.arenas.trait_defs.alloc(def);
+        self.trait_defs.borrow_mut().insert(did, interned);
+        interned
+    }
+
     pub fn store_free_region_map(&self, id: NodeId, map: FreeRegionMap) {
         self.free_region_maps.borrow_mut()
                              .insert(id, map);
@@ -1414,10 +1427,10 @@ impl<'tcx> TyTrait<'tcx> {
         // otherwise the escaping regions would be captured by the binder
         assert!(!self_ty.has_escaping_regions());
 
-        ty::Binder(Rc::new(ty::TraitRef {
+        ty::Binder(TraitRef {
             def_id: self.principal.0.def_id,
             substs: tcx.mk_substs(self.principal.0.substs.with_self_ty(self_ty)),
-        }))
+        })
     }
 
     pub fn projection_bounds_with_self_ty(&self,
@@ -1432,9 +1445,8 @@ impl<'tcx> TyTrait<'tcx> {
             .map(|in_poly_projection_predicate| {
                 let in_projection_ty = &in_poly_projection_predicate.0.projection_ty;
                 let substs = tcx.mk_substs(in_projection_ty.trait_ref.substs.with_self_ty(self_ty));
-                let trait_ref =
-                    Rc::new(ty::TraitRef::new(in_projection_ty.trait_ref.def_id,
-                                              substs));
+                let trait_ref = ty::TraitRef::new(in_projection_ty.trait_ref.def_id,
+                                              substs);
                 let projection_ty = ty::ProjectionTy {
                     trait_ref: trait_ref,
                     item_name: in_projection_ty.item_name
@@ -1463,13 +1475,13 @@ impl<'tcx> TyTrait<'tcx> {
 /// Note that a `TraitRef` introduces a level of region binding, to
 /// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
 /// U>` or higher-ranked object types.
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct TraitRef<'tcx> {
     pub def_id: DefId,
     pub substs: &'tcx Substs<'tcx>,
 }
 
-pub type PolyTraitRef<'tcx> = Binder<Rc<TraitRef<'tcx>>>;
+pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
 
 impl<'tcx> PolyTraitRef<'tcx> {
     pub fn self_ty(&self) -> Ty<'tcx> {
@@ -1995,7 +2007,7 @@ impl<'tcx> Predicate<'tcx> {
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct TraitPredicate<'tcx> {
-    pub trait_ref: Rc<TraitRef<'tcx>>
+    pub trait_ref: TraitRef<'tcx>
 }
 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
 
@@ -2064,7 +2076,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct ProjectionTy<'tcx> {
     /// The trait reference `T as Trait<..>`.
-    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+    pub trait_ref: ty::TraitRef<'tcx>,
 
     /// The name `N` of the associated type.
     pub item_name: ast::Name,
@@ -2080,7 +2092,7 @@ pub trait ToPolyTraitRef<'tcx> {
     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
 }
 
-impl<'tcx> ToPolyTraitRef<'tcx> for Rc<TraitRef<'tcx>> {
+impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
         assert!(!self.has_escaping_regions());
         ty::Binder(self.clone())
@@ -2108,7 +2120,7 @@ pub trait AsPredicate<'tcx> {
     fn as_predicate(&self) -> Predicate<'tcx>;
 }
 
-impl<'tcx> AsPredicate<'tcx> for Rc<TraitRef<'tcx>> {
+impl<'tcx> AsPredicate<'tcx> for TraitRef<'tcx> {
     fn as_predicate(&self) -> Predicate<'tcx> {
         // we're about to add a binder, so let's check that we don't
         // accidentally capture anything, or else that might be some
@@ -2505,7 +2517,7 @@ pub struct TraitDef<'tcx> {
     /// implements the trait.
     pub generics: Generics<'tcx>,
 
-    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+    pub trait_ref: TraitRef<'tcx>,
 
     /// A list of the associated types defined in this trait. Useful
     /// for resolving `X::Foo` type markers.
@@ -3132,7 +3144,7 @@ pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) {
 }
 
 pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>,
-                           trait_ref: Rc<ty::TraitRef<'tcx>>,
+                           trait_ref: TraitRef<'tcx>,
                            item_name: ast::Name)
                            -> Ty<'tcx> {
     // take a copy of substs so that we own the vectors inside
@@ -4398,9 +4410,9 @@ pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
 }
 
 pub fn impl_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
-                                  -> Rc<ty::TraitRef<'tcx>> {
+                                  -> ty::TraitRef<'tcx> {
     match cx.impl_trait_refs.borrow().get(&id) {
-        Some(ty) => ty.clone(),
+        Some(ty) => *ty,
         None => cx.sess.bug(
             &format!("impl_id_to_trait_ref: no trait ref for impl `{}`",
                     cx.map.node_to_string(id)))
@@ -5313,7 +5325,7 @@ pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
 }
 
 pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-                            -> Option<Rc<TraitRef<'tcx>>> {
+                            -> Option<TraitRef<'tcx>> {
     memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
         if id.krate == ast::LOCAL_CRATE {
             debug!("(impl_trait_ref) searching for trait impl {:?}", id);
@@ -5819,10 +5831,10 @@ pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
 
 /// Given the did of a trait, returns its canonical trait ref.
 pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
-                              -> Rc<TraitDef<'tcx>> {
+                              -> &'tcx TraitDef<'tcx> {
     memoized(&cx.trait_defs, did, |did: DefId| {
         assert!(did.krate != ast::LOCAL_CRATE);
-        Rc::new(csearch::get_trait_def(cx, did))
+        cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did))
     })
 }
 
diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs
index 1c414d3d5f3..0ef7b5be1fb 100644
--- a/src/librustc/middle/ty_relate/mod.rs
+++ b/src/librustc/middle/ty_relate/mod.rs
@@ -321,8 +321,8 @@ impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::ProjectionTy<'tcx> {
             Err(ty::terr_projection_name_mismatched(
                 expected_found(relation, &a.item_name, &b.item_name)))
         } else {
-            let trait_ref = try!(relation.relate(&*a.trait_ref, &*b.trait_ref));
-            Ok(ty::ProjectionTy { trait_ref: Rc::new(trait_ref), item_name: a.item_name })
+            let trait_ref = try!(relation.relate(&a.trait_ref, &b.trait_ref));
+            Ok(ty::ProjectionTy { trait_ref: trait_ref, item_name: a.item_name })
         }
     }
 }
@@ -652,4 +652,3 @@ pub fn expected_found_bool<T>(a_is_expected: bool,
         ty::expected_found {expected: b, found: a}
     }
 }
-
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 3d56371dd52..aa89c1943a2 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -671,7 +671,7 @@ impl<'tcx> Repr<'tcx> for def::Def {
 /// projection bounds, so we just stuff them altogether. But in
 /// reality we should eventually sort things out better.
 type TraitAndProjections<'tcx> =
-    (Rc<ty::TraitRef<'tcx>>, Vec<ty::ProjectionPredicate<'tcx>>);
+    (ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
 
 impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> {
     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 0e468072307..e87c058faf9 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -452,7 +452,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
 
                     // Compute the first substitution
                     let first_subst =
-                        ty::make_substs_for_receiver_types(tcx, &*trait_ref, &*method)
+                        ty::make_substs_for_receiver_types(tcx, &trait_ref, &*method)
                         .erase_regions();
 
                     // And compose them
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index f5ee44d69cc..7be1f3813d7 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -86,7 +86,6 @@ use syntax::ptr::P;
 use syntax::parse::token;
 use std::iter::repeat;
 use std::mem;
-use std::rc::Rc;
 
 // Destinations
 
@@ -320,8 +319,8 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
             // Note that we preserve binding levels here:
             let substs = principal.0.substs.with_self_ty(source).erase_regions();
             let substs = ccx.tcx().mk_substs(substs);
-            let trait_ref = ty::Binder(Rc::new(ty::TraitRef { def_id: principal.def_id(),
-                                                               substs: substs }));
+            let trait_ref = ty::Binder(ty::TraitRef { def_id: principal.def_id(),
+                                                      substs: substs });
             consts::ptrcast(meth::get_vtable(ccx, trait_ref, param_substs),
                             Type::vtable_ptr(ccx))
         }
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index fda931fde6e..7039968b029 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -40,7 +40,6 @@ use middle::ty::{self, Ty};
 use middle::ty::MethodCall;
 use util::ppaux::Repr;
 
-use std::rc::Rc;
 use syntax::abi::{Rust, RustCall};
 use syntax::parse::token;
 use syntax::{ast, ast_map, attr, visit};
@@ -232,8 +231,8 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                              Vec::new()));
     let trait_substs = tcx.mk_substs(trait_substs);
     debug!("trait_substs={}", trait_substs.repr(tcx));
-    let trait_ref = ty::Binder(Rc::new(ty::TraitRef { def_id: trait_id,
-                                                      substs: trait_substs }));
+    let trait_ref = ty::Binder(ty::TraitRef { def_id: trait_id,
+                                              substs: trait_substs });
     let vtbl = fulfill_obligation(ccx,
                                   DUMMY_SP,
                                   trait_ref);
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 9dbf918ddb5..694993cdc0a 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -64,7 +64,6 @@ use util::nodemap::FnvHashSet;
 use util::ppaux::{self, Repr, UserString};
 
 use std::iter::repeat;
-use std::rc::Rc;
 use std::slice;
 use syntax::{abi, ast, ast_util};
 use syntax::codemap::{Span, Pos};
@@ -83,7 +82,7 @@ pub trait AstConv<'tcx> {
     /// Returns the `TraitDef` for a given trait. This allows you to
     /// figure out the set of type parameters defined on the trait.
     fn get_trait_def(&self, span: Span, id: ast::DefId)
-                     -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>;
+                     -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>;
 
     /// Ensure that the super-predicates for the trait with the given
     /// id are available and also for the transitive set of
@@ -140,7 +139,7 @@ pub trait AstConv<'tcx> {
     /// This is fairly straightforward and can be accommodated in any context.
     fn projected_ty(&self,
                     span: Span,
-                    _trait_ref: Rc<ty::TraitRef<'tcx>>,
+                    _trait_ref: ty::TraitRef<'tcx>,
                     _item_name: ast::Name)
                     -> Ty<'tcx>;
 }
@@ -633,7 +632,7 @@ pub fn instantiate_mono_trait_ref<'tcx>(
     rscope: &RegionScope,
     trait_ref: &ast::TraitRef,
     self_ty: Option<Ty<'tcx>>)
-    -> Rc<ty::TraitRef<'tcx>>
+    -> ty::TraitRef<'tcx>
 {
     let trait_def_id = trait_def_id(this, trait_ref);
     ast_path_to_mono_trait_ref(this,
@@ -702,7 +701,7 @@ fn ast_path_to_poly_trait_ref<'a,'tcx>(
                                         trait_def_id,
                                         self_ty,
                                         trait_segment);
-    let poly_trait_ref = ty::Binder(Rc::new(ty::TraitRef::new(trait_def_id, substs)));
+    let poly_trait_ref = ty::Binder(ty::TraitRef::new(trait_def_id, substs));
 
     {
         let converted_bindings =
@@ -730,7 +729,7 @@ fn ast_path_to_mono_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
                                        trait_def_id: ast::DefId,
                                        self_ty: Option<Ty<'tcx>>,
                                        trait_segment: &ast::PathSegment)
-                                       -> Rc<ty::TraitRef<'tcx>>
+                                       -> ty::TraitRef<'tcx>
 {
     let (substs, assoc_bindings) =
         create_substs_for_ast_trait_ref(this,
@@ -741,7 +740,7 @@ fn ast_path_to_mono_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
                                         self_ty,
                                         trait_segment);
     prohibit_projections(this.tcx(), &assoc_bindings);
-    Rc::new(ty::TraitRef::new(trait_def_id, substs))
+    ty::TraitRef::new(trait_def_id, substs)
 }
 
 fn create_substs_for_ast_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
@@ -856,8 +855,8 @@ fn ast_type_binding_to_poly_projection_predicate<'tcx>(
         let mut dummy_substs = trait_ref.skip_binder().substs.clone(); // binder moved here -+
         assert!(dummy_substs.self_ty().is_none());                     //                    |
         dummy_substs.types.push(SelfSpace, dummy_self_ty);             //                    |
-        trait_ref = ty::Binder(Rc::new(ty::TraitRef::new(trait_ref.def_id(), // <------------+
-                                                         tcx.mk_substs(dummy_substs))));
+        trait_ref = ty::Binder(ty::TraitRef::new(trait_ref.def_id(),   // <------------+
+                                                 tcx.mk_substs(dummy_substs)));
     }
 
     try!(this.ensure_super_predicates(binding.span, trait_ref.def_id()));
@@ -874,8 +873,8 @@ fn ast_type_binding_to_poly_projection_predicate<'tcx>(
             let mut dummy_substs = candidate.0.substs.clone();
             assert!(dummy_substs.self_ty() == Some(dummy_self_ty));
             dummy_substs.types.pop(SelfSpace);
-            *candidate = ty::Binder(Rc::new(ty::TraitRef::new(candidate.def_id(),
-                                                              tcx.mk_substs(dummy_substs))));
+            *candidate = ty::Binder(ty::TraitRef::new(candidate.def_id(),
+                                                      tcx.mk_substs(dummy_substs)));
         }
     }
 
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index cf1323e71bd..c068bfaa82e 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -23,7 +23,6 @@ use middle::infer;
 use middle::infer::InferCtxt;
 use syntax::ast;
 use syntax::codemap::Span;
-use std::rc::Rc;
 use std::iter::repeat;
 use util::ppaux::Repr;
 
@@ -276,7 +275,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
                                                                  self.infcx().next_ty_var());
 
                 let trait_ref =
-                    Rc::new(ty::TraitRef::new(trait_def_id, self.tcx().mk_substs(substs.clone())));
+                    ty::TraitRef::new(trait_def_id, self.tcx().mk_substs(substs.clone()));
                 let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref,
                                                            method_num: method_num,
                                                            impl_def_id: None });
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index c5d8e2758ba..c070df6b593 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -170,7 +170,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
     // Construct a trait-reference `self_ty : Trait<input_tys>`
     let substs = subst::Substs::new_trait(input_types, Vec::new(), self_ty);
-    let trait_ref = Rc::new(ty::TraitRef::new(trait_def_id, fcx.tcx().mk_substs(substs)));
+    let trait_ref = ty::TraitRef::new(trait_def_id, fcx.tcx().mk_substs(substs));
 
     // Construct an obligation
     let poly_trait_ref = trait_ref.to_poly_trait_ref();
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 7ff1355184b..2f6b57217ff 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -61,7 +61,7 @@ struct Candidate<'tcx> {
 enum CandidateKind<'tcx> {
     InherentImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>),
     ObjectCandidate(/* Trait */ ast::DefId, /* method_num */ usize, /* vtable index */ usize),
-    ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>,
+    ExtensionImplCandidate(/* Impl */ ast::DefId, ty::TraitRef<'tcx>,
                            subst::Substs<'tcx>, ItemIndex),
     ClosureCandidate(/* Trait */ ast::DefId, ItemIndex),
     WhereClauseCandidate(ty::PolyTraitRef<'tcx>, ItemIndex),
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index cb5b569fd79..ad1042c068a 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -112,7 +112,6 @@ use util::lev_distance::lev_distance;
 
 use std::cell::{Cell, Ref, RefCell};
 use std::mem::replace;
-use std::rc::Rc;
 use std::iter::repeat;
 use std::slice;
 use syntax::{self, abi, attr};
@@ -747,7 +746,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
               Some(impl_trait_ref) => {
                 check_impl_items_against_trait(ccx,
                                                it.span,
-                                               &*impl_trait_ref,
+                                               &impl_trait_ref,
                                                impl_items);
               }
               None => { }
@@ -1174,7 +1173,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
     }
 
     fn get_trait_def(&self, _: Span, id: ast::DefId)
-                     -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>
+                     -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
     {
         Ok(ty::lookup_trait_def(self.tcx(), id))
     }
@@ -1244,7 +1243,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
 
     fn projected_ty(&self,
                     span: Span,
-                    trait_ref: Rc<ty::TraitRef<'tcx>>,
+                    trait_ref: ty::TraitRef<'tcx>,
                     item_name: ast::Name)
                     -> Ty<'tcx>
     {
@@ -1457,7 +1456,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn normalize_associated_type(&self,
                                  span: Span,
-                                 trait_ref: Rc<ty::TraitRef<'tcx>>,
+                                 trait_ref: ty::TraitRef<'tcx>,
                                  item_name: ast::Name)
                                  -> Ty<'tcx>
     {
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 83e0c398590..c2209ba2dc6 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -252,7 +252,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             // trait reference. Instead, this is done at the impl site.
             // Arguably this is wrong and we should treat the trait-reference
             // the same way as we treat the self-type.
-            bounds_checker.check_trait_ref(&*trait_ref);
+            bounds_checker.check_trait_ref(&trait_ref);
 
             let cause =
                 traits::ObligationCause::new(
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index fbfe73674e1..7ba92feafcd 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -300,7 +300,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
                                                              item.id);
 
                     self.instantiate_default_methods(local_def(item.id),
-                                                     &*trait_ref,
+                                                     &trait_ref,
                                                      &mut items);
                 }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 6cb6df008c1..b6672065e64 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -309,7 +309,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
 
     /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
     fn get_trait_def(&self, trait_id: ast::DefId)
-                     -> Rc<ty::TraitDef<'tcx>>
+                     -> &'tcx ty::TraitDef<'tcx>
     {
         let tcx = self.tcx;
 
@@ -361,7 +361,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
     }
 
     fn get_trait_def(&self, span: Span, id: ast::DefId)
-                     -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>
+                     -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
     {
         self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
             Ok(self.ccx.get_trait_def(id))
@@ -415,7 +415,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
 
     fn projected_ty(&self,
                     _span: Span,
-                    trait_ref: Rc<ty::TraitRef<'tcx>>,
+                    trait_ref: ty::TraitRef<'tcx>,
                     item_name: ast::Name)
                     -> Ty<'tcx>
     {
@@ -1210,7 +1210,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
 
 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                it: &ast::Item)
-                               -> Rc<ty::TraitDef<'tcx>>
+                               -> &'tcx ty::TraitDef<'tcx>
 {
     let def_id = local_def(it.id);
     let tcx = ccx.tcx;
@@ -1246,22 +1246,20 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         }
     }).collect();
 
-    let trait_ref = Rc::new(ty::TraitRef {
+    let trait_ref = ty::TraitRef {
         def_id: def_id,
         substs: substs,
-    });
+    };
 
-    let trait_def = Rc::new(ty::TraitDef {
+    let trait_def = ty::TraitDef {
         paren_sugar: paren_sugar,
         unsafety: unsafety,
         generics: ty_generics,
         trait_ref: trait_ref,
         associated_type_names: associated_type_names,
-    });
-
-    tcx.trait_defs.borrow_mut().insert(def_id, trait_def.clone());
+    };
 
-    return trait_def;
+    return tcx.intern_trait_def(trait_def);
 
     fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                  generics: &ast::Generics)
@@ -1357,7 +1355,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
     let assoc_predicates = predicates_for_associated_types(ccx,
                                                            generics,
                                                            &trait_predicates,
-                                                           &trait_def.trait_ref,
+                                                           trait_def.trait_ref,
                                                            items);
     trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
 
@@ -1369,7 +1367,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
     fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                                  ast_generics: &ast::Generics,
                                                  trait_predicates: &ty::GenericPredicates<'tcx>,
-                                                 self_trait_ref: &Rc<ty::TraitRef<'tcx>>,
+                                                 self_trait_ref: ty::TraitRef<'tcx>,
                                                  trait_items: &[P<ast::TraitItem>])
                                                  -> Vec<ty::Predicate<'tcx>>
     {
@@ -1382,7 +1380,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
             };
 
             let assoc_ty = ty::mk_projection(ccx.tcx,
-                                             self_trait_ref.clone(),
+                                             self_trait_ref,
                                              trait_item.ident.name);
 
             let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs
index fad8fbef2a4..3c8aab8447a 100644
--- a/src/librustc_typeck/constrained_type_params.rs
+++ b/src/librustc_typeck/constrained_type_params.rs
@@ -12,7 +12,6 @@ use middle::subst;
 use middle::ty::{self, Ty};
 
 use std::collections::HashSet;
-use std::rc::Rc;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum Parameter {
@@ -26,7 +25,7 @@ pub fn parameters_for_type<'tcx>(ty: Ty<'tcx>) -> Vec<Parameter> {
       .collect()
 }
 
-pub fn parameters_for_trait_ref<'tcx>(trait_ref: &Rc<ty::TraitRef<'tcx>>) -> Vec<Parameter> {
+pub fn parameters_for_trait_ref<'tcx>(trait_ref: &ty::TraitRef<'tcx>) -> Vec<Parameter> {
     let mut region_parameters =
         parameters_for_regions_in_substs(&trait_ref.substs);
 
@@ -71,7 +70,7 @@ fn parameters_for_region(region: &ty::Region) -> Option<Parameter> {
 
 pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>,
                                               predicates: &[ty::Predicate<'tcx>],
-                                              impl_trait_ref: Option<Rc<ty::TraitRef<'tcx>>>,
+                                              impl_trait_ref: Option<ty::TraitRef<'tcx>>,
                                               input_parameters: &mut HashSet<Parameter>)
 {
     loop {
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index 7575f12878a..9e8c23734e3 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -654,7 +654,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
             ast::ItemTrait(..) => {
                 let trait_def = ty::lookup_trait_def(tcx, did);
                 self.add_constraints_from_trait_ref(&trait_def.generics,
-                                                    &trait_def.trait_ref,
+                                                    trait_def.trait_ref,
                                                     self.invariant);
             }
 
@@ -844,7 +844,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
     fn add_constraints_from_trait_ref(&mut self,
                                       generics: &ty::Generics<'tcx>,
-                                      trait_ref: &ty::TraitRef<'tcx>,
+                                      trait_ref: ty::TraitRef<'tcx>,
                                       variance: VarianceTermPtr<'a>) {
         debug!("add_constraints_from_trait_ref: trait_ref={} variance={:?}",
                trait_ref.repr(self.tcx()),
@@ -946,7 +946,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.add_constraints_from_region(generics, data.bounds.region_bound, contra);
 
                 // Ignore the SelfSpace, it is erased.
-                self.add_constraints_from_trait_ref(generics, &*poly_trait_ref.0, variance);
+                self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance);
 
                 let projections = data.projection_bounds_with_self_ty(self.tcx(),
                                                                       self.tcx().types.err);