Fix an infinite loop in the stability check that was the result of

various bugs in `trait_id_of_impl`. The end result was that looking up
the "trait_id_of_impl" with a trait's def-id yielded the same trait
again, even though it ought to have yielded None.
This commit is contained in:
Niko Matsakis 2015-01-01 21:41:44 -05:00
parent 6ed3f24907
commit 82a2e8e310
3 changed files with 22 additions and 26 deletions

View File

@ -441,9 +441,15 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
-> Option<Rc<ty::TraitRef<'tcx>>>
{
let item_doc = lookup_item(id, cdata.data());
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
doc_trait_ref(tp, tcx, cdata)
})
let fam = item_family(item_doc);
match fam {
Family::Impl => {
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
doc_trait_ref(tp, tcx, cdata)
})
}
_ => None
}
}
pub fn get_impl_vtables<'tcx>(cdata: Cmd,

View File

@ -11,7 +11,8 @@
//! A pass that annotates every item and method with its stability level,
//! propagating default levels lexically from parent to children ast nodes.
use util::nodemap::{NodeMap, DefIdMap};
use middle::ty;
use metadata::csearch;
use syntax::codemap::Span;
use syntax::{attr, visit};
use syntax::ast;
@ -21,8 +22,8 @@ use syntax::ast::{TypeMethod, Method, Generics, StructField, TypeTraitItem};
use syntax::ast_util::is_local;
use syntax::attr::Stability;
use syntax::visit::{FnKind, FkMethod, Visitor};
use middle::ty;
use metadata::csearch;
use util::nodemap::{NodeMap, DefIdMap};
use util::ppaux::Repr;
use std::mem::replace;
@ -154,10 +155,13 @@ impl Index {
/// Lookup the stability for a node, loading external crate
/// metadata as necessary.
pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
debug!("lookup(id={})",
id.repr(tcx));
// is this definition the implementation of a trait method?
match ty::trait_item_of_item(tcx, id) {
Some(ty::MethodTraitItemId(trait_method_id))
if trait_method_id != id => {
Some(ty::MethodTraitItemId(trait_method_id)) if trait_method_id != id => {
debug!("lookup: trait_method_id={}", trait_method_id);
return lookup(tcx, trait_method_id)
}
_ => {}
@ -178,6 +182,7 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
// stability of the trait to determine the stability of any
// unmarked impls for it. See FIXME above for more details.
debug!("lookup: trait_id={}", trait_id);
lookup(tcx, trait_id)
} else {
None

View File

@ -2862,8 +2862,6 @@ pub fn maybe_walk_ty<'tcx,F>(ty_root: Ty<'tcx>, mut f: F)
walker.skip_current_subtree();
}
}
maybe_walk_ty_(ty, &mut f);
}
// Folds types from the bottom up.
@ -6071,22 +6069,9 @@ pub fn populate_implementations_for_trait_if_necessary(
/// Given the def_id of an impl, return the def_id of the trait it implements.
/// If it implements no trait, return `None`.
pub fn trait_id_of_impl(tcx: &ctxt,
def_id: ast::DefId) -> Option<ast::DefId> {
let node = match tcx.map.find(def_id.node) {
Some(node) => node,
None => return None
};
match node {
ast_map::NodeItem(item) => {
match item.node {
ast::ItemImpl(_, _, Some(ref trait_ref), _, _) => {
Some(node_id_to_trait_ref(tcx, trait_ref.ref_id).def_id)
}
_ => None
}
}
_ => None
}
def_id: ast::DefId)
-> Option<ast::DefId> {
ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id)
}
/// If the given def ID describes a method belonging to an impl, return the