diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 23 |
2 files changed, 23 insertions, 6 deletions
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index aba534ac19f..b516810205f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -436,12 +436,6 @@ rustc_queries! { desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } } - /// Maps from the `DefId` of a trait to the list of - /// all the ancestors super traits. - query super_traits_of(key: DefId) -> Lrc<FxHashSet<DefId>> { - desc { |tcx| "computing the super traits of `{}`", tcx.def_path_str(key) } - } - /// The `Option<Ident>` is the name of an associated type. If it is `None`, then this query /// returns the full set of predicates. If `Some<Ident>`, then the query returns only the /// subset of super-predicates that reference traits that define the given associated type. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b2a8b33e4ff..6a60d65661a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2095,6 +2095,29 @@ 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>> { + 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; + } + + 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()); + } + } + } + + Lrc::new(set) + } + /// Given a closure signature, returns an equivalent fn signature. Detuples /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then /// you would get a `fn(u32, i32)`. |
