diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 60725fa6b7346..001f85f46f458 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -3094,6 +3094,7 @@ pub fn trans_crate(sess: session::Session,
               const_globals: @mut HashMap::new(),
               const_values: @mut HashMap::new(),
               extern_const_values: @mut HashMap::new(),
+              impl_method_cache: @mut HashMap::new(),
               module_data: @mut HashMap::new(),
               lltypes: @mut HashMap::new(),
               llsizingtypes: @mut HashMap::new(),
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index a12ce790d041b..2c80ef7980da7 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -205,6 +205,8 @@ pub struct CrateContext {
      // Cache of external const values
      extern_const_values: @mut HashMap<ast::def_id, ValueRef>,
 
+     impl_method_cache: @mut HashMap<(ast::def_id, ast::ident), ast::def_id>,
+
      module_data: @mut HashMap<~str, ValueRef>,
      lltypes: @mut HashMap<ty::t, TypeRef>,
      llsizingtypes: @mut HashMap<ty::t, TypeRef>,
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index d118c900b8113..93587d81dd682 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -381,35 +381,37 @@ pub fn method_from_methods(ms: &[@ast::method], name: ast::ident)
 pub fn method_with_name_or_default(ccx: @CrateContext,
                                    impl_id: ast::def_id,
                                    name: ast::ident) -> ast::def_id {
-    if impl_id.crate == ast::local_crate {
-        match ccx.tcx.items.get_copy(&impl_id.node) {
-          ast_map::node_item(@ast::item {
-                node: ast::item_impl(_, _, _, ref ms), _
-          }, _) => {
-              let did = method_from_methods(*ms, name);
-              if did.is_some() {
-                  return did.get();
-              } else {
-                  // Look for a default method
-                  let pmm = ccx.tcx.provided_methods;
-                  match pmm.find(&impl_id) {
-                      Some(pmis) => {
-                          for pmis.each |pmi| {
-                              if pmi.method_info.ident == name {
-                                  debug!("pmi.method_info.did = %?", pmi.method_info.did);
-                                  return pmi.method_info.did;
-                              }
-                          }
-                          fail!()
-                      }
-                      None => fail!()
-                  }
-              }
-          }
-          _ => fail!("method_with_name")
+    *do ccx.impl_method_cache.find_or_insert_with((impl_id, name)) |_| {
+        if impl_id.crate == ast::local_crate {
+            match ccx.tcx.items.get_copy(&impl_id.node) {
+                ast_map::node_item(@ast::item {
+                                   node: ast::item_impl(_, _, _, ref ms), _
+                                   }, _) => {
+                    let did = method_from_methods(*ms, name);
+                    if did.is_some() {
+                        did.get()
+                    } else {
+                        // Look for a default method
+                        let pmm = ccx.tcx.provided_methods;
+                        match pmm.find(&impl_id) {
+                            Some(pmis) => {
+                                for pmis.each |pmi| {
+                                    if pmi.method_info.ident == name {
+                                        debug!("pmi.method_info.did = %?", pmi.method_info.did);
+                                        return pmi.method_info.did;
+                                    }
+                                }
+                                fail!()
+                            }
+                            None => fail!()
+                        }
+                    }
+                }
+                _ => fail!("method_with_name")
+            }
+        } else {
+            csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
         }
-    } else {
-        csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
     }
 }
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index fe533f6ad80a5..271bc6bfd6c9b 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -271,6 +271,8 @@ struct ctxt_ {
     // A cache for the trait_methods() routine
     trait_methods_cache: @mut HashMap<def_id, @~[@Method]>,
 
+    impl_trait_cache: @mut HashMap<ast::def_id, Option<@ty::TraitRef>>,
+
     trait_refs: @mut HashMap<node_id, @TraitRef>,
     trait_defs: @mut HashMap<def_id, @TraitDef>,
 
@@ -967,6 +969,7 @@ pub fn mk_ctxt(s: session::Session,
         methods: @mut HashMap::new(),
         trait_method_def_ids: @mut HashMap::new(),
         trait_methods_cache: @mut HashMap::new(),
+        impl_trait_cache: @mut HashMap::new(),
         ty_param_defs: @mut HashMap::new(),
         adjustments: @mut HashMap::new(),
         normalized_cache: new_ty_hash(),
@@ -3749,22 +3752,24 @@ pub fn trait_method_def_ids(cx: ctxt, id: ast::def_id) -> @~[def_id] {
 }
 
 pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> {
-    if id.crate == ast::local_crate {
-        debug!("(impl_trait_ref) searching for trait impl %?", id);
-        match cx.items.find(&id.node) {
-           Some(&ast_map::node_item(@ast::item {
-                        node: ast::item_impl(_, opt_trait, _, _),
-                        _},
-                    _)) => {
-               match opt_trait {
-                   Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)),
-                   None => None
-               }
-           }
-           _ => None
+    *do cx.impl_trait_cache.find_or_insert_with(id) |_| {
+        if id.crate == ast::local_crate {
+            debug!("(impl_trait_ref) searching for trait impl %?", id);
+            match cx.items.find(&id.node) {
+                Some(&ast_map::node_item(@ast::item {
+                                         node: ast::item_impl(_, opt_trait, _, _),
+                                         _},
+                                         _)) => {
+                    match opt_trait {
+                        Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)),
+                        None => None
+                    }
+                }
+                _ => None
+            }
+        } else {
+            csearch::get_impl_trait(cx, id)
         }
-    } else {
-        csearch::get_impl_trait(cx, id)
     }
 }