@@ -4,13 +4,12 @@ use rustc_errors::struct_span_code_err;
44use  rustc_hir as  hir; 
55use  rustc_hir:: def:: { DefKind ,  Res } ; 
66use  rustc_lint_defs:: builtin:: UNUSED_ASSOCIATED_TYPE_BOUNDS ; 
7- use  rustc_middle:: span_bug; 
87use  rustc_middle:: ty:: fold:: BottomUpFolder ; 
98use  rustc_middle:: ty:: { 
109    self ,  DynKind ,  ExistentialPredicateStableCmpExt  as  _,  Ty ,  TyCtxt ,  TypeFoldable , 
1110    TypeVisitableExt ,  Upcast , 
1211} ; 
13- use  rustc_span:: { DUMMY_SP ,   ErrorGuaranteed ,  Span } ; 
12+ use  rustc_span:: { ErrorGuaranteed ,  Span } ; 
1413use  rustc_trait_selection:: error_reporting:: traits:: report_dyn_incompatibility; 
1514use  rustc_trait_selection:: traits:: { self ,  hir_ty_lowering_dyn_compatibility_violations} ; 
1615use  rustc_type_ir:: elaborate:: ClauseWithSupertraitSpan ; 
@@ -30,16 +29,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
3029        & self , 
3130        span :  Span , 
3231        hir_id :  hir:: HirId , 
33-         hir_trait_bounds :  & [ hir:: PolyTraitRef < ' tcx > ] , 
32+         hir_bounds :  & [ hir:: PolyTraitRef < ' tcx > ] , 
3433        lifetime :  & hir:: Lifetime , 
3534        representation :  DynKind , 
3635    )  -> Ty < ' tcx >  { 
3736        let  tcx = self . tcx ( ) ; 
37+         let  dummy_self = self . tcx ( ) . types . trait_object_dummy_self ; 
3838
39-         let  mut  bounds  = Bounds :: default ( ) ; 
39+         let  mut  user_written_bounds  = Bounds :: default ( ) ; 
4040        let  mut  potential_assoc_types = Vec :: new ( ) ; 
41-         let  dummy_self = self . tcx ( ) . types . trait_object_dummy_self ; 
42-         for  trait_bound in  hir_trait_bounds. iter ( ) . rev ( )  { 
41+         for  trait_bound in  hir_bounds. iter ( )  { 
4342            if  let  hir:: BoundPolarity :: Maybe ( _)  = trait_bound. modifiers . polarity  { 
4443                continue ; 
4544            } 
@@ -53,92 +52,67 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
5352                hir:: BoundConstness :: Never , 
5453                hir:: BoundPolarity :: Positive , 
5554                dummy_self, 
56-                 & mut  bounds , 
55+                 & mut  user_written_bounds , 
5756                PredicateFilter :: SelfOnly , 
5857            )  { 
5958                potential_assoc_types. extend ( cur_potential_assoc_types) ; 
6059            } 
6160        } 
6261
63-         let  mut  trait_bounds = vec ! [ ] ; 
64-         let  mut  projection_bounds = vec ! [ ] ; 
65-         for  ( pred,  span)  in  bounds. clauses ( )  { 
66-             let  bound_pred = pred. kind ( ) ; 
67-             match  bound_pred. skip_binder ( )  { 
68-                 ty:: ClauseKind :: Trait ( trait_pred)  => { 
69-                     assert_eq ! ( trait_pred. polarity,  ty:: PredicatePolarity :: Positive ) ; 
70-                     trait_bounds. push ( ( bound_pred. rebind ( trait_pred. trait_ref ) ,  span) ) ; 
71-                 } 
72-                 ty:: ClauseKind :: Projection ( proj)  => { 
73-                     projection_bounds. push ( ( bound_pred. rebind ( proj) ,  span) ) ; 
74-                 } 
75-                 ty:: ClauseKind :: TypeOutlives ( _)  => { 
76-                     // Do nothing, we deal with regions separately 
77-                 } 
78-                 ty:: ClauseKind :: RegionOutlives ( _) 
79-                 | ty:: ClauseKind :: ConstArgHasType ( ..) 
80-                 | ty:: ClauseKind :: WellFormed ( _) 
81-                 | ty:: ClauseKind :: ConstEvaluatable ( _) 
82-                 | ty:: ClauseKind :: HostEffect ( ..)  => { 
83-                     span_bug ! ( span,  "did not expect {pred} clause in object bounds" ) ; 
62+         // Check that there are no gross dyn-compatibility violations; 
63+         // most importantly, that the supertraits don't contain `Self`, 
64+         // to avoid ICEs. 
65+         for  ( clause,  span)  in  user_written_bounds. clauses ( )  { 
66+             if  let  Some ( trait_pred)  = clause. as_trait_clause ( )  { 
67+                 let  violations =
68+                     hir_ty_lowering_dyn_compatibility_violations ( tcx,  trait_pred. def_id ( ) ) ; 
69+                 if  !violations. is_empty ( )  { 
70+                     let  reported = report_dyn_incompatibility ( 
71+                         tcx, 
72+                         span, 
73+                         Some ( hir_id) , 
74+                         trait_pred. def_id ( ) , 
75+                         & violations, 
76+                     ) 
77+                     . emit ( ) ; 
78+                     return  Ty :: new_error ( tcx,  reported) ; 
8479                } 
8580            } 
8681        } 
8782
88-         // Expand trait aliases recursively and check that only one regular (non-auto) trait 
89-         // 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) ) ) ; 
92- 
93-         let  ( mut  auto_traits,  regular_traits) :  ( Vec < _ > ,  Vec < _ > )  =
94-             expanded_traits. partition ( |i| tcx. trait_is_auto ( i. trait_ref ( ) . def_id ( ) ) ) ; 
83+         let  ( trait_bounds,  mut  projection_bounds)  =
84+             traits:: expand_trait_aliases ( tcx,  user_written_bounds. clauses ( ) ) ; 
85+         let  ( regular_traits,  mut  auto_traits) :  ( Vec < _ > ,  Vec < _ > )  = trait_bounds
86+             . into_iter ( ) 
87+             . partition ( |( trait_ref,  _) | !tcx. trait_is_auto ( trait_ref. def_id ( ) ) ) ; 
9588
89+         // We  don't support empty trait objects. 
90+         if  regular_traits. is_empty ( )  && auto_traits. is_empty ( )  { 
91+             let  guar =
92+                 self . report_trait_object_with_no_traits_error ( span,  user_written_bounds. clauses ( ) ) ; 
93+             return  Ty :: new_error ( tcx,  guar) ; 
94+         } 
9695        // We don't support >1 principal 
9796        if  regular_traits. len ( )  > 1  { 
9897            let  guar = self . report_trait_object_addition_traits_error ( & regular_traits) ; 
9998            return  Ty :: new_error ( tcx,  guar) ; 
10099        } 
101-         // We  don't support empty trait objects. 
102-         if  regular_traits. is_empty ( )  && auto_traits. is_empty ( )  { 
103-             let  guar = self . report_trait_object_with_no_traits_error ( span,  & trait_bounds) ; 
104-             return  Ty :: new_error ( tcx,  guar) ; 
105-         } 
106100        // Don't create a dyn trait if we have errors in the principal. 
107-         if  let  Err ( guar)  = trait_bounds . error_reported ( )  { 
101+         if  let  Err ( guar)  = regular_traits . error_reported ( )  { 
108102            return  Ty :: new_error ( tcx,  guar) ; 
109103        } 
110104
111-         // Check that there are no gross dyn-compatibility violations; 
112-         // most importantly, that the supertraits don't contain `Self`, 
113-         // to avoid ICEs. 
114-         for  item in  & regular_traits { 
115-             let  violations =
116-                 hir_ty_lowering_dyn_compatibility_violations ( tcx,  item. trait_ref ( ) . def_id ( ) ) ; 
117-             if  !violations. is_empty ( )  { 
118-                 let  reported = report_dyn_incompatibility ( 
119-                     tcx, 
120-                     span, 
121-                     Some ( hir_id) , 
122-                     item. trait_ref ( ) . def_id ( ) , 
123-                     & violations, 
124-                 ) 
125-                 . emit ( ) ; 
126-                 return  Ty :: new_error ( tcx,  reported) ; 
127-             } 
128-         } 
105+         let  principal_trait = regular_traits. into_iter ( ) . next ( ) ; 
129106
130107        let  mut  needed_associated_types = FxIndexSet :: default ( ) ; 
131- 
132-         let  principal_span = regular_traits. first ( ) . map_or ( DUMMY_SP ,  |info| info. bottom ( ) . 1 ) ; 
133-         let  regular_traits_refs_spans = trait_bounds
134-             . into_iter ( ) 
135-             . filter ( |( trait_ref,  _) | !tcx. trait_is_auto ( trait_ref. def_id ( ) ) ) ; 
136- 
137-         for  ( base_trait_ref,  original_span)  in  regular_traits_refs_spans { 
138-             let  base_pred:  ty:: Predicate < ' tcx >  = base_trait_ref. upcast ( tcx) ; 
108+         if  let  Some ( ( principal_trait,  spans) )  = & principal_trait { 
109+             let  pred:  ty:: Predicate < ' tcx >  = ( * principal_trait) . upcast ( tcx) ; 
139110            for  ClauseWithSupertraitSpan  {  pred,  supertrait_span }  in 
140-                 traits:: elaborate ( tcx,  [ ClauseWithSupertraitSpan :: new ( base_pred,  original_span) ] ) 
141-                     . filter_only_self ( ) 
111+                 traits:: elaborate ( tcx,  [ ClauseWithSupertraitSpan :: new ( 
112+                     pred, 
113+                     * spans. last ( ) . unwrap ( ) , 
114+                 ) ] ) 
115+                 . filter_only_self ( ) 
142116            { 
143117                debug ! ( "observing object predicate `{pred:?}`" ) ; 
144118
@@ -186,12 +160,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
186160                        // the discussion in #56288 for alternatives. 
187161                        if  !references_self { 
188162                            // Include projections defined on supertraits. 
189-                             projection_bounds. push ( ( pred,  original_span ) ) ; 
163+                             projection_bounds. push ( ( pred,  supertrait_span ) ) ; 
190164                        } 
191165
192166                        self . check_elaborated_projection_mentions_input_lifetimes ( 
193167                            pred, 
194-                             original_span , 
168+                             * spans . first ( ) . unwrap ( ) , 
195169                            supertrait_span, 
196170                        ) ; 
197171                    } 
@@ -204,24 +178,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
204178        // So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated 
205179        // types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a 
206180        // corresponding `Projection` clause 
207-         for  ( projection_bound,  span)  in  & projection_bounds { 
181+         for  & ( projection_bound,  span)  in  & projection_bounds { 
208182            let  def_id = projection_bound. projection_def_id ( ) ; 
209183            needed_associated_types. swap_remove ( & def_id) ; 
210184            if  tcx. generics_require_sized_self ( def_id)  { 
211185                tcx. emit_node_span_lint ( 
212186                    UNUSED_ASSOCIATED_TYPE_BOUNDS , 
213187                    hir_id, 
214-                     * span, 
215-                     crate :: errors:: UnusedAssociatedTypeBounds  {  span :   * span  } , 
188+                     span, 
189+                     crate :: errors:: UnusedAssociatedTypeBounds  {  span } , 
216190                ) ; 
217191            } 
218192        } 
219193
220194        if  let  Err ( guar)  = self . check_for_required_assoc_tys ( 
221-             principal_span , 
195+             principal_trait . as_ref ( ) . map_or ( smallvec ! [ ] ,  | ( _ ,  spans ) | spans . clone ( ) ) , 
222196            needed_associated_types, 
223197            potential_assoc_types, 
224-             hir_trait_bounds , 
198+             hir_bounds , 
225199        )  { 
226200            return  Ty :: new_error ( tcx,  guar) ; 
227201        } 
@@ -231,15 +205,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
231205        // We remove duplicates by inserting into a `FxHashSet` to avoid re-ordering 
232206        // the bounds 
233207        let  mut  duplicates = FxHashSet :: default ( ) ; 
234-         auto_traits. retain ( |i| duplicates. insert ( i. trait_ref ( ) . def_id ( ) ) ) ; 
235-         debug ! ( ?regular_traits) ; 
208+         auto_traits. retain ( |( trait_pred,  _) | duplicates. insert ( trait_pred. def_id ( ) ) ) ; 
209+ 
210+         debug ! ( ?principal_trait) ; 
236211        debug ! ( ?auto_traits) ; 
237212
238213        // Erase the `dummy_self` (`trait_object_dummy_self`) used above. 
239-         let  existential_trait_refs = regular_traits. iter ( ) . map ( |i| { 
240-             i. trait_ref ( ) . map_bound ( |trait_ref :  ty:: TraitRef < ' tcx > | { 
214+         let  principal_trait_ref = principal_trait. map ( |( trait_pred,  spans) | { 
215+             trait_pred. map_bound ( |trait_pred| { 
216+                 let  trait_ref = trait_pred. trait_ref ; 
217+                 assert_eq ! ( trait_pred. polarity,  ty:: PredicatePolarity :: Positive ) ; 
241218                assert_eq ! ( trait_ref. self_ty( ) ,  dummy_self) ; 
242219
220+                 let  span = * spans. first ( ) . unwrap ( ) ; 
221+ 
243222                // Verify that `dummy_self` did not leak inside default type parameters. This 
244223                // could not be done at path creation, since we need to see through trait aliases. 
245224                let  mut  missing_type_params = vec ! [ ] ; 
@@ -249,7 +228,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
249228                    . args 
250229                    . iter ( ) 
251230                    . enumerate ( ) 
252-                     . skip ( 1 )  // Remove `Self` for `ExistentialPredicate`. 
231+                     // Skip `Self` 
232+                     . skip ( 1 ) 
253233                    . map ( |( index,  arg) | { 
254234                        if  arg == dummy_self. into ( )  { 
255235                            let  param = & generics. own_params [ index] ; 
@@ -268,8 +248,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
268248                    } ) 
269249                    . collect ( ) ; 
270250
271-                 let  span = i. bottom ( ) . 1 ; 
272-                 let  empty_generic_args = hir_trait_bounds. iter ( ) . any ( |hir_bound| { 
251+                 let  empty_generic_args = hir_bounds. iter ( ) . any ( |hir_bound| { 
273252                    hir_bound. trait_ref . path . res  == Res :: Def ( DefKind :: Trait ,  trait_ref. def_id ) 
274253                        && hir_bound. span . contains ( span) 
275254                } ) ; 
@@ -280,26 +259,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
280259                    empty_generic_args, 
281260                ) ; 
282261
283-                 if  references_self { 
284-                     let  def_id = i. bottom ( ) . 0 . def_id ( ) ; 
285-                     struct_span_code_err ! ( 
286-                         self . dcx( ) , 
287-                         i. bottom( ) . 1 , 
288-                         E0038 , 
289-                         "the {} `{}` cannot be made into an object" , 
290-                         tcx. def_descr( def_id) , 
291-                         tcx. item_name( def_id) , 
292-                     ) 
293-                     . with_note ( 
294-                         rustc_middle:: traits:: DynCompatibilityViolation :: SupertraitSelf ( 
295-                             smallvec ! [ ] , 
296-                         ) 
297-                         . error_msg ( ) , 
298-                     ) 
299-                     . emit ( ) ; 
300-                 } 
301- 
302-                 ty:: ExistentialTraitRef :: new ( tcx,  trait_ref. def_id ,  args) 
262+                 ty:: ExistentialPredicate :: Trait ( ty:: ExistentialTraitRef :: new ( 
263+                     tcx, 
264+                     trait_ref. def_id , 
265+                     args, 
266+                 ) ) 
303267            } ) 
304268        } ) ; 
305269
@@ -322,21 +286,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
322286                    b. projection_term  = replace_dummy_self_with_error ( tcx,  b. projection_term ,  guar) ; 
323287                } 
324288
325-                 ty:: ExistentialProjection :: erase_self_ty ( tcx,  b) 
289+                 ty:: ExistentialPredicate :: Projection ( ty:: ExistentialProjection :: erase_self_ty ( 
290+                     tcx,  b, 
291+                 ) ) 
326292            } ) 
327293        } ) ; 
328294
329-         let  regular_trait_predicates = existential_trait_refs
330-             . map ( |trait_ref| trait_ref. map_bound ( ty:: ExistentialPredicate :: Trait ) ) ; 
331-         let  auto_trait_predicates = auto_traits. into_iter ( ) . map ( |trait_ref| { 
332-             ty:: Binder :: dummy ( ty:: ExistentialPredicate :: AutoTrait ( trait_ref. trait_ref ( ) . def_id ( ) ) ) 
295+         let  auto_trait_predicates = auto_traits. into_iter ( ) . map ( |( trait_pred,  _) | { 
296+             assert_eq ! ( trait_pred. polarity( ) ,  ty:: PredicatePolarity :: Positive ) ; 
297+             assert_eq ! ( trait_pred. self_ty( ) . skip_binder( ) ,  dummy_self) ; 
298+ 
299+             ty:: Binder :: dummy ( ty:: ExistentialPredicate :: AutoTrait ( trait_pred. def_id ( ) ) ) 
333300        } ) ; 
301+ 
334302        // N.b. principal, projections, auto traits 
335303        // FIXME: This is actually wrong with multiple principals in regards to symbol mangling 
336-         let  mut  v = regular_trait_predicates
337-             . chain ( 
338-                 existential_projections. map ( |x| x. map_bound ( ty:: ExistentialPredicate :: Projection ) ) , 
339-             ) 
304+         let  mut  v = principal_trait_ref
305+             . into_iter ( ) 
306+             . chain ( existential_projections) 
340307            . chain ( auto_trait_predicates) 
341308            . collect :: < SmallVec < [ _ ;  8 ] > > ( ) ; 
342309        v. sort_by ( |a,  b| a. skip_binder ( ) . stable_cmp ( tcx,  & b. skip_binder ( ) ) ) ; 
0 commit comments