diff options
| author | Michael Woerister <michaelwoerister@posteo.net> | 2017-05-15 12:21:28 +0200 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo.net> | 2017-05-15 15:28:28 +0200 |
| commit | 40a6734ae1a1ec9ad96b8f5b58a64d10d0cdbe76 (patch) | |
| tree | bed9a964631771761e329d00eb49ade2081b4ce1 /src | |
| parent | 8da2fe8ed72cc9960f4043867fc55c2b4bc4a3e3 (diff) | |
| download | rust-40a6734ae1a1ec9ad96b8f5b58a64d10d0cdbe76.tar.gz rust-40a6734ae1a1ec9ad96b8f5b58a64d10d0cdbe76.zip | |
Re-introduce cycle-check in assoc. item resolution.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/traits/project.rs | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index d6f6350373a..e119ead7473 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -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}; @@ -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 |
