about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2020-11-25 13:24:05 -0300
committerSantiago Pastorino <spastorino@gmail.com>2020-11-27 11:55:17 -0300
commit504d27cb0c705a51f437e0e02a19f2e7512fa8ab (patch)
tree9ebddfb27364b2ebcc7259d33e7c3f3fe4dbab03
parent35bf466a2764abde4c78389c5fc91ca9c4e9ab28 (diff)
downloadrust-504d27cb0c705a51f437e0e02a19f2e7512fa8ab.tar.gz
rust-504d27cb0c705a51f437e0e02a19f2e7512fa8ab.zip
Make super_traits_of return an iterator
-rw-r--r--compiler/rustc_middle/src/ty/context.rs27
1 files changed, 15 insertions, 12 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 6a60d65661a..744aa39b96c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2088,9 +2088,9 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
     /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
     pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
-        self.super_traits_of(trait_def_id).iter().any(|trait_did| {
-            self.associated_items(*trait_did)
-                .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, *trait_did)
+        self.super_traits_of(trait_def_id).any(|trait_did| {
+            self.associated_items(trait_did)
+                .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
                 .is_some()
         })
     }
@@ -2098,24 +2098,27 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Computes the def-ids of the transitive super-traits of `trait_def_id`. This (intentionally)
     /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
     /// to identify which traits may define a given associated type to help avoid cycle errors.
-    /// Returns `Lrc<FxHashSet<DefId>>` so that cloning is cheaper.
-    fn super_traits_of(self, trait_def_id: DefId) -> Lrc<FxHashSet<DefId>> {
+    /// Returns a `DefId` iterator.
+    fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
         let mut set = FxHashSet::default();
         let mut stack = vec![trait_def_id];
-        while let Some(trait_did) = stack.pop() {
-            if !set.insert(trait_did) {
-                continue;
-            }
 
+        set.insert(trait_def_id);
+
+        iter::from_fn(move || -> Option<DefId> {
+            let trait_did = stack.pop()?;
             let generic_predicates = self.super_predicates_of(trait_did);
+
             for (predicate, _) in generic_predicates.predicates {
                 if let ty::PredicateAtom::Trait(data, _) = predicate.skip_binders() {
-                    stack.push(data.def_id());
+                    if set.insert(data.def_id()) {
+                        stack.push(data.def_id());
+                    }
                 }
             }
-        }
 
-        Lrc::new(set)
+            Some(trait_did)
+        })
     }
 
     /// Given a closure signature, returns an equivalent fn signature. Detuples