@@ -19,9 +19,7 @@ use tracing::{debug, instrument};
19
19
use super :: errors:: GenericsArgsErrExtend ;
20
20
use crate :: bounds:: Bounds ;
21
21
use crate :: errors;
22
- use crate :: hir_ty_lowering:: {
23
- AssocItemQSelf , HirTyLowerer , OnlySelfBounds , PredicateFilter , RegionInferReason ,
24
- } ;
22
+ use crate :: hir_ty_lowering:: { AssocItemQSelf , HirTyLowerer , PredicateFilter , RegionInferReason } ;
25
23
26
24
impl < ' tcx > dyn HirTyLowerer < ' tcx > + ' _ {
27
25
/// Add a `Sized` bound to the `bounds` if appropriate.
@@ -150,11 +148,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
150
148
hir_bounds : I ,
151
149
bounds : & mut Bounds < ' tcx > ,
152
150
bound_vars : & ' tcx ty:: List < ty:: BoundVariableKind > ,
153
- only_self_bounds : OnlySelfBounds ,
151
+ predicate_filter : PredicateFilter ,
154
152
) where
155
153
' tcx : ' hir ,
156
154
{
157
155
for hir_bound in hir_bounds {
156
+ // In order to avoid cycles, when we're lowering `SelfThatDefines`,
157
+ // we skip over any traits that don't define the given associated type.
158
+
159
+ if let PredicateFilter :: SelfThatDefines ( assoc_name) = predicate_filter {
160
+ if let Some ( trait_ref) = hir_bound. trait_ref ( )
161
+ && let Some ( trait_did) = trait_ref. trait_def_id ( )
162
+ && self . tcx ( ) . trait_may_define_assoc_item ( trait_did, assoc_name)
163
+ {
164
+ // Okay
165
+ } else {
166
+ continue ;
167
+ }
168
+ }
169
+
158
170
match hir_bound {
159
171
hir:: GenericBound :: Trait ( poly_trait_ref) => {
160
172
let ( constness, polarity) = match poly_trait_ref. modifiers {
@@ -179,7 +191,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
179
191
polarity,
180
192
param_ty,
181
193
bounds,
182
- only_self_bounds ,
194
+ predicate_filter ,
183
195
) ;
184
196
}
185
197
hir:: GenericBound :: Outlives ( lifetime) => {
@@ -213,37 +225,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
213
225
& self ,
214
226
param_ty : Ty < ' tcx > ,
215
227
hir_bounds : & [ hir:: GenericBound < ' tcx > ] ,
216
- filter : PredicateFilter ,
228
+ predicate_filter : PredicateFilter ,
217
229
) -> Bounds < ' tcx > {
218
230
let mut bounds = Bounds :: default ( ) ;
219
231
220
- let only_self_bounds = match filter {
221
- PredicateFilter :: All | PredicateFilter :: SelfAndAssociatedTypeBounds => {
222
- OnlySelfBounds ( false )
223
- }
224
- PredicateFilter :: SelfOnly | PredicateFilter :: SelfThatDefines ( _) => OnlySelfBounds ( true ) ,
225
- } ;
226
-
227
232
self . lower_poly_bounds (
228
233
param_ty,
229
- hir_bounds. iter ( ) . filter ( |bound| match filter {
230
- PredicateFilter :: All
231
- | PredicateFilter :: SelfOnly
232
- | PredicateFilter :: SelfAndAssociatedTypeBounds => true ,
233
- PredicateFilter :: SelfThatDefines ( assoc_name) => {
234
- if let Some ( trait_ref) = bound. trait_ref ( )
235
- && let Some ( trait_did) = trait_ref. trait_def_id ( )
236
- && self . tcx ( ) . trait_may_define_assoc_item ( trait_did, assoc_name)
237
- {
238
- true
239
- } else {
240
- false
241
- }
242
- }
243
- } ) ,
234
+ hir_bounds. iter ( ) ,
244
235
& mut bounds,
245
236
ty:: List :: empty ( ) ,
246
- only_self_bounds ,
237
+ predicate_filter ,
247
238
) ;
248
239
debug ! ( ?bounds) ;
249
240
@@ -267,7 +258,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
267
258
bounds : & mut Bounds < ' tcx > ,
268
259
duplicates : & mut FxIndexMap < DefId , Span > ,
269
260
path_span : Span ,
270
- only_self_bounds : OnlySelfBounds ,
261
+ predicate_filter : PredicateFilter ,
271
262
) -> Result < ( ) , ErrorGuaranteed > {
272
263
let tcx = self . tcx ( ) ;
273
264
@@ -444,21 +435,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
444
435
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
445
436
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
446
437
hir:: AssocItemConstraintKind :: Bound { bounds : hir_bounds } => {
447
- // NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
448
- // a trait predicate, since we only want to add predicates for the `Self` type.
449
- if !only_self_bounds. 0 {
450
- let projection_ty = projection_term
451
- . map_bound ( |projection_term| projection_term. expect_ty ( self . tcx ( ) ) ) ;
452
- // Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
453
- // parameter to have a skipped binder.
454
- let param_ty = Ty :: new_alias ( tcx, ty:: Projection , projection_ty. skip_binder ( ) ) ;
455
- self . lower_poly_bounds (
456
- param_ty,
457
- hir_bounds. iter ( ) ,
458
- bounds,
459
- projection_ty. bound_vars ( ) ,
460
- only_self_bounds,
461
- ) ;
438
+ match predicate_filter {
439
+ PredicateFilter :: SelfOnly | PredicateFilter :: SelfThatDefines ( _) => { }
440
+ PredicateFilter :: All | PredicateFilter :: SelfAndAssociatedTypeBounds => {
441
+ let projection_ty = projection_term
442
+ . map_bound ( |projection_term| projection_term. expect_ty ( self . tcx ( ) ) ) ;
443
+ // Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
444
+ // parameter to have a skipped binder.
445
+ let param_ty =
446
+ Ty :: new_alias ( tcx, ty:: Projection , projection_ty. skip_binder ( ) ) ;
447
+ self . lower_poly_bounds (
448
+ param_ty,
449
+ hir_bounds. iter ( ) ,
450
+ bounds,
451
+ projection_ty. bound_vars ( ) ,
452
+ predicate_filter,
453
+ ) ;
454
+ }
462
455
}
463
456
}
464
457
}
0 commit comments