From 683d20c3c5c82043a36b3d328324599261912580 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Wed, 7 Jan 2015 19:26:51 +0100 Subject: [PATCH] Record negative trait_impls separatedly --- src/librustc/metadata/csearch.rs | 9 +++++++++ src/librustc/metadata/decoder.rs | 23 +++++++++++++++++++++ src/librustc/middle/ty.rs | 34 ++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 0bbd11bea0a..e34fb37e1c5 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -262,6 +262,15 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId, } } +pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>, + def: ast::DefId) + -> Option +{ + let cstore = &tcx.sess.cstore; + let cdata = cstore.get_crate_data(def.krate); + decoder::get_impl_polarity(&*cdata, def.node) +} + // Given a def_id for an impl, return the trait it implements, // if there is one. pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>, diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index dfbff715688..6bf1798d246 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -371,6 +371,15 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety { } } +fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity { + let polarity_doc = reader::get_doc(item_doc, tag_polarity); + if reader::doc_as_u8(polarity_doc) != 0 { + ast::ImplPolarity::Negative + } else { + ast::ImplPolarity::Positive + } +} + fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec { let names_doc = reader::get_doc(item_doc, tag_associated_type_names); let mut names = Vec::new(); @@ -436,6 +445,20 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec { } } +pub fn get_impl_polarity<'tcx>(cdata: Cmd, + id: ast::NodeId) + -> Option +{ + let item_doc = lookup_item(id, cdata.data()); + let fam = item_family(item_doc); + match fam { + Family::Impl => { + Some(parse_polarity(item_doc)) + } + _ => None + } +} + pub fn get_impl_trait<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 11b605e2e2f..fdd4b975caa 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -750,6 +750,9 @@ pub struct ctxt<'tcx> { /// Maps a trait onto a list of impls of that trait. pub trait_impls: RefCell>>>>, + /// Maps a trait onto a list of negative impls of that trait. + pub trait_negative_impls: RefCell>>>>, + /// Maps a DefId of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. @@ -2412,6 +2415,7 @@ pub fn mk_ctxt<'tcx>(s: Session, destructor_for_type: RefCell::new(DefIdMap::new()), destructors: RefCell::new(DefIdSet::new()), trait_impls: RefCell::new(DefIdMap::new()), + trait_negative_impls: RefCell::new(DefIdMap::new()), inherent_impls: RefCell::new(DefIdMap::new()), impl_items: RefCell::new(DefIdMap::new()), used_unsafe: RefCell::new(NodeSet::new()), @@ -5035,6 +5039,23 @@ pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId) } } +pub fn trait_impl_polarity<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) + -> Option { + if id.krate == ast::LOCAL_CRATE { + match cx.map.find(id.node) { + Some(ast_map::NodeItem(item)) => { + match item.node { + ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity), + _ => None + } + } + _ => None + } + } else { + csearch::get_impl_polarity(cx, id) + } +} + pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> ImplOrTraitItem<'tcx> { lookup_locally_or_in_crate_store("impl_or_trait_items", @@ -5984,14 +6005,23 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc { pub fn record_trait_implementation(tcx: &ctxt, trait_def_id: DefId, impl_def_id: DefId) { - match tcx.trait_impls.borrow().get(&trait_def_id) { + + let trait_impls = match trait_impl_polarity(tcx, impl_def_id) { + Some(ast::ImplPolarity::Positive) => &tcx.trait_impls, + Some(ast::ImplPolarity::Negative) => &tcx.trait_negative_impls, + _ => tcx.sess.bug(&format!("tried to record a non-impl item with id {:?}", + impl_def_id)[]) + }; + + match trait_impls.borrow().get(&trait_def_id) { Some(impls_for_trait) => { impls_for_trait.borrow_mut().push(impl_def_id); return; } None => {} } - tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id)))); + + trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id)))); } /// Populates the type context with all the implementations for the given type