Skip to content

Commit

Permalink
Re-introduce cycle-check in assoc. item resolution.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed May 15, 2017
1 parent 8da2fe8 commit 40a6734
Showing 1 changed file with 33 additions and 7 deletions.
40 changes: 33 additions & 7 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use infer::type_variable::TypeVariableOrigin;
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use syntax::ast;
use syntax::symbol::Symbol;
use syntax_pos::DUMMY_SP;
use ty::subst::Subst;
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder};
Expand Down Expand Up @@ -1317,13 +1318,38 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
assoc_ty_name: ast::Name)
-> Option<specialization_graph::NodeItem<ty::AssociatedItem>>
{
let trait_def_id = selcx.tcx().impl_trait_ref(impl_def_id).unwrap().def_id;
let trait_def = selcx.tcx().trait_def(trait_def_id);

trait_def
.ancestors(selcx.tcx(), impl_def_id)
.defs(selcx.tcx(), assoc_ty_name, ty::AssociatedKind::Type)
.next()
let tcx = selcx.tcx();
let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id;
let trait_def = tcx.trait_def(trait_def_id);

// This function may be called while we are still building the
// specialization graph that is queried below (via TraidDef::ancestors()),
// so, in order to avoid infinite recursion, we detect this case by
// seeing if a query of the specialization graph fails with a cycle error.
// If we are in cycle, and thus still building the graph, we perform a
// reduced version of the associated item lookup that does not need the
// specialization graph.
let specialization_graph_complete =
ty::queries::specialization_graph_of::try_get(tcx,
DUMMY_SP,
trait_def_id).is_ok();
if !specialization_graph_complete {
let impl_node = specialization_graph::Node::Impl(impl_def_id);
for item in impl_node.items(tcx) {
if item.kind == ty::AssociatedKind::Type && item.name == assoc_ty_name {
return Some(specialization_graph::NodeItem {
node: specialization_graph::Node::Impl(impl_def_id),
item: item,
});
}
}
None
} else {
trait_def
.ancestors(tcx, impl_def_id)
.defs(tcx, assoc_ty_name, ty::AssociatedKind::Type)
.next()
}
}

// # Cache
Expand Down

0 comments on commit 40a6734

Please sign in to comment.