1- use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
1+ use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
22use rustc_errors:: codes:: * ;
33use rustc_errors:: struct_span_code_err;
44use rustc_hir as hir;
55use rustc_hir:: def:: { DefKind , Res } ;
6- use rustc_hir:: def_id:: DefId ;
76use rustc_lint_defs:: builtin:: UNUSED_ASSOCIATED_TYPE_BOUNDS ;
87use rustc_middle:: span_bug;
98use rustc_middle:: ty:: fold:: BottomUpFolder ;
109use rustc_middle:: ty:: {
11- self , DynKind , ExistentialPredicateStableCmpExt as _, Ty , TyCtxt , TypeFoldable , Upcast ,
10+ self , DynKind , ExistentialPredicateStableCmpExt as _, Ty , TyCtxt , TypeFoldable ,
11+ TypeVisitableExt , Upcast ,
1212} ;
13- use rustc_span:: { ErrorGuaranteed , Span } ;
13+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span } ;
1414use rustc_trait_selection:: error_reporting:: traits:: report_dyn_incompatibility;
1515use rustc_trait_selection:: traits:: { self , hir_ty_lowering_dyn_compatibility_violations} ;
1616use rustc_type_ir:: elaborate:: ClauseWithSupertraitSpan ;
@@ -92,11 +92,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
9292
9393 let ( mut auto_traits, regular_traits) : ( Vec < _ > , Vec < _ > ) =
9494 expanded_traits. partition ( |i| tcx. trait_is_auto ( i. trait_ref ( ) . def_id ( ) ) ) ;
95+
96+ // We don't support >1 principal
9597 if regular_traits. len ( ) > 1 {
96- let _ = self . report_trait_object_addition_traits_error ( & regular_traits) ;
97- } else if regular_traits. is_empty ( ) && auto_traits. is_empty ( ) {
98- let reported = self . report_trait_object_with_no_traits_error ( span, & trait_bounds) ;
99- return Ty :: new_error ( tcx, reported) ;
98+ let guar = self . report_trait_object_addition_traits_error ( & regular_traits) ;
99+ return Ty :: new_error ( tcx, guar) ;
100+ }
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+ }
106+ // Don't create a dyn trait if we have errors in the principal.
107+ if let Err ( guar) = trait_bounds. error_reported ( ) {
108+ return Ty :: new_error ( tcx, guar) ;
100109 }
101110
102111 // Check that there are no gross dyn-compatibility violations;
@@ -118,15 +127,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
118127 }
119128 }
120129
121- let mut associated_types : FxIndexMap < Span , FxIndexSet < DefId > > = FxIndexMap :: default ( ) ;
130+ let mut needed_associated_types = FxIndexSet :: default ( ) ;
122131
132+ let principal_span = regular_traits. first ( ) . map_or ( DUMMY_SP , |info| info. bottom ( ) . 1 ) ;
123133 let regular_traits_refs_spans = trait_bounds
124134 . into_iter ( )
125135 . filter ( |( trait_ref, _) | !tcx. trait_is_auto ( trait_ref. def_id ( ) ) ) ;
126136
127137 for ( base_trait_ref, original_span) in regular_traits_refs_spans {
128138 let base_pred: ty:: Predicate < ' tcx > = base_trait_ref. upcast ( tcx) ;
129- for ClauseWithSupertraitSpan { pred, original_span , supertrait_span } in
139+ for ClauseWithSupertraitSpan { pred, supertrait_span } in
130140 traits:: elaborate ( tcx, [ ClauseWithSupertraitSpan :: new ( base_pred, original_span) ] )
131141 . filter_only_self ( )
132142 {
@@ -135,13 +145,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
135145 let bound_predicate = pred. kind ( ) ;
136146 match bound_predicate. skip_binder ( ) {
137147 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
138- let pred = bound_predicate. rebind ( pred) ;
139- associated_types. entry ( original_span) . or_default ( ) . extend (
140- tcx. associated_items ( pred. def_id ( ) )
148+ // FIXME(negative_bounds): Handle this correctly...
149+ let trait_ref =
150+ tcx. anonymize_bound_vars ( bound_predicate. rebind ( pred. trait_ref ) ) ;
151+ needed_associated_types. extend (
152+ tcx. associated_items ( trait_ref. def_id ( ) )
141153 . in_definition_order ( )
142154 . filter ( |item| item. kind == ty:: AssocKind :: Type )
143155 . filter ( |item| !item. is_impl_trait_in_trait ( ) )
144- . map ( |item| item. def_id ) ,
156+ // If the associated type has a `where Self: Sized` bound,
157+ // we do not need to constrain the associated type.
158+ . filter ( |item| !tcx. generics_require_sized_self ( item. def_id ) )
159+ . map ( |item| ( item. def_id , trait_ref) ) ,
145160 ) ;
146161 }
147162 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( pred) ) => {
@@ -191,27 +206,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
191206 // So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
192207 // types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
193208 // corresponding `Projection` clause
194- for def_ids in associated_types . values_mut ( ) {
195- for ( projection_bound , span ) in & projection_bounds {
196- let def_id = projection_bound . projection_def_id ( ) ;
197- // FIXME(#120456) - is `swap_remove` correct?
198- def_ids . swap_remove ( & def_id ) ;
199- if tcx . generics_require_sized_self ( def_id) {
200- tcx. emit_node_span_lint (
201- UNUSED_ASSOCIATED_TYPE_BOUNDS ,
202- hir_id ,
203- * span ,
204- crate :: errors :: UnusedAssociatedTypeBounds { span : * span } ,
205- ) ;
206- }
209+ for ( projection_bound , span ) in & projection_bounds {
210+ let def_id = projection_bound . projection_def_id ( ) ;
211+ let trait_ref = tcx . anonymize_bound_vars (
212+ projection_bound . map_bound ( |p| p . projection_term . trait_ref ( tcx ) ) ,
213+ ) ;
214+ needed_associated_types . swap_remove ( & ( def_id, trait_ref ) ) ;
215+ if tcx. generics_require_sized_self ( def_id ) {
216+ tcx . emit_node_span_lint (
217+ UNUSED_ASSOCIATED_TYPE_BOUNDS ,
218+ hir_id ,
219+ * span,
220+ crate :: errors :: UnusedAssociatedTypeBounds { span : * span } ,
221+ ) ;
207222 }
208- // If the associated type has a `where Self: Sized` bound, we do not need to constrain the associated
209- // type in the `dyn Trait`.
210- def_ids. retain ( |def_id| !tcx. generics_require_sized_self ( def_id) ) ;
211223 }
212224
213225 self . complain_about_missing_assoc_tys (
214- associated_types,
226+ principal_span,
227+ needed_associated_types,
215228 potential_assoc_types,
216229 hir_trait_bounds,
217230 ) ;
0 commit comments