support default impl for specialization

pr review
This commit is contained in:
Gianni Ciccarelli 2017-04-24 09:56:54 +00:00
parent b0fca5f790
commit 715811d0be
22 changed files with 202 additions and 65 deletions

View file

@ -1362,6 +1362,9 @@ impl<'a> LoweringContext<'a> {
}
ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
}
// [1] `defaultness.has_value()` is necer called for an `impl`, always `true` in order to
// not cause an assertion failure inside the `lower_defaultness` function
}
fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {

View file

@ -933,7 +933,7 @@ impl_stable_hash_for!(enum hir::Item_ {
ItemUnion(variant_data, generics),
ItemTrait(unsafety, generics, bounds, item_refs),
ItemDefaultImpl(unsafety, trait_ref),
ItemImpl(unsafety, impl_polarity, generics, trait_ref, ty, impl_item_refs)
ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
});
impl_stable_hash_for!(struct hir::TraitItemRef {

View file

@ -195,6 +195,7 @@ pub trait CrateStore {
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
// impl info
fn impl_defaultness(&self, def: DefId) -> hir::Defaultness;
fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
// trait/impl-item info
@ -329,6 +330,7 @@ impl CrateStore for DummyCrateStore {
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
// impl info
fn impl_defaultness(&self, def: DefId) -> hir::Defaultness { bug!("impl_defaultness") }
fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
// trait/impl-item info

View file

@ -33,7 +33,6 @@ use ty::subst::Subst;
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder};
use util::common::FN_OUTPUT_NAME;
use hir::{self};
/// Depending on the stage of compilation, we want projection to be
/// more or less conservative.
@ -924,28 +923,8 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
// being invoked).
node_item.item.defaultness.has_value()
} else {
let is_default = match selcx.tcx()
.map
.as_local_node_id(node_item.node.def_id()) {
Some(node_id) => {
let item = selcx.tcx().map.expect_item(node_id);
if let hir::ItemImpl(_, _, defaultness, ..) = item.node {
defaultness.is_default()
} else {
false
}
}
None => {
selcx.tcx()
.global_tcx()
.sess
.cstore
.impl_defaultness(node_item.node.def_id())
.is_default()
}
};
node_item.item.defaultness.is_default() || is_default
node_item.item.defaultness.is_default() ||
selcx.tcx().impl_is_default(node_item.node.def_id())
};
// Only reveal a specializable default if we're past type-checking

View file

@ -13,6 +13,7 @@ use ty::subst::{Subst, Substs};
use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
use ty::outlives::Component;
use util::nodemap::FxHashSet;
use hir::{self};
use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
@ -504,6 +505,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
};
ty::Binder((trait_ref, sig.skip_binder().output()))
}
pub fn impl_is_default(self, node_item_def_id: DefId) -> bool {
match self.hir.as_local_node_id(node_item_def_id) {
Some(node_id) => {
let item = self.hir.expect_item(node_id);
if let hir::ItemImpl(_, _, defaultness, ..) = item.node {
defaultness.is_default()
} else {
false
}
}
None => {
self.global_tcx()
.sess
.cstore
.impl_defaultness(node_item_def_id)
.is_default()
}
}
}
}
pub enum TupleArgumentsFlag { Yes, No }