@@ -29,6 +29,7 @@ use infer::type_variable::TypeVariableOrigin;
2929use rustc_data_structures:: snapshot_map:: { Snapshot , SnapshotMap } ;
3030use syntax:: ast;
3131use syntax:: symbol:: Symbol ;
32+ use syntax_pos:: DUMMY_SP ;
3233use ty:: subst:: Subst ;
3334use ty:: { self , ToPredicate , ToPolyTraitRef , Ty , TyCtxt } ;
3435use ty:: fold:: { TypeFoldable , TypeFolder } ;
@@ -1317,13 +1318,38 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
13171318 assoc_ty_name : ast:: Name )
13181319 -> Option < specialization_graph:: NodeItem < ty:: AssociatedItem > >
13191320{
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+ }
13271353}
13281354
13291355// # Cache
0 commit comments