Skip to content

Commit 40a6734

Browse files
Re-introduce cycle-check in assoc. item resolution.
1 parent 8da2fe8 commit 40a6734

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

src/librustc/traits/project.rs

+33-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use infer::type_variable::TypeVariableOrigin;
2929
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
3030
use syntax::ast;
3131
use syntax::symbol::Symbol;
32+
use syntax_pos::DUMMY_SP;
3233
use ty::subst::Subst;
3334
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
3435
use 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

Comments
 (0)