}
}
+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();
}
}
+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>)
/// 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.
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()),
}
}
+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",
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