mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 18:53:39 +00:00
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:
parent
6ed3f24907
commit
82a2e8e310
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user