From e5412da723d8d8ff68461ee6b43d5725c3d37968 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 15:51:53 -0400 Subject: [PATCH 1/2] Supertrait elaboration doesn't need to use Predicates --- compiler/rustc_infer/src/traits/util.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 24cf9f03fcdb3..def341beceb9d 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -405,14 +405,14 @@ impl<'tcx, O: Elaboratable<'tcx>> Iterator for Elaborator<'tcx, O> { pub fn supertraits<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, -) -> FilterToTraits>> { +) -> FilterToTraits>> { elaborate(tcx, [trait_ref.upcast(tcx)]).filter_only_self().filter_to_traits() } pub fn transitive_bounds<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, -) -> FilterToTraits>> { +) -> FilterToTraits>> { elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) .filter_only_self() .filter_to_traits() @@ -427,7 +427,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, assoc_name: Ident, -) -> FilterToTraits>> { +) -> FilterToTraits>> { elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) .filter_only_self_that_defines(assoc_name) .filter_to_traits() @@ -437,7 +437,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( // Other /////////////////////////////////////////////////////////////////////////// -impl<'tcx> Elaborator<'tcx, ty::Predicate<'tcx>> { +impl<'tcx> Elaborator<'tcx, ty::Clause<'tcx>> { fn filter_to_traits(self) -> FilterToTraits { FilterToTraits { base_iterator: self } } @@ -449,7 +449,7 @@ pub struct FilterToTraits { base_iterator: I, } -impl<'tcx, I: Iterator>> Iterator for FilterToTraits { +impl<'tcx, I: Iterator>> Iterator for FilterToTraits { type Item = ty::PolyTraitRef<'tcx>; fn next(&mut self) -> Option> { From 99429a6a18cbc671c313ac8df17aa163729bc284 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 16:02:35 -0400 Subject: [PATCH 2/2] Split out transitive_bounds_that_define_assoc_item --- compiler/rustc_infer/src/traits/util.rs | 39 ++++++++++++++++--------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index def341beceb9d..18d36c3a5df34 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -3,6 +3,7 @@ use smallvec::smallvec; use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; use rustc_data_structures::fx::FxHashSet; +use rustc_middle::ty::ToPolyTraitRef; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -82,7 +83,6 @@ pub struct Elaborator<'tcx, O> { enum Filter { All, OnlySelf, - OnlySelfThatDefines(Ident), } /// Describes how to elaborate an obligation into a sub-obligation. @@ -252,12 +252,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { self } - /// Filter to only the supertraits of trait predicates that define the assoc_ty. - pub fn filter_only_self_that_defines(mut self, assoc_ty: Ident) -> Self { - self.mode = Filter::OnlySelfThatDefines(assoc_ty); - self - } - fn elaborate(&mut self, elaboratable: &O) { let tcx = self.visited.tcx; @@ -277,9 +271,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { let predicates = match self.mode { Filter::All => tcx.explicit_implied_predicates_of(data.def_id()), Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()), - Filter::OnlySelfThatDefines(ident) => { - tcx.explicit_supertraits_containing_assoc_item((data.def_id(), ident)) - } }; let obligations = @@ -427,10 +418,30 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, assoc_name: Ident, -) -> FilterToTraits>> { - elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) - .filter_only_self_that_defines(assoc_name) - .filter_to_traits() +) -> impl Iterator> { + let mut seen = FxHashSet::default(); + let mut stack: Vec<_> = trait_refs.collect(); + + std::iter::from_fn(move || { + while let Some(trait_ref) = stack.pop() { + if !seen.insert(tcx.anonymize_bound_vars(trait_ref)) { + continue; + } + + stack.extend( + tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name)) + .instantiate_own_identity() + .map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref)) + .filter_map(|clause| clause.as_trait_clause()) + // FIXME: Negative supertraits are elaborated here lol + .map(|trait_pred| trait_pred.to_poly_trait_ref()), + ); + + return Some(trait_ref); + } + + None + }) } ///////////////////////////////////////////////////////////////////////////