Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_typeck: remove the "preload all impls ever" workaround in coherence. #25323

Merged
merged 4 commits into from
May 12, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
rustc_typeck: remove the "preload all impls ever" workaround in coher…
…ence.
  • Loading branch information
eddyb committed May 12, 2015
commit 75cd8f94e1f6319f92f837f9ef6884fafca8fb6f
9 changes: 0 additions & 9 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,6 @@ pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
decoder::get_native_libraries(&*cdata)
}

pub fn each_impl<F>(cstore: &cstore::CStore,
crate_num: ast::CrateNum,
callback: F) where
F: FnMut(ast::DefId),
{
let cdata = cstore.get_crate_data(crate_num);
decoder::each_impl(&*cdata, callback)
}

pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore,
def_id: ast::DefId,
callback: F) where
Expand Down
10 changes: 0 additions & 10 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,16 +1344,6 @@ fn reverse_translate_def_id(cdata: Cmd, did: ast::DefId) -> Option<ast::DefId> {
None
}

pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
F: FnMut(ast::DefId),
{
let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| {
callback(item_def_id(impl_doc, cdata));
true
});
}

pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
id: ast::NodeId,
mut callback: F)
Expand Down
80 changes: 3 additions & 77 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@
// mappings. That mapping code resides here.


use metadata::csearch::{each_impl, get_impl_trait};
use metadata::csearch;
use middle::subst::{self, Subst};
use middle::ty::RegionEscape;
use middle::ty::{ImplContainer, ImplOrTraitItemId, ConstTraitItemId};
use middle::ty::{MethodTraitItemId, TypeTraitItemId};
use middle::ty::{ParameterEnvironment, lookup_item_type};
use middle::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment};
use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
use middle::ty::{ty_param, TypeScheme, ty_ptr};
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
Expand All @@ -33,7 +30,6 @@ use middle::ty;
use CrateCtxt;
use middle::infer::InferCtxt;
use middle::infer::new_infer_ctxt;
use std::collections::HashSet;
use std::cell::RefCell;
use std::rc::Rc;
use syntax::ast::{Crate, DefId};
Expand Down Expand Up @@ -130,11 +126,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
Rc::new((*v.borrow()).clone()));
}

// Bring in external crates. It's fine for this to happen after the
// coherence checks, because we ensure by construction that no errors
// can happen at link time.
self.add_external_crates();

// Populate the table of destructors. It might seem a bit strange to
// do this here, but it's actually the most convenient place, since
// the coherence tables contain the trait -> type mappings.
Expand Down Expand Up @@ -267,11 +258,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
trait_def.record_impl(self.crate_context.tcx, impl_def_id, impl_trait_ref);
}

fn get_self_type_for_implementation(&self, impl_did: DefId)
-> TypeScheme<'tcx> {
self.crate_context.tcx.tcache.borrow().get(&impl_did).unwrap().clone()
}

// Converts an implementation in the AST to a vector of items.
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
match item.node {
Expand Down Expand Up @@ -313,66 +299,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
}
}

// External crate handling

fn add_external_impl(&self,
impls_seen: &mut HashSet<DefId>,
impl_def_id: DefId) {
let tcx = self.crate_context.tcx;
let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
impl_def_id);

// Make sure we don't visit the same implementation multiple times.
if !impls_seen.insert(impl_def_id) {
// Skip this one.
return
}
// Good. Continue.

let _ = lookup_item_type(tcx, impl_def_id);
let associated_traits = get_impl_trait(tcx, impl_def_id);

// Do a sanity check.
assert!(associated_traits.is_some());

// Record all the trait items.
if let Some(trait_ref) = associated_traits {
self.add_trait_impl(trait_ref, impl_def_id);
}

// For any methods that use a default implementation, add them to
// the map. This is a bit unfortunate.
for item_def_id in &impl_items {
let impl_item = ty::impl_or_trait_item(tcx, item_def_id.def_id());
match impl_item {
ty::MethodTraitItem(ref method) => {
if let Some(source) = method.provided_source {
tcx.provided_method_sources
.borrow_mut()
.insert(item_def_id.def_id(), source);
}
}
_ => {}
}
}

tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
}

// Adds implementations and traits from external crates to the coherence
// info.
fn add_external_crates(&self) {
let mut impls_seen = HashSet::new();

let crate_store = &self.crate_context.tcx.sess.cstore;
crate_store.iter_crate_data(|crate_number, _crate_metadata| {
each_impl(crate_store, crate_number, |def_id| {
assert_eq!(crate_number, def_id.krate);
self.add_external_impl(&mut impls_seen, def_id)
})
})
}

//
// Destructors
//
Expand All @@ -395,7 +321,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
}
let method_def_id = items[0];

let self_type = self.get_self_type_for_implementation(impl_did);
let self_type = ty::lookup_item_type(tcx, impl_did);
match self_type.ty.sty {
ty::ty_enum(type_def_id, _) |
ty::ty_struct(type_def_id, _) |
Expand Down Expand Up @@ -451,7 +377,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
return
}

let self_type = self.get_self_type_for_implementation(impl_did);
let self_type = ty::lookup_item_type(tcx, impl_did);
debug!("check_implementations_of_copy: self_type={} (bound)",
self_type.repr(tcx));

Expand Down
7 changes: 1 addition & 6 deletions src/librustc_typeck/coherence/overlap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,9 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
// check_for_overlapping_impls_of_trait() check, since that
// check can populate this table further with impls from other
// crates.
let trait_defs : Vec<&ty::TraitDef> = {
let d = self.tcx.trait_defs.borrow();
d.values().map(|&v|v).collect()
};
let trait_defs: Vec<_> = self.tcx.trait_defs.borrow().values().cloned().collect();

for trait_def in trait_defs {
// FIXME -- it seems like this method actually pushes
// duplicate impls onto the list
ty::populate_implementations_for_trait_if_necessary(
self.tcx,
trait_def.trait_ref.def_id);
Expand Down