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, + impl_method_cache: @mut HashMap<(ast::def_id, ast::ident), ast::def_id>, + module_data: @mut HashMap<~str, ValueRef>, lltypes: @mut HashMap, llsizingtypes: @mut HashMap, 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, + impl_trait_cache: @mut HashMap>, + trait_refs: @mut HashMap, trait_defs: @mut HashMap, @@ -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) } }