Skip to content

Commit 2afc09e

Browse files
committed
This works, except that coherence problems go in the wrong order
It compile-tests, and causes ICE when the "first" impl comes from a local crate. Will give perf numbers tomorrow.
1 parent f2a4202 commit 2afc09e

File tree

6 files changed

+26
-20
lines changed

6 files changed

+26
-20
lines changed

src/librustc/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ fn encode_extension_implementations(ecx: &EncodeContext,
977977
// TODO: how do we ensure only locals?
978978
let def = ty::lookup_trait_def(ecx.tcx, trait_def_id);
979979

980-
def.for_each_impl(|impl_def_id| {
980+
def.for_each_impl(ecx.tcx, |impl_def_id| {
981981
rbml_w.start_tag(tag_items_data_item_extension_impl);
982982
encode_def_id(rbml_w, impl_def_id);
983983
rbml_w.end_tag();

src/librustc/middle/ty.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,9 @@ pub struct ctxt<'tcx> {
761761
/// The set of external nominal types whose implementations have been read.
762762
/// This is used for lazy resolution of methods.
763763
pub populated_external_types: RefCell<DefIdSet>,
764+
/// The set of external primitive types whose implementations have been read.
765+
/// FIXME(arielb1): why is this separate from populated_external_types?
766+
pub populated_external_primitive_impls: RefCell<DefIdSet>,
764767

765768
/// Borrows
766769
pub upvar_capture_map: RefCell<UpvarCaptureMap>,
@@ -949,6 +952,7 @@ impl fmt::Debug for TypeFlags {
949952
}
950953

951954
impl<'tcx> PartialEq for TyS<'tcx> {
955+
#[inline]
952956
fn eq(&self, other: &TyS<'tcx>) -> bool {
953957
// (self as *const _) == (other as *const _)
954958
(self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
@@ -2490,7 +2494,6 @@ bitflags! {
24902494
const IS_OBJECT_SAFE = 0b10,
24912495
const OBJECT_SAFETY_VALID = 0b100,
24922496
const IMPLS_VALID = 0b1000,
2493-
const PRIMITIVE_IMPLS_VALID = 0b10000
24942497
}
24952498
}
24962499

@@ -2548,7 +2551,9 @@ impl<'tcx> TraitDef<'tcx> {
25482551
);
25492552
}
25502553

2551-
pub fn for_each_impl<F: FnMut(DefId)>(&self, mut f: F) {
2554+
pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F) {
2555+
ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
2556+
25522557
for &impl_def_id in self.blanket_impls.borrow().iter() {
25532558
f(impl_def_id);
25542559
}
@@ -2565,6 +2570,8 @@ impl<'tcx> TraitDef<'tcx> {
25652570
trait_ref: TraitRef<'tcx>,
25662571
mut f: F)
25672572
{
2573+
ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
2574+
25682575
for &impl_def_id in self.blanket_impls.borrow().iter() {
25692576
f(impl_def_id);
25702577
}
@@ -2751,6 +2758,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
27512758
used_unsafe: RefCell::new(NodeSet()),
27522759
used_mut_nodes: RefCell::new(NodeSet()),
27532760
populated_external_types: RefCell::new(DefIdSet()),
2761+
populated_external_primitive_impls: RefCell::new(DefIdSet()),
27542762
upvar_capture_map: RefCell::new(FnvHashMap()),
27552763
extern_const_statics: RefCell::new(DefIdMap()),
27562764
extern_const_variants: RefCell::new(DefIdMap()),
@@ -6314,24 +6322,24 @@ pub fn record_trait_implementation<'tcx>(tcx: &ctxt<'tcx>,
63146322
}
63156323

63166324
/// Load primitive inherent implementations if necessary
6317-
pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt, lang_def_id: ast::DefId) {
6318-
if lang_def_id.krate == LOCAL_CRATE {
6325+
pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt,
6326+
primitive_def_id: ast::DefId) {
6327+
if primitive_def_id.krate == LOCAL_CRATE {
63196328
return
63206329
}
63216330

6322-
let def = lookup_trait_def(tcx, lang_def_id);
6323-
if def.flags.get().intersects(PRIMITIVE_IMPLS_VALID) {
6331+
if tcx.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
63246332
return
63256333
}
63266334

6327-
debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}", lang_def_id);
6335+
debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
6336+
primitive_def_id);
63286337

6329-
let impl_items = csearch::get_impl_items(&tcx.sess.cstore, lang_def_id);
6338+
let impl_items = csearch::get_impl_items(&tcx.sess.cstore, primitive_def_id);
63306339

63316340
// Store the implementation info.
6332-
tcx.impl_items.borrow_mut().insert(lang_def_id, impl_items);
6333-
6334-
def.flags.set(def.flags.get() | PRIMITIVE_IMPLS_VALID);
6341+
tcx.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
6342+
tcx.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
63356343
}
63366344

63376345
/// Populates the type context with all the implementations for the given type

src/librustc_lint/builtin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ impl LintPass for MissingDebugImplementations {
17471747
if self.impling_types.is_none() {
17481748
let debug_def = ty::lookup_trait_def(cx.tcx, debug);
17491749
let mut impls = NodeSet();
1750-
debug_def.for_each_impl(|d| {
1750+
debug_def.for_each_impl(cx.tcx, |d| {
17511751
if d.krate == ast::LOCAL_CRATE {
17521752
if let Some(ty_def) = ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)) {
17531753
impls.insert(ty_def.node);

src/librustc_typeck/check/method/probe.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -624,13 +624,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
624624
item: ty::ImplOrTraitItem<'tcx>,
625625
item_index: usize)
626626
{
627-
ty::populate_implementations_for_trait_if_necessary(self.tcx(),
628-
trait_def_id);
629-
630627
let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
631628

632629
// FIXME(arielb1): can we use for_each_relevant_impl here?
633-
trait_def.for_each_impl(|impl_def_id| {
630+
trait_def.for_each_impl(self.tcx(), |impl_def_id| {
634631
debug!("assemble_extension_candidates_for_trait_impl: trait_def_id={} impl_def_id={}",
635632
trait_def_id.repr(self.tcx()),
636633
impl_def_id.repr(self.tcx()));

src/librustc_typeck/coherence/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,12 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
385385
let drop_trait = match tcx.lang_items.drop_trait() {
386386
Some(id) => id, None => { return }
387387
};
388+
ty::populate_implementations_for_trait_if_necessary(tcx, drop_trait);
388389
let drop_trait = ty::lookup_trait_def(tcx, drop_trait);
389390

390391
let impl_items = tcx.impl_items.borrow();
391392

392-
drop_trait.for_each_impl(|impl_did| {
393+
drop_trait.for_each_impl(tcx, |impl_did| {
393394
let items = impl_items.get(&impl_did).unwrap();
394395
if items.is_empty() {
395396
// We'll error out later. For now, just don't ICE.
@@ -443,7 +444,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
443444
ty::populate_implementations_for_trait_if_necessary(tcx, copy_trait);
444445
let copy_trait = ty::lookup_trait_def(tcx, copy_trait);
445446

446-
copy_trait.for_each_impl(|impl_did| {
447+
copy_trait.for_each_impl(tcx, |impl_did| {
447448
debug!("check_implementations_of_copy: impl_did={}",
448449
impl_did.repr(tcx));
449450

src/test/compile-fail/associated-types-coherence-failure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ pub trait IntoCow<'a, B: ?Sized> {
2323
}
2424

2525
impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
26-
//~^ ERROR E0119
2726
fn into_cow(self) -> Cow<'a, B> {
2827
self
2928
}
3029
}
3130

3231
impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
32+
//~^ ERROR E0119
3333
//~^ ERROR E0119
3434
fn into_cow(self) -> Cow<'a, B> {
3535
Cow

0 commit comments

Comments
 (0)