1
- use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
1
+ use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
2
2
use rustc_errors:: codes:: * ;
3
3
use rustc_errors:: struct_span_code_err;
4
4
use rustc_hir as hir;
5
5
use rustc_hir:: def:: { DefKind , Res } ;
6
- use rustc_hir:: def_id:: DefId ;
7
6
use rustc_lint_defs:: builtin:: UNUSED_ASSOCIATED_TYPE_BOUNDS ;
8
7
use rustc_middle:: span_bug;
9
8
use rustc_middle:: ty:: fold:: BottomUpFolder ;
10
9
use rustc_middle:: ty:: {
11
- self , DynKind , ExistentialPredicateStableCmpExt as _, Ty , TyCtxt , TypeFoldable , Upcast ,
10
+ self , DynKind , ExistentialPredicateStableCmpExt as _, Ty , TyCtxt , TypeFoldable ,
11
+ TypeVisitableExt , Upcast ,
12
12
} ;
13
- use rustc_span:: { ErrorGuaranteed , Span } ;
13
+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span } ;
14
14
use rustc_trait_selection:: error_reporting:: traits:: report_dyn_incompatibility;
15
15
use rustc_trait_selection:: traits:: { self , hir_ty_lowering_dyn_compatibility_violations} ;
16
16
use rustc_type_ir:: elaborate:: ClauseWithSupertraitSpan ;
@@ -92,11 +92,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
92
92
93
93
let ( mut auto_traits, regular_traits) : ( Vec < _ > , Vec < _ > ) =
94
94
expanded_traits. partition ( |i| tcx. trait_is_auto ( i. trait_ref ( ) . def_id ( ) ) ) ;
95
+
96
+ // We don't support >1 principal
95
97
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) ;
100
109
}
101
110
102
111
// Check that there are no gross dyn-compatibility violations;
@@ -118,15 +127,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
118
127
}
119
128
}
120
129
121
- let mut associated_types : FxIndexMap < Span , FxIndexSet < DefId > > = FxIndexMap :: default ( ) ;
130
+ let mut needed_associated_types = FxIndexSet :: default ( ) ;
122
131
132
+ let principal_span = regular_traits. first ( ) . map_or ( DUMMY_SP , |info| info. bottom ( ) . 1 ) ;
123
133
let regular_traits_refs_spans = trait_bounds
124
134
. into_iter ( )
125
135
. filter ( |( trait_ref, _) | !tcx. trait_is_auto ( trait_ref. def_id ( ) ) ) ;
126
136
127
137
for ( base_trait_ref, original_span) in regular_traits_refs_spans {
128
138
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
130
140
traits:: elaborate ( tcx, [ ClauseWithSupertraitSpan :: new ( base_pred, original_span) ] )
131
141
. filter_only_self ( )
132
142
{
@@ -135,13 +145,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
135
145
let bound_predicate = pred. kind ( ) ;
136
146
match bound_predicate. skip_binder ( ) {
137
147
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 ( ) )
141
153
. in_definition_order ( )
142
154
. filter ( |item| item. kind == ty:: AssocKind :: Type )
143
155
. 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) ) ,
145
160
) ;
146
161
}
147
162
ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( pred) ) => {
@@ -191,27 +206,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
191
206
// So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
192
207
// types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
193
208
// 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
+ ) ;
207
222
}
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) ) ;
211
223
}
212
224
213
225
self . complain_about_missing_assoc_tys (
214
- associated_types,
226
+ principal_span,
227
+ needed_associated_types,
215
228
potential_assoc_types,
216
229
hir_trait_bounds,
217
230
) ;
0 commit comments