about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJimmy Brisson <theotherjimmy@gmail.com>2017-10-09 10:39:53 -0500
committerJimmy Brisson <theotherjimmy@gmail.com>2017-10-13 09:34:13 -0500
commit81f9d4e78f3bc17bc803c793ecac43861ee5eed5 (patch)
tree2c9a5324d9cc7e6eb32f2287aa10a53de0afdca8
parentb640c2b95a13ead0285490323b55bfbe01da8e60 (diff)
downloadrust-81f9d4e78f3bc17bc803c793ecac43861ee5eed5.tar.gz
rust-81f9d4e78f3bc17bc803c793ecac43861ee5eed5.zip
Wrap vtable_methods return type in RC
-rw-r--r--src/librustc/traits/mod.rs84
-rw-r--r--src/librustc/ty/maps/mod.rs2
-rw-r--r--src/librustc_trans/collector.rs2
-rw-r--r--src/librustc_trans/meth.rs3
4 files changed, 47 insertions, 44 deletions
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 8da0f8f13ff..53a974a4bbb 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -653,50 +653,52 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 pub fn vtable_methods<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>)
-    -> Vec<Option<(DefId, &'tcx Substs<'tcx>)>>
+    -> Rc<Vec<Option<(DefId, &'tcx Substs<'tcx>)>>>
 {
     debug!("vtable_methods({:?})", trait_ref);
 
-    supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
-        let trait_methods = tcx.associated_items(trait_ref.def_id())
-            .filter(|item| item.kind == ty::AssociatedKind::Method);
-
-        // Now list each method's DefId and Substs (for within its trait).
-        // If the method can never be called from this object, produce None.
-        trait_methods.map(move |trait_method| {
-            debug!("vtable_methods: trait_method={:?}", trait_method);
-            let def_id = trait_method.def_id;
-
-            // Some methods cannot be called on an object; skip those.
-            if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
-                debug!("vtable_methods: not vtable safe");
-                return None;
-            }
-
-            // the method may have some early-bound lifetimes, add
-            // regions for those
-            let substs = Substs::for_item(tcx, def_id,
-                                          |_, _| tcx.types.re_erased,
-                                          |def, _| trait_ref.substs().type_for_def(def));
-
-            // the trait type may have higher-ranked lifetimes in it;
-            // so erase them if they appear, so that we get the type
-            // at some particular call site
-            let substs = tcx.erase_late_bound_regions_and_normalize(&ty::Binder(substs));
-
-            // It's possible that the method 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 (see #23435).
-            let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
-            if !normalize_and_test_predicates(tcx, predicates.predicates) {
-                debug!("vtable_methods: predicates do not hold");
-                return None;
-            }
-
-            Some((def_id, substs))
-        })
-    }).collect()
+    Rc::new(
+        supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
+            let trait_methods = tcx.associated_items(trait_ref.def_id())
+                .filter(|item| item.kind == ty::AssociatedKind::Method);
+
+            // Now list each method's DefId and Substs (for within its trait).
+            // If the method can never be called from this object, produce None.
+            trait_methods.map(move |trait_method| {
+                debug!("vtable_methods: trait_method={:?}", trait_method);
+                let def_id = trait_method.def_id;
+
+                // Some methods cannot be called on an object; skip those.
+                if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
+                    debug!("vtable_methods: not vtable safe");
+                    return None;
+                }
+
+                // the method may have some early-bound lifetimes, add
+                // regions for those
+                let substs = Substs::for_item(tcx, def_id,
+                                              |_, _| tcx.types.re_erased,
+                                              |def, _| trait_ref.substs().type_for_def(def));
+
+                // the trait type may have higher-ranked lifetimes in it;
+                // so erase them if they appear, so that we get the type
+                // at some particular call site
+                let substs = tcx.erase_late_bound_regions_and_normalize(&ty::Binder(substs));
+
+                // It's possible that the method 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 (see #23435).
+                let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
+                if !normalize_and_test_predicates(tcx, predicates.predicates) {
+                    debug!("vtable_methods: predicates do not hold");
+                    return None;
+                }
+
+                Some((def_id, substs))
+            })
+        }).collect()
+    )
 }
 
 impl<'tcx,O> Obligation<'tcx,O> {
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 872069d381b..4b68f5addd2 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -229,7 +229,7 @@ define_maps! { <'tcx>
     [] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
     [] fn is_mir_available: IsMirAvailable(DefId) -> bool,
     [] fn vtable_methods: vtable_methods_node(ty::PolyTraitRef<'tcx>)
-                          -> Vec<Option<(DefId, &'tcx Substs<'tcx>)>>,
+                          -> Rc<Vec<Option<(DefId, &'tcx Substs<'tcx>)>>>,
 
     [] fn trans_fulfill_obligation: fulfill_obligation_dep_node(
         (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Vtable<'tcx, ()>,
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 08478700001..33a2e96ee66 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -850,7 +850,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
             // Walk all methods of the trait, including those of its supertraits
             let methods = tcx.vtable_methods(poly_trait_ref);
-            let methods = methods.into_iter().filter_map(|method| method)
+            let methods = methods.iter().cloned().filter_map(|method| method)
                 .map(|(def_id, substs)| ty::Instance::resolve(
                         tcx,
                         ty::ParamEnv::empty(traits::Reveal::All),
diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs
index 66d633cf9a1..3253a0339a8 100644
--- a/src/librustc_trans/meth.rs
+++ b/src/librustc_trans/meth.rs
@@ -86,7 +86,8 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     if let Some(trait_ref) = trait_ref {
         let trait_ref = trait_ref.with_self_ty(tcx, ty);
-        let methods = tcx.vtable_methods(trait_ref).into_iter().map(|opt_mth| {
+        let methods = tcx.vtable_methods(trait_ref);
+        let methods = methods.iter().cloned().map(|opt_mth| {
             opt_mth.map_or(nullptr, |(def_id, substs)| {
                 callee::resolve_and_get_fn(ccx, def_id, substs)
             })