]> git.lizzy.rs Git - rust.git/commitdiff
Record negative trait_impls separatedly
authorFlavio Percoco <flaper87@gmail.com>
Wed, 7 Jan 2015 18:26:51 +0000 (19:26 +0100)
committerFlavio Percoco <flaper87@gmail.com>
Fri, 16 Jan 2015 07:18:55 +0000 (08:18 +0100)
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/middle/ty.rs

index 0bbd11bea0a48e0daaee8a8e5b8da9b0fdef911b..e34fb37e1c5551b499270a49387b193550fc07b7 100644 (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>,
index dfbff7156886d42ce45f9e15eac2a02c8de51bd1..6bf1798d246a409e5b36e7d0531380e6e965c54d 100644 (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>)
index 11b605e2e2fec57d354cb654926eab62af4f1047..fdd4b975caa234a9e6521adc3e2312a4075e394b 100644 (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