@@ -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