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; 
@@ -58,9 +58,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
5858            } 
5959        } 
6060
61-         let  ( trait_bounds ,   mut  projection_bounds )  =
61+         let  ( elaborated_trait_bounds ,  elaborated_projection_bounds )  =
6262            traits:: expand_trait_aliases ( tcx,  user_written_bounds. iter ( ) . copied ( ) ) ; 
63-         let  ( regular_traits,  mut  auto_traits) :  ( Vec < _ > ,  Vec < _ > )  = trait_bounds 
63+         let  ( regular_traits,  mut  auto_traits) :  ( Vec < _ > ,  Vec < _ > )  = elaborated_trait_bounds 
6464            . into_iter ( ) 
6565            . partition ( |( trait_ref,  _) | !tcx. trait_is_auto ( trait_ref. def_id ( ) ) ) ; 
6666
@@ -103,37 +103,89 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
103103            } 
104104        } 
105105
106+         // Map the projection bounds onto a key that makes it easy to remove redundant 
107+         // bounds that are constrained by supertraits of the principal def id. 
108+         // 
109+         // Also make sure we detect conflicting bounds from expanding a trait alias and 
110+         // also specifying it manually, like: 
111+         // ``` 
112+         // type Alias = Trait<Assoc = i32>; 
113+         // let _: &dyn Alias<Assoc = u32> = /* ... */; 
114+         // ``` 
115+         let  mut  projection_bounds = FxIndexMap :: default ( ) ; 
116+         for  ( proj,  proj_span)  in  elaborated_projection_bounds { 
117+             let  key = ( 
118+                 proj. skip_binder ( ) . projection_term . def_id , 
119+                 tcx. anonymize_bound_vars ( 
120+                     proj. map_bound ( |proj| proj. projection_term . trait_ref ( tcx) ) , 
121+                 ) , 
122+             ) ; 
123+             if  let  Some ( ( old_proj,  old_proj_span) )  =
124+                 projection_bounds. insert ( key,  ( proj,  proj_span) ) 
125+                 && tcx. anonymize_bound_vars ( proj)  != tcx. anonymize_bound_vars ( old_proj) 
126+             { 
127+                 let  item = tcx. item_name ( proj. item_def_id ( ) ) ; 
128+                 self . dcx ( ) 
129+                     . struct_span_err ( 
130+                         span, 
131+                         format ! ( 
132+                             "conflicting associated type bounds for `{item}` when \  
133+ 
134+                         ) , 
135+                     ) 
136+                     . with_span_label ( 
137+                         old_proj_span, 
138+                         format ! ( "`{item}` is specified to be `{}` here" ,  old_proj. term( ) ) , 
139+                     ) 
140+                     . with_span_label ( 
141+                         proj_span, 
142+                         format ! ( "`{item}` is specified to be `{}` here" ,  proj. term( ) ) , 
143+                     ) 
144+                     . emit ( ) ; 
145+             } 
146+         } 
147+ 
106148        let  principal_trait = regular_traits. into_iter ( ) . next ( ) ; 
107149
108-         let  mut  needed_associated_types = FxIndexSet :: default ( ) ; 
109-         if  let  Some ( ( principal_trait,  spans) )  = & principal_trait { 
110-             let  pred:  ty:: Predicate < ' tcx >  = ( * principal_trait) . upcast ( tcx) ; 
111-             for  ClauseWithSupertraitSpan  {  pred,  supertrait_span }  in  traits:: elaborate ( 
150+         let  mut  needed_associated_types = vec ! [ ] ; 
151+         if  let  Some ( ( principal_trait,  ref  spans) )  = principal_trait { 
152+             let  principal_trait = principal_trait. map_bound ( |trait_pred| { 
153+                 assert_eq ! ( trait_pred. polarity,  ty:: PredicatePolarity :: Positive ) ; 
154+                 trait_pred. trait_ref 
155+             } ) ; 
156+ 
157+             for  ClauseWithSupertraitSpan  {  clause,  supertrait_span }  in  traits:: elaborate ( 
112158                tcx, 
113-                 [ ClauseWithSupertraitSpan :: new ( pred,  * spans. last ( ) . unwrap ( ) ) ] , 
159+                 [ ClauseWithSupertraitSpan :: new ( 
160+                     ty:: TraitRef :: identity ( tcx,  principal_trait. def_id ( ) ) . upcast ( tcx) , 
161+                     * spans. last ( ) . unwrap ( ) , 
162+                 ) ] , 
114163            ) 
115164            . filter_only_self ( ) 
116165            { 
117-                 debug ! ( "observing object predicate `{pred:?}`" ) ; 
166+                 let  clause = clause. instantiate_supertrait ( tcx,  principal_trait) ; 
167+                 debug ! ( "observing object predicate `{clause:?}`" ) ; 
118168
119-                 let  bound_predicate = pred . kind ( ) ; 
169+                 let  bound_predicate = clause . kind ( ) ; 
120170                match  bound_predicate. skip_binder ( )  { 
121-                     ty:: PredicateKind :: Clause ( ty :: ClauseKind :: Trait ( pred) )  => { 
171+                     ty:: ClauseKind :: Trait ( pred)  => { 
122172                        // FIXME(negative_bounds): Handle this correctly... 
123173                        let  trait_ref =
124174                            tcx. anonymize_bound_vars ( bound_predicate. rebind ( pred. trait_ref ) ) ; 
125175                        needed_associated_types. extend ( 
126-                             tcx. associated_items ( trait_ref. def_id ( ) ) 
176+                             tcx. associated_items ( pred . trait_ref . def_id ) 
127177                                . in_definition_order ( ) 
178+                                 // We only care about associated types. 
128179                                . filter ( |item| item. kind  == ty:: AssocKind :: Type ) 
180+                                 // No RPITITs -- even with `async_fn_in_dyn_trait`, they are implicit. 
129181                                . filter ( |item| !item. is_impl_trait_in_trait ( ) ) 
130182                                // If the associated type has a `where Self: Sized` bound, 
131183                                // we do not need to constrain the associated type. 
132184                                . filter ( |item| !tcx. generics_require_sized_self ( item. def_id ) ) 
133185                                . map ( |item| ( item. def_id ,  trait_ref) ) , 
134186                        ) ; 
135187                    } 
136-                     ty:: PredicateKind :: Clause ( ty :: ClauseKind :: Projection ( pred) )  => { 
188+                     ty:: ClauseKind :: Projection ( pred)  => { 
137189                        let  pred = bound_predicate. rebind ( pred) ; 
138190                        // A `Self` within the original bound will be instantiated with a 
139191                        // `trait_object_dummy_self`, so check for that. 
@@ -161,8 +213,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
161213                        // `dyn MyTrait<MyOutput = X, Output = X>`, which is uglier but works. See 
162214                        // the discussion in #56288 for alternatives. 
163215                        if  !references_self { 
164-                             // Include projections defined on supertraits. 
165-                             projection_bounds. push ( ( pred,  supertrait_span) ) ; 
216+                             let  key = ( 
217+                                 pred. skip_binder ( ) . projection_term . def_id , 
218+                                 tcx. anonymize_bound_vars ( 
219+                                     pred. map_bound ( |proj| proj. projection_term . trait_ref ( tcx) ) , 
220+                                 ) , 
221+                             ) ; 
222+                             if  !projection_bounds. contains_key ( & key)  { 
223+                                 projection_bounds. insert ( key,  ( pred,  supertrait_span) ) ; 
224+                             } 
166225                        } 
167226
168227                        self . check_elaborated_projection_mentions_input_lifetimes ( 
@@ -182,12 +241,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
182241        // types that we expect to be provided by the user, so the following loop 
183242        // removes all the associated types that have a corresponding `Projection` 
184243        // clause, either from expanding trait aliases or written by the user. 
185-         for  & ( projection_bound,  span)  in  & projection_bounds { 
244+         for  & ( projection_bound,  span)  in  projection_bounds. values ( )  { 
186245            let  def_id = projection_bound. item_def_id ( ) ; 
187-             let  trait_ref = tcx. anonymize_bound_vars ( 
188-                 projection_bound. map_bound ( |p| p. projection_term . trait_ref ( tcx) ) , 
189-             ) ; 
190-             needed_associated_types. swap_remove ( & ( def_id,  trait_ref) ) ; 
191246            if  tcx. generics_require_sized_self ( def_id)  { 
192247                tcx. emit_node_span_lint ( 
193248                    UNUSED_ASSOCIATED_TYPE_BOUNDS , 
@@ -198,9 +253,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
198253            } 
199254        } 
200255
256+         let  mut  missing_assoc_types = FxIndexSet :: default ( ) ; 
257+         let  projection_bounds:  Vec < _ >  = needed_associated_types
258+             . into_iter ( ) 
259+             . filter_map ( |key| { 
260+                 if  let  Some ( assoc)  = projection_bounds. get ( & key)  { 
261+                     Some ( * assoc) 
262+                 }  else  { 
263+                     missing_assoc_types. insert ( key) ; 
264+                     None 
265+                 } 
266+             } ) 
267+             . collect ( ) ; 
268+ 
201269        if  let  Err ( guar)  = self . check_for_required_assoc_tys ( 
202270            principal_trait. as_ref ( ) . map_or ( smallvec ! [ ] ,  |( _,  spans) | spans. clone ( ) ) , 
203-             needed_associated_types , 
271+             missing_assoc_types , 
204272            potential_assoc_types, 
205273            hir_bounds, 
206274        )  { 
@@ -266,7 +334,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
266334            } ) 
267335        } ) ; 
268336
269-         let  existential_projections = projection_bounds. iter ( ) . map ( |( bound,  _) | { 
337+         let  existential_projections = projection_bounds. into_iter ( ) . map ( |( bound,  _) | { 
270338            bound. map_bound ( |mut  b| { 
271339                assert_eq ! ( b. projection_term. self_ty( ) ,  dummy_self) ; 
272340
@@ -291,12 +359,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
291359            } ) 
292360        } ) ; 
293361
294-         let  auto_trait_predicates = auto_traits. into_iter ( ) . map ( |( trait_pred,  _) | { 
295-             assert_eq ! ( trait_pred. polarity( ) ,  ty:: PredicatePolarity :: Positive ) ; 
296-             assert_eq ! ( trait_pred. self_ty( ) . skip_binder( ) ,  dummy_self) ; 
362+         let  mut  auto_trait_predicates:  Vec < _ >  = auto_traits
363+             . into_iter ( ) 
364+             . map ( |( trait_pred,  _) | { 
365+                 assert_eq ! ( trait_pred. polarity( ) ,  ty:: PredicatePolarity :: Positive ) ; 
366+                 assert_eq ! ( trait_pred. self_ty( ) . skip_binder( ) ,  dummy_self) ; 
297367
298-             ty:: Binder :: dummy ( ty:: ExistentialPredicate :: AutoTrait ( trait_pred. def_id ( ) ) ) 
299-         } ) ; 
368+                 ty:: Binder :: dummy ( ty:: ExistentialPredicate :: AutoTrait ( trait_pred. def_id ( ) ) ) 
369+             } ) 
370+             . collect ( ) ; 
371+         auto_trait_predicates. dedup ( ) ; 
300372
301373        // N.b. principal, projections, auto traits 
302374        // FIXME: This is actually wrong with multiple principals in regards to symbol mangling 
@@ -306,7 +378,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
306378            . chain ( auto_trait_predicates) 
307379            . collect :: < SmallVec < [ _ ;  8 ] > > ( ) ; 
308380        v. sort_by ( |a,  b| a. skip_binder ( ) . stable_cmp ( tcx,  & b. skip_binder ( ) ) ) ; 
309-         v. dedup ( ) ; 
310381        let  existential_predicates = tcx. mk_poly_existential_predicates ( & v) ; 
311382
312383        // Use explicitly-specified region bound, unless the bound is missing. 
0 commit comments