Record negative trait_impls separatedly

This commit is contained in:
Flavio Percoco 2015-01-07 19:26:51 +01:00
parent b565501ad8
commit 683d20c3c5
3 changed files with 64 additions and 2 deletions

View File

@ -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<ast::ImplPolarity>
{
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>,

View File

@ -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<ast::Name> {
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<attr::ReprAttr> {
}
}
pub fn get_impl_polarity<'tcx>(cdata: Cmd,
id: ast::NodeId)
-> Option<ast::ImplPolarity>
{
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>)

View File

@ -750,6 +750,9 @@ pub struct ctxt<'tcx> {
/// Maps a trait onto a list of impls of that trait.
pub trait_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
/// Maps a trait onto a list of negative impls of that trait.
pub trait_negative_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
/// 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<ast::ImplPolarity> {
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<ItemVariances> {
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