1- use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
1+ use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
22use rustc_errors:: codes:: * ;
33use rustc_errors:: struct_span_code_err;
44use rustc_hir as hir;
@@ -61,7 +61,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
6161 }
6262
6363 let mut trait_bounds = vec ! [ ] ;
64- let mut projection_bounds = vec ! [ ] ;
64+ let mut projection_bounds = FxIndexMap :: default ( ) ;
6565 for ( pred, span) in bounds. clauses ( ) {
6666 let bound_pred = pred. kind ( ) ;
6767 match bound_pred. skip_binder ( ) {
@@ -70,7 +70,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
7070 trait_bounds. push ( ( bound_pred. rebind ( trait_pred. trait_ref ) , span) ) ;
7171 }
7272 ty:: ClauseKind :: Projection ( proj) => {
73- projection_bounds. push ( ( bound_pred. rebind ( proj) , span) ) ;
73+ let anon = tcx. anonymize_bound_vars ( bound_pred. rebind ( proj) ) ;
74+ projection_bounds. insert ( anon, ( bound_pred. rebind ( proj) , span) ) ;
7475 }
7576 ty:: ClauseKind :: TypeOutlives ( _) => {
7677 // Do nothing, we deal with regions separately
@@ -87,8 +88,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
8788
8889 // Expand trait aliases recursively and check that only one regular (non-auto) trait
8990 // is used and no 'maybe' bounds are used.
90- let expanded_traits =
91- traits:: expand_trait_aliases ( tcx, trait_bounds. iter ( ) . map ( |& ( a, b) | ( a, b) ) ) ;
91+ let mut trait_alias_projection_bounds = FxIndexSet :: default ( ) ;
92+ let expanded_traits = traits:: expand_trait_aliases (
93+ tcx,
94+ & mut trait_alias_projection_bounds,
95+ trait_bounds. iter ( ) . map ( |& ( a, b) | ( a, b) ) ,
96+ ) ;
9297
9398 let ( mut auto_traits, regular_traits) : ( Vec < _ > , Vec < _ > ) =
9499 expanded_traits. partition ( |i| tcx. trait_is_auto ( i. trait_ref ( ) . def_id ( ) ) ) ;
@@ -162,6 +167,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
162167 }
163168 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( pred) ) => {
164169 let pred = bound_predicate. rebind ( pred) ;
170+
171+ let pred_key = tcx. anonymize_bound_vars ( pred) ;
172+ if !trait_alias_projection_bounds. contains ( & pred_key) {
173+ projection_bounds. shift_remove ( & pred_key) ;
174+ }
175+
165176 // A `Self` within the original bound will be instantiated with a
166177 // `trait_object_dummy_self`, so check for that.
167178 let references_self = match pred. skip_binder ( ) . term . unpack ( ) {
@@ -188,8 +199,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
188199 // `dyn MyTrait<MyOutput = X, Output = X>`, which is uglier but works. See
189200 // the discussion in #56288 for alternatives.
190201 if !references_self {
191- // Include projections defined on supertraits.
192- implied_projection_bounds. push ( pred) ;
202+ if trait_alias_projection_bounds. contains ( & pred_key) {
203+ // Include projections defined on supertraits.
204+ projection_bounds. insert ( pred_key, ( pred, supertrait_span) ) ;
205+ } else {
206+ // Include projections defined on supertraits.
207+ implied_projection_bounds. push ( pred) ;
208+ }
193209 }
194210
195211 self . check_elaborated_projection_mentions_input_lifetimes (
@@ -207,7 +223,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
207223 // So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
208224 // types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
209225 // corresponding `Projection` clause
210- for ( projection_bound, span) in & projection_bounds {
226+ for ( projection_bound, span) in projection_bounds. values ( ) {
211227 let def_id = projection_bound. projection_def_id ( ) ;
212228 let trait_ref = tcx. anonymize_bound_vars (
213229 projection_bound. map_bound ( |p| p. projection_term . trait_ref ( tcx) ) ,
@@ -314,7 +330,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
314330 } )
315331 } ) ;
316332
317- let existential_projections = projection_bounds. iter ( ) . map ( |( bound, _) | {
333+ let existential_projections = projection_bounds. values ( ) . map ( |( bound, _) | {
318334 bound. map_bound ( |mut b| {
319335 assert_eq ! ( b. projection_term. self_ty( ) , dummy_self) ;
320336
0 commit comments