@@ -29,6 +29,7 @@ use infer::type_variable::TypeVariableOrigin;
29
29
use rustc_data_structures:: snapshot_map:: { Snapshot , SnapshotMap } ;
30
30
use syntax:: ast;
31
31
use syntax:: symbol:: Symbol ;
32
+ use syntax_pos:: DUMMY_SP ;
32
33
use ty:: subst:: Subst ;
33
34
use ty:: { self , ToPredicate , ToPolyTraitRef , Ty , TyCtxt } ;
34
35
use ty:: fold:: { TypeFoldable , TypeFolder } ;
@@ -1317,13 +1318,38 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
1317
1318
assoc_ty_name : ast:: Name )
1318
1319
-> Option < specialization_graph:: NodeItem < ty:: AssociatedItem > >
1319
1320
{
1320
- let trait_def_id = selcx. tcx ( ) . impl_trait_ref ( impl_def_id) . unwrap ( ) . def_id ;
1321
- let trait_def = selcx. tcx ( ) . trait_def ( trait_def_id) ;
1322
-
1323
- trait_def
1324
- . ancestors ( selcx. tcx ( ) , impl_def_id)
1325
- . defs ( selcx. tcx ( ) , assoc_ty_name, ty:: AssociatedKind :: Type )
1326
- . next ( )
1321
+ let tcx = selcx. tcx ( ) ;
1322
+ let trait_def_id = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . def_id ;
1323
+ let trait_def = tcx. trait_def ( trait_def_id) ;
1324
+
1325
+ // This function may be called while we are still building the
1326
+ // specialization graph that is queried below (via TraidDef::ancestors()),
1327
+ // so, in order to avoid infinite recursion, we detect this case by
1328
+ // seeing if a query of the specialization graph fails with a cycle error.
1329
+ // If we are in cycle, and thus still building the graph, we perform a
1330
+ // reduced version of the associated item lookup that does not need the
1331
+ // specialization graph.
1332
+ let specialization_graph_complete =
1333
+ ty:: queries:: specialization_graph_of:: try_get ( tcx,
1334
+ DUMMY_SP ,
1335
+ trait_def_id) . is_ok ( ) ;
1336
+ if !specialization_graph_complete {
1337
+ let impl_node = specialization_graph:: Node :: Impl ( impl_def_id) ;
1338
+ for item in impl_node. items ( tcx) {
1339
+ if item. kind == ty:: AssociatedKind :: Type && item. name == assoc_ty_name {
1340
+ return Some ( specialization_graph:: NodeItem {
1341
+ node : specialization_graph:: Node :: Impl ( impl_def_id) ,
1342
+ item : item,
1343
+ } ) ;
1344
+ }
1345
+ }
1346
+ None
1347
+ } else {
1348
+ trait_def
1349
+ . ancestors ( tcx, impl_def_id)
1350
+ . defs ( tcx, assoc_ty_name, ty:: AssociatedKind :: Type )
1351
+ . next ( )
1352
+ }
1327
1353
}
1328
1354
1329
1355
// # Cache
0 commit comments