Skip to content

Commit 683d20c

Browse files
committed
Record negative trait_impls separatedly
1 parent b565501 commit 683d20c

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

src/librustc/metadata/csearch.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,15 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
262262
}
263263
}
264264

265+
pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
266+
def: ast::DefId)
267+
-> Option<ast::ImplPolarity>
268+
{
269+
let cstore = &tcx.sess.cstore;
270+
let cdata = cstore.get_crate_data(def.krate);
271+
decoder::get_impl_polarity(&*cdata, def.node)
272+
}
273+
265274
// Given a def_id for an impl, return the trait it implements,
266275
// if there is one.
267276
pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,

src/librustc/metadata/decoder.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,15 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
371371
}
372372
}
373373

374+
fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
375+
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
376+
if reader::doc_as_u8(polarity_doc) != 0 {
377+
ast::ImplPolarity::Negative
378+
} else {
379+
ast::ImplPolarity::Positive
380+
}
381+
}
382+
374383
fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
375384
let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
376385
let mut names = Vec::new();
@@ -436,6 +445,20 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
436445
}
437446
}
438447

448+
pub fn get_impl_polarity<'tcx>(cdata: Cmd,
449+
id: ast::NodeId)
450+
-> Option<ast::ImplPolarity>
451+
{
452+
let item_doc = lookup_item(id, cdata.data());
453+
let fam = item_family(item_doc);
454+
match fam {
455+
Family::Impl => {
456+
Some(parse_polarity(item_doc))
457+
}
458+
_ => None
459+
}
460+
}
461+
439462
pub fn get_impl_trait<'tcx>(cdata: Cmd,
440463
id: ast::NodeId,
441464
tcx: &ty::ctxt<'tcx>)

src/librustc/middle/ty.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,9 @@ pub struct ctxt<'tcx> {
750750
/// Maps a trait onto a list of impls of that trait.
751751
pub trait_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
752752

753+
/// Maps a trait onto a list of negative impls of that trait.
754+
pub trait_negative_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
755+
753756
/// Maps a DefId of a type to a list of its inherent impls.
754757
/// Contains implementations of methods that are inherent to a type.
755758
/// Methods in these implementations don't need to be exported.
@@ -2412,6 +2415,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
24122415
destructor_for_type: RefCell::new(DefIdMap::new()),
24132416
destructors: RefCell::new(DefIdSet::new()),
24142417
trait_impls: RefCell::new(DefIdMap::new()),
2418+
trait_negative_impls: RefCell::new(DefIdMap::new()),
24152419
inherent_impls: RefCell::new(DefIdMap::new()),
24162420
impl_items: RefCell::new(DefIdMap::new()),
24172421
used_unsafe: RefCell::new(NodeSet::new()),
@@ -5035,6 +5039,23 @@ pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId)
50355039
}
50365040
}
50375041

5042+
pub fn trait_impl_polarity<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5043+
-> Option<ast::ImplPolarity> {
5044+
if id.krate == ast::LOCAL_CRATE {
5045+
match cx.map.find(id.node) {
5046+
Some(ast_map::NodeItem(item)) => {
5047+
match item.node {
5048+
ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
5049+
_ => None
5050+
}
5051+
}
5052+
_ => None
5053+
}
5054+
} else {
5055+
csearch::get_impl_polarity(cx, id)
5056+
}
5057+
}
5058+
50385059
pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
50395060
-> ImplOrTraitItem<'tcx> {
50405061
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> {
59846005
pub fn record_trait_implementation(tcx: &ctxt,
59856006
trait_def_id: DefId,
59866007
impl_def_id: DefId) {
5987-
match tcx.trait_impls.borrow().get(&trait_def_id) {
6008+
6009+
let trait_impls = match trait_impl_polarity(tcx, impl_def_id) {
6010+
Some(ast::ImplPolarity::Positive) => &tcx.trait_impls,
6011+
Some(ast::ImplPolarity::Negative) => &tcx.trait_negative_impls,
6012+
_ => tcx.sess.bug(&format!("tried to record a non-impl item with id {:?}",
6013+
impl_def_id)[])
6014+
};
6015+
6016+
match trait_impls.borrow().get(&trait_def_id) {
59886017
Some(impls_for_trait) => {
59896018
impls_for_trait.borrow_mut().push(impl_def_id);
59906019
return;
59916020
}
59926021
None => {}
59936022
}
5994-
tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
6023+
6024+
trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
59956025
}
59966026

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

0 commit comments

Comments
 (0)