From 82a2e8e31016ace5ee67c89b852dcc8e1fa09e32 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 1 Jan 2015 21:41:44 -0500 Subject: [PATCH] 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. --- src/librustc/metadata/decoder.rs | 12 +++++++++--- src/librustc/middle/stability.rs | 15 ++++++++++----- src/librustc/middle/ty.rs | 21 +++------------------ 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index d079d0e52aa..a7fd7054a93 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -441,9 +441,15 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd, -> Option>> { 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, diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d793f49efe5..505352fa123 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -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 { + 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 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 diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index c84217d956f..622163bf7b8 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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 { - 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 { + 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