@@ -22,11 +22,20 @@ struct OpaqueTypeCollector<'tcx> {
22
22
seen : FxHashSet < LocalDefId > ,
23
23
24
24
span : Option < Span > ,
25
+
26
+ mode : CollectionMode ,
27
+ }
28
+
29
+ enum CollectionMode {
30
+ /// For impl trait in assoc types we only permit collecting them from
31
+ /// associated types of the same impl block.
32
+ ImplTraitInAssocTypes ,
33
+ TypeAliasImplTraitTransition ,
25
34
}
26
35
27
36
impl < ' tcx > OpaqueTypeCollector < ' tcx > {
28
- fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId ) -> Self {
29
- Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) , span : None }
37
+ fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId , mode : CollectionMode ) -> Self {
38
+ Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) , span : None , mode }
30
39
}
31
40
32
41
fn span ( & self ) -> Span {
@@ -251,6 +260,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
251
260
}
252
261
}
253
262
ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => {
263
+ if let CollectionMode :: ImplTraitInAssocTypes = self . mode {
264
+ return ControlFlow :: Continue ( ( ) ) ;
265
+ }
254
266
if !self . seen . insert ( def. did ( ) . expect_local ( ) ) {
255
267
return ControlFlow :: Continue ( ( ) ) ;
256
268
}
@@ -275,89 +287,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
275
287
}
276
288
}
277
289
278
- struct ImplTraitInAssocTypeCollector < ' tcx > ( OpaqueTypeCollector < ' tcx > ) ;
279
-
280
- impl < ' tcx > super :: sig_types:: SpannedTypeVisitor < ' tcx > for ImplTraitInAssocTypeCollector < ' tcx > {
281
- #[ instrument( skip( self ) , ret, level = "trace" ) ]
282
- fn visit ( & mut self , span : Span , value : impl TypeVisitable < TyCtxt < ' tcx > > ) -> ControlFlow < !> {
283
- let old = self . 0 . span ;
284
- self . 0 . span = Some ( span) ;
285
- value. visit_with ( self ) ;
286
- self . 0 . span = old;
287
-
288
- ControlFlow :: Continue ( ( ) )
289
- }
290
- }
291
-
292
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for ImplTraitInAssocTypeCollector < ' tcx > {
293
- #[ instrument( skip( self ) , ret, level = "trace" ) ]
294
- fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < !> {
295
- t. super_visit_with ( self ) ?;
296
- match t. kind ( ) {
297
- ty:: Alias ( ty:: Opaque , alias_ty) if alias_ty. def_id . is_local ( ) => {
298
- self . 0 . visit_opaque_ty ( alias_ty) ;
299
- }
300
- ty:: Alias ( ty:: Projection , alias_ty) => {
301
- // This avoids having to do normalization of `Self::AssocTy` by only
302
- // supporting the case of a method defining opaque types from assoc types
303
- // in the same impl block.
304
- let parent_trait_ref = self
305
- . 0
306
- . parent_trait_ref ( )
307
- . expect ( "impl trait in assoc type collector used on non-assoc item" ) ;
308
- // If the trait ref of the associated item and the impl differs,
309
- // then we can't use the impl's identity args below, so
310
- // just skip.
311
- if alias_ty. trait_ref ( self . 0 . tcx ) == parent_trait_ref {
312
- let parent = self . 0 . parent ( ) . expect ( "we should have a parent here" ) ;
313
-
314
- for & assoc in self . 0 . tcx . associated_items ( parent) . in_definition_order ( ) {
315
- trace ! ( ?assoc) ;
316
- if assoc. trait_item_def_id != Some ( alias_ty. def_id ) {
317
- continue ;
318
- }
319
-
320
- // If the type is further specializable, then the type_of
321
- // is not actually correct below.
322
- if !assoc. defaultness ( self . 0 . tcx ) . is_final ( ) {
323
- continue ;
324
- }
325
-
326
- let impl_args = alias_ty. args . rebase_onto (
327
- self . 0 . tcx ,
328
- parent_trait_ref. def_id ,
329
- ty:: GenericArgs :: identity_for_item ( self . 0 . tcx , parent) ,
330
- ) ;
331
-
332
- if check_args_compatible ( self . 0 . tcx , assoc, impl_args) {
333
- return self
334
- . 0
335
- . tcx
336
- . type_of ( assoc. def_id )
337
- . instantiate ( self . 0 . tcx , impl_args)
338
- . visit_with ( self ) ;
339
- } else {
340
- self . 0 . tcx . dcx ( ) . span_bug (
341
- self . 0 . tcx . def_span ( assoc. def_id ) ,
342
- "item had incorrect args" ,
343
- ) ;
344
- }
345
- }
346
- }
347
- }
348
- _ => trace ! ( kind=?t. kind( ) ) ,
349
- }
350
- ControlFlow :: Continue ( ( ) )
351
- }
352
- }
353
-
354
290
fn impl_trait_in_assoc_types_defined_by < ' tcx > (
355
291
tcx : TyCtxt < ' tcx > ,
356
292
item : LocalDefId ,
357
293
) -> & ' tcx ty:: List < LocalDefId > {
358
- let mut collector = ImplTraitInAssocTypeCollector ( OpaqueTypeCollector :: new ( tcx, item) ) ;
294
+ let mut collector = OpaqueTypeCollector :: new ( tcx, item, CollectionMode :: ImplTraitInAssocTypes ) ;
359
295
super :: sig_types:: walk_types ( tcx, item, & mut collector) ;
360
- tcx. mk_local_def_ids ( & collector. 0 . opaques )
296
+ tcx. mk_local_def_ids ( & collector. opaques )
361
297
}
362
298
363
299
fn opaque_types_defined_by < ' tcx > (
@@ -366,7 +302,8 @@ fn opaque_types_defined_by<'tcx>(
366
302
) -> & ' tcx ty:: List < LocalDefId > {
367
303
let kind = tcx. def_kind ( item) ;
368
304
trace ! ( ?kind) ;
369
- let mut collector = OpaqueTypeCollector :: new ( tcx, item) ;
305
+ let mut collector =
306
+ OpaqueTypeCollector :: new ( tcx, item, CollectionMode :: TypeAliasImplTraitTransition ) ;
370
307
super :: sig_types:: walk_types ( tcx, item, & mut collector) ;
371
308
match kind {
372
309
DefKind :: AssocFn
0 commit comments