Skip to content

Commit 7e464c2

Browse files
committed
Record negative trait_impls separatedly
1 parent 3614e1d commit 7e464c2

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()),
@@ -5025,6 +5029,23 @@ pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId)
50255029
}
50265030
}
50275031

5032+
pub fn trait_impl_polarity<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5033+
-> Option<ast::ImplPolarity> {
5034+
if id.krate == ast::LOCAL_CRATE {
5035+
match cx.map.find(id.node) {
5036+
Some(ast_map::NodeItem(item)) => {
5037+
match item.node {
5038+
ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
5039+
_ => None
5040+
}
5041+
}
5042+
_ => None
5043+
}
5044+
} else {
5045+
csearch::get_impl_polarity(cx, id)
5046+
}
5047+
}
5048+
50285049
pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
50295050
-> ImplOrTraitItem<'tcx> {
50305051
lookup_locally_or_in_crate_store("impl_or_trait_items",
@@ -5974,14 +5995,23 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
59745995
pub fn record_trait_implementation(tcx: &ctxt,
59755996
trait_def_id: DefId,
59765997
impl_def_id: DefId) {
5977-
match tcx.trait_impls.borrow().get(&trait_def_id) {
5998+
5999+
let trait_impls = match trait_impl_polarity(tcx, impl_def_id) {
6000+
Some(ast::ImplPolarity::Positive) => &tcx.trait_impls,
6001+
Some(ast::ImplPolarity::Negative) => &tcx.trait_negative_impls,
6002+
_ => tcx.sess.bug(&format!("tried to record a non-impl item with id {:?}",
6003+
impl_def_id)[])
6004+
};
6005+
6006+
match trait_impls.borrow().get(&trait_def_id) {
59786007
Some(impls_for_trait) => {
59796008
impls_for_trait.borrow_mut().push(impl_def_id);
59806009
return;
59816010
}
59826011
None => {}
59836012
}
5984-
tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
6013+
6014+
trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
59856015
}
59866016

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

0 commit comments

Comments
 (0)