]> git.lizzy.rs Git - rust.git/commitdiff
kill the fake provided method stubs
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>
Wed, 30 Sep 2015 19:28:27 +0000 (22:28 +0300)
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>
Wed, 30 Sep 2015 21:14:56 +0000 (00:14 +0300)
this simplifies the code while reducing the size of libcore.rlib by
3.3 MiB (~1M of which is bloat a separate patch of mine removes
too), while reducing rustc memory usage on small crates by 18MiB.

This also simplifies the code considerably.

14 files changed:
src/librustc/metadata/common.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/ty/context.rs
src/librustc/middle/ty/mod.rs
src/librustc/middle/ty/util.rs
src/librustc_privacy/lib.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/meth.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/inline.rs

index bc54d9ff133963791757734a8805056394a1c239..a6cbb4ec50490467bed45a7a6fac0d6582477826 100644 (file)
@@ -180,7 +180,7 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
 pub const tag_misc_info: usize = 0x108; // top-level only
 pub const tag_misc_info_crate_items: usize = 0x7c;
 
-pub const tag_item_method_provided_source: usize = 0x7d;
+// GAP 0x7d
 pub const tag_item_impl_vtables: usize = 0x7e;
 
 pub const tag_impls: usize = 0x109; // top-level only
index 648ebdefffe6cca3f7735fd081e3ab9dde76145e..77863ee3c87a2f8509052fbf4166134b97b0fd6d 100644 (file)
@@ -187,12 +187,6 @@ fn item_def_id(d: rbml::Doc, cdata: Cmd) -> DefId {
     translated_def_id(cdata, reader::get_doc(d, tag_def_id))
 }
 
-fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<DefId> {
-    reader::maybe_get_doc(d, tag_item_method_provided_source).map(|doc| {
-        translated_def_id(cdata, doc)
-    })
-}
-
 fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> {
     reader::tagged_docs(d, tag_items_data_item_reexport)
 }
@@ -276,11 +270,14 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
     match fam {
         Constant  => {
             // Check whether we have an associated const item.
-            if item_sort(item) == Some('C') {
-                DlDef(def::DefAssociatedConst(did))
-            } else {
-                // Regular const item.
-                DlDef(def::DefConst(did))
+            match item_sort(item) {
+                Some('C') | Some('c') => {
+                    DlDef(def::DefAssociatedConst(did))
+                }
+                _ => {
+                    // Regular const item.
+                    DlDef(def::DefConst(did))
+                }
             }
         }
         ImmStatic => DlDef(def::DefStatic(did, false)),
@@ -818,7 +815,7 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
     reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| {
         let def_id = item_def_id(doc, cdata);
         match item_sort(doc) {
-            Some('C') => ty::ConstTraitItemId(def_id),
+            Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
             Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
             Some('t') => ty::TypeTraitItemId(def_id),
             _ => panic!("unknown impl item sort"),
@@ -864,16 +861,15 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
     let vis = item_visibility(item_doc);
 
     match item_sort(item_doc) {
-        Some('C') => {
+        sort @ Some('C') | sort @ Some('c') => {
             let ty = doc_type(item_doc, tcx, cdata);
-            let default = get_provided_source(item_doc, cdata);
             ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
                 name: name,
                 ty: ty,
                 vis: vis,
                 def_id: def_id,
                 container: container,
-                default: default,
+                has_value: sort == Some('C')
             }))
         }
         Some('r') | Some('p') => {
@@ -881,7 +877,6 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
             let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics);
             let fty = doc_method_fty(item_doc, tcx, cdata);
             let explicit_self = get_explicit_self(item_doc);
-            let provided_source = get_provided_source(item_doc, cdata);
 
             ty::MethodTraitItem(Rc::new(ty::Method::new(name,
                                                         generics,
@@ -890,8 +885,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
                                                         explicit_self,
                                                         vis,
                                                         def_id,
-                                                        container,
-                                                        provided_source)))
+                                                        container)))
         }
         Some('t') => {
             let ty = maybe_doc_type(item_doc, tcx, cdata);
@@ -913,7 +907,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
     reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
         let def_id = item_def_id(mth, cdata);
         match item_sort(mth) {
-            Some('C') => ty::ConstTraitItemId(def_id),
+            Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
             Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
             Some('t') => ty::TypeTraitItemId(def_id),
             _ => panic!("unknown trait item sort"),
@@ -967,18 +961,19 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
             let did = item_def_id(ac_id, cdata);
             let ac_doc = cdata.lookup_item(did.node);
 
-            if item_sort(ac_doc) == Some('C') {
-                let trait_item = get_impl_or_trait_item(intr.clone(),
-                                                        cdata,
-                                                        did.node,
-                                                        tcx);
-                if let ty::ConstTraitItem(ref ac) = trait_item {
-                    Some((*ac).clone())
-                } else {
-                    None
+            match item_sort(ac_doc) {
+                Some('C') | Some('c') => {
+                    let trait_item = get_impl_or_trait_item(intr.clone(),
+                                                            cdata,
+                                                            did.node,
+                                                            tcx);
+                    if let ty::ConstTraitItem(ref ac) = trait_item {
+                        Some((*ac).clone())
+                    } else {
+                        None
+                    }
                 }
-            } else {
-                None
+                _ => None
             }
         })
     }).collect()
index 8acdc7e8ce2baad767eba6a86e86e9ae36480f66..0d83103e0bb495573d1271b44d71d1f65198b061 100644 (file)
@@ -609,13 +609,6 @@ fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
     rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8);
 }
 
-fn encode_provided_source(rbml_w: &mut Encoder,
-                          source_opt: Option<DefId>) {
-    if let Some(source) = source_opt {
-        rbml_w.wr_tagged_u64(tag_item_method_provided_source, def_to_u64(source));
-    }
-}
-
 fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                           rbml_w: &mut Encoder,
                           field: ty::FieldDef<'tcx>,
@@ -776,7 +769,6 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         }
         _ => encode_family(rbml_w, METHOD_FAMILY)
     }
-    encode_provided_source(rbml_w, method_ty.provided_source);
 }
 
 fn encode_info_for_associated_const(ecx: &EncodeContext,
@@ -795,7 +787,6 @@ fn encode_info_for_associated_const(ecx: &EncodeContext,
     encode_name(rbml_w, associated_const.name);
     encode_visibility(rbml_w, associated_const.vis);
     encode_family(rbml_w, 'C');
-    encode_provided_source(rbml_w, associated_const.default);
 
     encode_parent_item(rbml_w, DefId::local(parent_id));
     encode_item_sort(rbml_w, 'C');
@@ -1367,13 +1358,10 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
                     encode_def_id(rbml_w, associated_const.def_id);
                     encode_visibility(rbml_w, associated_const.vis);
 
-                    encode_provided_source(rbml_w, associated_const.default);
-
                     let elem = ast_map::PathName(associated_const.name);
                     encode_path(rbml_w,
                                 path.clone().chain(Some(elem)));
 
-                    encode_item_sort(rbml_w, 'C');
                     encode_family(rbml_w, 'C');
 
                     encode_bounds_and_type_for_item(rbml_w, ecx,
@@ -1429,7 +1417,13 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
             let trait_item = &*ms[i];
             encode_attributes(rbml_w, &trait_item.attrs);
             match trait_item.node {
-                hir::ConstTraitItem(_, _) => {
+                hir::ConstTraitItem(_, ref default) => {
+                    if default.is_some() {
+                        encode_item_sort(rbml_w, 'C');
+                    } else {
+                        encode_item_sort(rbml_w, 'c');
+                    }
+
                     encode_inlined_item(ecx, rbml_w,
                                         InlinedItemRef::TraitItem(def_id, trait_item));
                 }
index f32e86e276c711380c07803e9b707bc75def7e87..57f04af2ba9138103fc05397540fa3356e2a8f75 100644 (file)
@@ -235,8 +235,6 @@ pub struct ctxt<'tcx> {
     pub ty_param_defs: RefCell<NodeMap<ty::TypeParameterDef<'tcx>>>,
     pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
     pub lang_items: middle::lang_items::LanguageItems,
-    /// A mapping of fake provided method def_ids to the default implementation
-    pub provided_method_sources: RefCell<DefIdMap<DefId>>,
 
     /// Maps from def-id of a type or region parameter to its
     /// (inferred) variance.
@@ -471,7 +469,6 @@ pub fn create_and_enter<F, R>(s: Session,
             ty_param_defs: RefCell::new(NodeMap()),
             normalized_cache: RefCell::new(FnvHashMap()),
             lang_items: lang_items,
-            provided_method_sources: RefCell::new(DefIdMap()),
             inherent_impls: RefCell::new(DefIdMap()),
             impl_items: RefCell::new(DefIdMap()),
             used_unsafe: RefCell::new(NodeSet()),
index c3e7fd4ceca21b47bb0479c10ff2cbafbf8c99e3..7ec39619d9cfd4be156c7eff57016589ecbbc825 100644 (file)
@@ -235,9 +235,6 @@ pub struct Method<'tcx> {
     pub vis: hir::Visibility,
     pub def_id: DefId,
     pub container: ImplOrTraitItemContainer,
-
-    // If this method is provided, we need to know where it came from
-    pub provided_source: Option<DefId>
 }
 
 impl<'tcx> Method<'tcx> {
@@ -248,8 +245,7 @@ pub fn new(name: Name,
                explicit_self: ExplicitSelfCategory,
                vis: hir::Visibility,
                def_id: DefId,
-               container: ImplOrTraitItemContainer,
-               provided_source: Option<DefId>)
+               container: ImplOrTraitItemContainer)
                -> Method<'tcx> {
        Method {
             name: name,
@@ -260,7 +256,6 @@ pub fn new(name: Name,
             vis: vis,
             def_id: def_id,
             container: container,
-            provided_source: provided_source
         }
     }
 
@@ -293,7 +288,7 @@ pub struct AssociatedConst<'tcx> {
     pub vis: hir::Visibility,
     pub def_id: DefId,
     pub container: ImplOrTraitItemContainer,
-    pub default: Option<DefId>,
+    pub has_value: bool
 }
 
 #[derive(Clone, Copy, Debug)]
@@ -2105,10 +2100,6 @@ pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
         }
     }
 
-    pub fn provided_source(&self, id: DefId) -> Option<DefId> {
-        self.provided_method_sources.borrow().get(&id).cloned()
-    }
-
     pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
         if id.is_local() {
             if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
@@ -2477,16 +2468,9 @@ pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: DefId) {
             // the map. This is a bit unfortunate.
             for impl_item_def_id in &impl_items {
                 let method_def_id = impl_item_def_id.def_id();
-                match self.impl_or_trait_item(method_def_id) {
-                    MethodTraitItem(method) => {
-                        if let Some(source) = method.provided_source {
-                            self.provided_method_sources
-                                .borrow_mut()
-                                .insert(method_def_id, source);
-                        }
-                    }
-                    _ => {}
-                }
+                // load impl items eagerly for convenience
+                // FIXME: we may want to load these lazily
+                self.impl_or_trait_item(method_def_id);
             }
 
             // Store the implementation info.
index 3a90f3e0136e50d008b65b441e09deeede4b18e8..a431bbaeeb8e37c081f448c0dd60b465f1218340 100644 (file)
@@ -14,7 +14,7 @@
 use middle::const_eval::{self, ConstVal, ErrKind};
 use middle::const_eval::EvalHint::UncheckedExprHint;
 use middle::def_id::DefId;
-use middle::subst;
+use middle::subst::{self, Subst, Substs};
 use middle::infer;
 use middle::pat_util;
 use middle::traits;
@@ -26,6 +26,7 @@
 
 use std::cmp;
 use std::hash::{Hash, SipHasher, Hasher};
+use std::rc::Rc;
 use syntax::ast::{self, Name};
 use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
 use syntax::codemap::Span;
@@ -646,6 +647,58 @@ pub fn is_adt_dtorck(&self, adt: ty::AdtDef<'tcx>) -> bool {
     }
 }
 
+#[derive(Debug)]
+pub struct ImplMethod<'tcx> {
+    pub method: Rc<ty::Method<'tcx>>,
+    pub substs: Substs<'tcx>,
+    pub is_provided: bool
+}
+
+impl<'tcx> ty::ctxt<'tcx> {
+    #[inline(never)] // is this perfy enough?
+    pub fn get_impl_method(&self,
+                           impl_def_id: DefId,
+                           substs: Substs<'tcx>,
+                           name: Name)
+                           -> ImplMethod<'tcx>
+    {
+        // there don't seem to be nicer accessors to these:
+        let impl_or_trait_items_map = self.impl_or_trait_items.borrow();
+
+        for impl_item in &self.impl_items.borrow()[&impl_def_id] {
+            if let ty::MethodTraitItem(ref meth) =
+                impl_or_trait_items_map[&impl_item.def_id()] {
+                if meth.name == name {
+                    return ImplMethod {
+                        method: meth.clone(),
+                        substs: substs,
+                        is_provided: false
+                    }
+                }
+            }
+        }
+
+        // It is not in the impl - get the default from the trait.
+        let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
+        for trait_item in self.trait_items(trait_ref.def_id).iter() {
+            if let &ty::MethodTraitItem(ref meth) = trait_item {
+                if meth.name == name {
+                    let impl_to_trait_substs = self
+                        .make_substs_for_receiver_types(&trait_ref, meth);
+                    return ImplMethod {
+                        method: meth.clone(),
+                        substs: impl_to_trait_substs.subst(self, &substs),
+                        is_provided: true
+                    }
+                }
+            }
+        }
+
+        self.sess.bug(&format!("method {:?} not found in {:?}",
+                               name, impl_def_id))
+    }
+}
+
 impl<'tcx> ty::TyS<'tcx> {
     fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
                        bound: ty::BuiltinBound,
index cf964107d16b38e201fb933e3d8418380efe356f..2090527ca202d1fa301c1d24a06b353d29b9e725 100644 (file)
@@ -725,19 +725,6 @@ fn check_static_method(&mut self,
                            span: Span,
                            method_id: DefId,
                            name: ast::Name) {
-        // If the method is a default method, we need to use the def_id of
-        // the default implementation.
-        let method_id = match self.tcx.impl_or_trait_item(method_id) {
-            ty::MethodTraitItem(method_type) => {
-                method_type.provided_source.unwrap_or(method_id)
-            }
-            _ => {
-                self.tcx.sess
-                    .span_bug(span,
-                              "got non-method item in check_static_method")
-            }
-        };
-
         self.report_error(self.ensure_public(span,
                                              method_id,
                                              None,
index 124f50d660329bddae84f400fbc1a18a0b458fae..cfa77d57bf619f7f646018e2a3316682cf358311 100644 (file)
@@ -26,7 +26,7 @@
 use middle::def_id::{DefId, LOCAL_CRATE};
 use middle::infer::normalize_associated_type;
 use middle::subst;
-use middle::subst::{Subst, Substs};
+use middle::subst::{Substs};
 use rustc::front::map as hir_map;
 use trans::adt;
 use trans::base;
@@ -398,77 +398,14 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
     assert!(!substs.types.has_escaping_regions());
     let substs = substs.erase_regions();
 
-    // Load the info for the appropriate trait if necessary.
-    match tcx.trait_of_item(def_id) {
-        None => {}
-        Some(trait_id) => {
-            tcx.populate_implementations_for_trait_if_necessary(trait_id)
-        }
-    }
-
-    // We need to do a bunch of special handling for default methods.
-    // We need to modify the def_id and our substs in order to monomorphize
-    // the function.
-    let (is_default, def_id, substs) = match tcx.provided_source(def_id) {
-        None => {
-            (false, def_id, tcx.mk_substs(substs))
-        }
-        Some(source_id) => {
-            // There are two relevant substitutions when compiling
-            // default methods. First, there is the substitution for
-            // the type parameters of the impl we are using and the
-            // method we are calling. This substitution is the substs
-            // argument we already have.
-            // In order to compile a default method, though, we need
-            // to consider another substitution: the substitution for
-            // the type parameters on trait; the impl we are using
-            // implements the trait at some particular type
-            // parameters, and we need to substitute for those first.
-            // So, what we need to do is find this substitution and
-            // compose it with the one we already have.
-
-            let impl_id = tcx.impl_or_trait_item(def_id).container()
-                                                             .id();
-            let impl_or_trait_item = tcx.impl_or_trait_item(source_id);
-            match impl_or_trait_item {
-                ty::MethodTraitItem(method) => {
-                    let trait_ref = tcx.impl_trait_ref(impl_id).unwrap();
-
-                    // Compute the first substitution
-                    let first_subst =
-                        tcx.make_substs_for_receiver_types(&trait_ref, &*method)
-                        .erase_regions();
-
-                    // And compose them
-                    let new_substs = tcx.mk_substs(first_subst.subst(tcx, &substs));
-
-                    debug!("trans_fn_with_vtables - default method: \
-                            substs = {:?}, trait_subst = {:?}, \
-                            first_subst = {:?}, new_subst = {:?}",
-                           substs, trait_ref.substs,
-                           first_subst, new_substs);
-
-                    (true, source_id, new_substs)
-                }
-                _ => {
-                    tcx.sess.bug("trans_fn_ref_with_vtables() tried \
-                                  to translate a non-method?!")
-                }
-            }
-        }
-    };
-
     // Check whether this fn has an inlined copy and, if so, redirect
     // def_id to the local id of the inlined copy.
     let def_id = inline::maybe_instantiate_inline(ccx, def_id);
 
-    // We must monomorphise if the fn has type parameters, is a default method,
-    // or is a named tuple constructor.
-    let must_monomorphise = if !substs.types.is_empty() || is_default {
-        true
-    } else if def_id.is_local() {
+    fn is_named_tuple_constructor(tcx: &ty::ctxt, def_id: DefId) -> bool {
+        if !def_id.is_local() { return false; }
         let map_node = session::expect(
-            ccx.sess(),
+            &tcx.sess,
             tcx.map.find(def_id.node),
             || "local item should be in ast map".to_string());
 
@@ -480,9 +417,9 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
             hir_map::NodeStructCtor(_) => true,
             _ => false
         }
-    } else {
-        false
-    };
+    }
+    let must_monomorphise =
+        !substs.types.is_empty() || is_named_tuple_constructor(tcx, def_id);
 
     debug!("trans_fn_ref_with_substs({:?}) must_monomorphise: {}",
            def_id, must_monomorphise);
@@ -497,6 +434,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
             MethodCallKey(_) => None,
         };
 
+        let substs = tcx.mk_substs(substs);
         let (val, fn_ty, must_cast) =
             monomorphize::monomorphic_fn(ccx, def_id, substs, opt_ref_id);
         if must_cast && node != ExprId(0) {
@@ -561,10 +499,10 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
     let llty = type_of::type_of_fn_from_ty(ccx, fn_type);
     let llptrty = llty.ptr_to();
     if common::val_ty(val) != llptrty {
-        debug!("trans_fn_ref_with_vtables(): casting pointer!");
+        debug!("trans_fn_ref_with_substs(): casting pointer!");
         val = consts::ptrcast(val, llptrty);
     } else {
-        debug!("trans_fn_ref_with_vtables(): not casting pointer!");
+        debug!("trans_fn_ref_with_substs(): not casting pointer!");
     }
 
     Datum::new(val, fn_type, Rvalue::new(ByValue))
index 6dcc60dc96276b90431cb4c63a25aaad9f5df048..614453830c63a47f392abd635485a8ffda83f6a3 100644 (file)
@@ -250,10 +250,10 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                      impl_self,
                                                      rcvr_method));
 
-            let mth_id = method_with_name(ccx, impl_did, mname);
-            trans_fn_ref_with_substs(ccx, mth_id, ExprId(expr_id),
+            let mth = tcx.get_impl_method(impl_did, callee_substs, mname);
+            trans_fn_ref_with_substs(ccx, mth.method.def_id, ExprId(expr_id),
                                      param_substs,
-                                     callee_substs)
+                                     mth.substs)
         }
         traits::VtableObject(ref data) => {
             let idx = traits::get_vtable_index_of_object_method(tcx, data, method_id);
@@ -269,28 +269,6 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     }
 }
 
-fn method_with_name(ccx: &CrateContext, impl_id: DefId, name: ast::Name)
-                    -> DefId {
-    match ccx.impl_method_cache().borrow().get(&(impl_id, name)).cloned() {
-        Some(m) => return m,
-        None => {}
-    }
-
-    let impl_items = ccx.tcx().impl_items.borrow();
-    let impl_items =
-        impl_items.get(&impl_id)
-                  .expect("could not find impl while translating");
-    let meth_did = impl_items.iter()
-                             .find(|&did| {
-                                ccx.tcx().impl_or_trait_item(did.def_id()).name() == name
-                             }).expect("could not find method while \
-                                        translating");
-
-    ccx.impl_method_cache().borrow_mut().insert((impl_id, name),
-                                              meth_did.def_id());
-    meth_did.def_id()
-}
-
 fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                           method_call: MethodCall,
                                           self_expr: Option<&hir::Expr>,
@@ -312,20 +290,19 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                         item")
                 }
             };
-            let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
-
             // create a concatenated set of substitutions which includes
             // those from the impl and those from the method:
             let callee_substs =
                 combine_impl_and_methods_tps(
                     bcx, MethodCallKey(method_call), vtable_impl.substs);
 
+            let mth = bcx.tcx().get_impl_method(impl_did, callee_substs, mname);
             // translate the function
             let datum = trans_fn_ref_with_substs(bcx.ccx(),
-                                                 mth_id,
+                                                 mth.method.def_id,
                                                  MethodCallKey(method_call),
                                                  bcx.fcx.param_substs,
-                                                 callee_substs);
+                                                 mth.substs);
 
             Callee { bcx: bcx, data: Fn(datum.val), ty: datum.ty }
         }
@@ -738,22 +715,17 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
             // The substitutions we have are on the impl, so we grab
             // the method type from the impl to substitute into.
-            let impl_method_def_id = method_with_name(ccx, impl_id, name);
-            let impl_method_type = match tcx.impl_or_trait_item(impl_method_def_id) {
-                ty::MethodTraitItem(m) => m,
-                _ => ccx.sess().bug("should be a method, not other assoc item"),
-            };
+            let mth = tcx.get_impl_method(impl_id, substs.clone(), name);
 
-            debug!("emit_vtable_methods: impl_method_type={:?}",
-                   impl_method_type);
+            debug!("emit_vtable_methods: mth={:?}", mth);
 
             // If this is a default method, it's possible that it
             // relies on where clauses that do not hold for this
             // particular set of type parameters. Note that this
             // method could then never be called, so we do not want to
             // try and trans it, in that case. Issue #23435.
-            if tcx.provided_source(impl_method_def_id).is_some() {
-                let predicates = impl_method_type.predicates.predicates.subst(tcx, &substs);
+            if mth.is_provided {
+                let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs);
                 if !normalize_and_test_predicates(ccx, predicates.into_vec()) {
                     debug!("emit_vtable_methods: predicates do not hold");
                     return nullptr;
@@ -761,10 +733,10 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             }
 
             trans_fn_ref_with_substs(ccx,
-                                     impl_method_def_id,
+                                     mth.method.def_id,
                                      ExprId(0),
                                      param_substs,
-                                     substs.clone()).val
+                                     mth.substs).val
         })
         .collect()
 }
index 6961f3444d90875bdad2183ba6ba8d69b73e6de5..821615d0341f0e8e08cb48ed37ca96dbc9e2af90 100644 (file)
@@ -182,7 +182,14 @@ fn report_candidates(fcx: &FnCtxt,
                 CandidateSource::ImplSource(impl_did) => {
                     // Provide the best span we can. Use the item, if local to crate, else
                     // the impl, if local to crate (item may be defaulted), else the call site.
-                    let item = impl_item(fcx.tcx(), impl_did, item_name).unwrap();
+                    let item = impl_item(fcx.tcx(), impl_did, item_name)
+                        .or_else(|| {
+                            trait_item(
+                                fcx.tcx(),
+                                fcx.tcx().impl_trait_ref(impl_did).unwrap().def_id,
+                                item_name
+                            )
+                        }).unwrap();
                     let impl_span = fcx.tcx().map.def_id_span(impl_did, span);
                     let item_span = fcx.tcx().map.def_id_span(item.def_id(), impl_span);
 
index 324a4a4ca083730ff26f6c4c9071ffa172053de6..e62f5b82e7a6ec7e23eeef3c8c6d6232688299c4 100644 (file)
@@ -989,7 +989,6 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
     // Check for missing items from trait
     let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
-    let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
     let mut missing_items = Vec::new();
     let mut invalidated_items = Vec::new();
     let associated_type_overridden = overridden_associated_type.is_some();
@@ -1004,9 +1003,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         _ => false,
                     }
                 });
-                let is_provided =
-                    associated_consts.iter().any(|ac| ac.default.is_some() &&
-                                                 ac.name == associated_const.name);
+                let is_provided = associated_const.has_value;
+
                 if !is_implemented {
                     if !is_provided {
                         missing_items.push(associated_const.name);
index 0c152a419d25f56ce19ec7f8a5913af2eef7b626..714bd1d2bc5f30b15dd92101596d2622868d7f04 100644 (file)
 use middle::traits;
 use middle::ty;
 use middle::ty::RegionEscape;
-use middle::ty::{ImplContainer, ImplOrTraitItemId, ConstTraitItemId};
+use middle::ty::{ImplOrTraitItemId, ConstTraitItemId};
 use middle::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment};
 use middle::ty::{Ty, TyBool, TyChar, TyEnum, TyError};
-use middle::ty::{TyParam, TypeScheme, TyRawPtr};
+use middle::ty::{TyParam, TyRawPtr};
 use middle::ty::{TyRef, TyStruct, TyTrait, TyTuple};
 use middle::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt};
 use middle::ty::{TyUint, TyClosure, TyBox, TyBareFn};
@@ -168,65 +168,6 @@ fn check_implementation(&self, item: &Item) {
         tcx.impl_items.borrow_mut().insert(impl_did, impl_items);
     }
 
-    // Creates default method IDs and performs type substitutions for an impl
-    // and trait pair. Then, for each provided method in the trait, inserts a
-    // `ProvidedMethodInfo` instance into the `provided_method_sources` map.
-    fn instantiate_default_methods(
-            &self,
-            impl_id: DefId,
-            trait_ref: &ty::TraitRef<'tcx>,
-            all_impl_items: &mut Vec<ImplOrTraitItemId>) {
-        let tcx = self.crate_context.tcx;
-        debug!("instantiate_default_methods(impl_id={:?}, trait_ref={:?})",
-               impl_id, trait_ref);
-
-        let impl_type_scheme = tcx.lookup_item_type(impl_id);
-
-        let prov = tcx.provided_trait_methods(trait_ref.def_id);
-        for trait_method in &prov {
-            // Synthesize an ID.
-            let new_id = tcx.sess.next_node_id();
-            let new_did = DefId::local(new_id);
-
-            debug!("new_did={:?} trait_method={:?}", new_did, trait_method);
-
-            // Create substitutions for the various trait parameters.
-            let new_method_ty =
-                Rc::new(subst_receiver_types_in_method_ty(
-                    tcx,
-                    impl_id,
-                    &impl_type_scheme,
-                    trait_ref,
-                    new_did,
-                    &**trait_method,
-                    Some(trait_method.def_id)));
-
-            debug!("new_method_ty={:?}", new_method_ty);
-            all_impl_items.push(MethodTraitItemId(new_did));
-
-            // construct the polytype for the method based on the
-            // method_ty.  it will have all the generics from the
-            // impl, plus its own.
-            let new_polytype = ty::TypeScheme {
-                generics: new_method_ty.generics.clone(),
-                ty: tcx.mk_fn(Some(new_did),
-                              tcx.mk_bare_fn(new_method_ty.fty.clone()))
-            };
-            debug!("new_polytype={:?}", new_polytype);
-
-            tcx.register_item_type(new_did, new_polytype);
-            tcx.predicates.borrow_mut().insert(new_did, new_method_ty.predicates.clone());
-            tcx.impl_or_trait_items
-               .borrow_mut()
-               .insert(new_did, ty::MethodTraitItem(new_method_ty));
-
-            // Pair the new synthesized ID up with the
-            // ID of the method.
-            self.crate_context.tcx.provided_method_sources.borrow_mut()
-                .insert(new_did, trait_method.def_id);
-        }
-    }
-
     fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
         match self.inherent_impls.borrow().get(&base_def_id) {
             Some(implementation_list) => {
@@ -252,8 +193,7 @@ fn add_trait_impl(&self, impl_trait_ref: ty::TraitRef<'tcx>, impl_def_id: DefId)
     fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
         match item.node {
             ItemImpl(_, _, _, _, _, ref impl_items) => {
-                let mut items: Vec<ImplOrTraitItemId> =
-                        impl_items.iter().map(|impl_item| {
+                impl_items.iter().map(|impl_item| {
                     match impl_item.node {
                         hir::ConstImplItem(..) => {
                             ConstTraitItemId(DefId::local(impl_item.id))
@@ -265,14 +205,7 @@ fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
                             TypeTraitItemId(DefId::local(impl_item.id))
                         }
                     }
-                }).collect();
-
-                let def_id = DefId::local(item.id);
-                if let Some(trait_ref) = self.crate_context.tcx.impl_trait_ref(def_id) {
-                    self.instantiate_default_methods(def_id, &trait_ref, &mut items);
-                }
-
-                items
+                }).collect()
             }
             _ => {
                 self.crate_context.tcx.sess.span_bug(item.span,
@@ -575,55 +508,6 @@ fn enforce_trait_manually_implementable(tcx: &ty::ctxt, sp: Span, trait_def_id:
                "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
 }
 
-fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                           impl_id: DefId,
-                                           impl_type_scheme: &ty::TypeScheme<'tcx>,
-                                           trait_ref: &ty::TraitRef<'tcx>,
-                                           new_def_id: DefId,
-                                           method: &ty::Method<'tcx>,
-                                           provided_source: Option<DefId>)
-                                           -> ty::Method<'tcx>
-{
-    let combined_substs = tcx.make_substs_for_receiver_types(trait_ref, method);
-
-    debug!("subst_receiver_types_in_method_ty: combined_substs={:?}",
-           combined_substs);
-
-    let method_predicates = method.predicates.subst(tcx, &combined_substs);
-    let mut method_generics = method.generics.subst(tcx, &combined_substs);
-
-    // replace the type parameters declared on the trait with those
-    // from the impl
-    for &space in &[subst::TypeSpace, subst::SelfSpace] {
-        method_generics.types.replace(
-            space,
-            impl_type_scheme.generics.types.get_slice(space).to_vec());
-        method_generics.regions.replace(
-            space,
-            impl_type_scheme.generics.regions.get_slice(space).to_vec());
-    }
-
-    debug!("subst_receiver_types_in_method_ty: method_generics={:?}",
-           method_generics);
-
-    let method_fty = method.fty.subst(tcx, &combined_substs);
-
-    debug!("subst_receiver_types_in_method_ty: method_ty={:?}",
-           method.fty);
-
-    ty::Method::new(
-        method.name,
-        method_generics,
-        method_predicates,
-        method_fty,
-        method.explicit_self,
-        method.vis,
-        new_def_id,
-        ImplContainer(impl_id),
-        provided_source
-    )
-}
-
 pub fn check_coherence(crate_context: &CrateCtxt) {
     CoherenceChecker {
         crate_context: crate_context,
index 9e1b20258f07b05d68135178a1dda0dd246aac63..a59e6f54c81d7d30c214e5fce90e175076c475ae 100644 (file)
@@ -599,8 +599,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                     explicit_self_category,
                                     vis,
                                     def_id,
-                                    container,
-                                    None);
+                                    container);
 
     let fty = ccx.tcx.mk_fn(Some(def_id),
                             ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
@@ -647,13 +646,12 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                       id: ast::NodeId,
                                       vis: hir::Visibility,
                                       ty: ty::Ty<'tcx>,
-                                      default: Option<&hir::Expr>)
+                                      has_value: bool)
 {
     ccx.tcx.predicates.borrow_mut().insert(DefId::local(id),
                                            ty::GenericPredicates::empty());
 
     write_ty_to_tcx(ccx.tcx, id, ty);
-    let default_id = default.map(|expr| DefId::local(expr.id));
 
     let associated_const = Rc::new(ty::AssociatedConst {
         name: name,
@@ -661,7 +659,7 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         def_id: DefId::local(id),
         container: container,
         ty: ty,
-        default: default_id,
+        has_value: has_value
     });
     ccx.tcx.impl_or_trait_items.borrow_mut()
        .insert(DefId::local(id), ty::ConstTraitItem(associated_const));
@@ -837,7 +835,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
                     span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
                 }
 
-                if let hir::ConstImplItem(ref ty, ref expr) = impl_item.node {
+                if let hir::ConstImplItem(ref ty, _) = impl_item.node {
                     let ty = ccx.icx(&ty_predicates)
                                 .to_ty(&ExplicitRscope, &*ty);
                     tcx.register_item_type(DefId::local(impl_item.id),
@@ -848,7 +846,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
                     convert_associated_const(ccx, ImplContainer(DefId::local(it.id)),
                                              impl_item.name, impl_item.id,
                                              impl_item.vis.inherit_from(parent_visibility),
-                                             ty, Some(&*expr));
+                                             ty, true /* has_value */);
                 }
             }
 
@@ -926,7 +924,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
                                                });
                         convert_associated_const(ccx, TraitContainer(DefId::local(it.id)),
                                                  trait_item.name, trait_item.id,
-                                                 hir::Public, ty, default.as_ref().map(|d| &**d));
+                                                 hir::Public, ty, default.is_some());
                     }
                     _ => {}
                 }
index 21895301a6ce8d8902f4dfa746c623f45c6cf0ee..ee772411c4e9af85b8b8ce01b8c385a546d4ee06 100644 (file)
@@ -317,10 +317,11 @@ pub fn build_impl(cx: &DocContext,
             ty::ConstTraitItem(ref assoc_const) => {
                 let did = assoc_const.def_id;
                 let type_scheme = tcx.lookup_item_type(did);
-                let default = match assoc_const.default {
-                    Some(_) => Some(const_eval::lookup_const_by_id(tcx, did, None)
-                                               .unwrap().span.to_src(cx)),
-                    None => None,
+                let default = if assoc_const.has_value {
+                    Some(const_eval::lookup_const_by_id(tcx, did, None)
+                         .unwrap().span.to_src(cx))
+                } else {
+                    None
                 };
                 Some(clean::Item {
                     name: Some(assoc_const.name.clean(cx)),
@@ -339,9 +340,6 @@ pub fn build_impl(cx: &DocContext,
                 if method.vis != hir::Public && associated_trait.is_none() {
                     return None
                 }
-                if method.provided_source.is_some() {
-                    return None
-                }
                 let mut item = method.clean(cx);
                 item.inner = match item.inner.clone() {
                     clean::TyMethodItem(clean::TyMethod {