if other.evaluation == EvaluatedToOk {
if let ImplCandidate(victim_def) = victim.candidate {
let tcx = self.tcx().global_tcx();
- return traits::specializes(tcx, other_def, victim_def);
+ return traits::specializes(tcx, other_def, victim_def) ||
+ tcx.impls_are_allowed_to_overlap(other_def, victim_def);
}
}
return r;
}
- if tcx.impl_always_allowed_to_overlap(impl1_def_id)
- && tcx.impl_always_allowed_to_overlap(impl2_def_id) {
- return true;
- }
-
// The feature gate should prevent introducing new specializations, but not
// taking advantage of upstream ones.
if !tcx.sess.features.borrow().specialization &&
possible_sibling,
impl_def_id);
if let Some(impl_header) = overlap {
- if tcx.impl_always_allowed_to_overlap(impl_def_id)
- && tcx.impl_always_allowed_to_overlap(possible_sibling) {
- return Ok((true, true));
+ if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
+ return Ok((false, false));
}
let le = specializes(tcx, impl_def_id, possible_sibling);
queries::impl_trait_ref::get(self, DUMMY_SP, id)
}
- /// Returns true if the impl is positive and is for a trait which contains
- /// no items
- pub fn impl_always_allowed_to_overlap(self, def_id: DefId) -> bool {
- self.trait_impl_polarity(def_id) == hir::ImplPolarity::Positive
- && self.impl_trait_ref(def_id)
- .map_or(false, |trait_ref| {
- self.associated_item_def_ids(trait_ref.def_id).is_empty()
- })
+ /// Returns true if the impls are the same polarity and are implementing
+ /// a trait which contains no items
+ pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool {
+ let trait1_is_empty = self.impl_trait_ref(def_id1)
+ .map_or(false, |trait_ref| {
+ self.associated_item_def_ids(trait_ref.def_id).is_empty()
+ });
+ let trait2_is_empty = self.impl_trait_ref(def_id2)
+ .map_or(false, |trait_ref| {
+ self.associated_item_def_ids(trait_ref.def_id).is_empty()
+ });
+ self.trait_impl_polarity(def_id1) == self.trait_impl_polarity(def_id2)
+ && trait1_is_empty
+ && trait2_is_empty
}
// Returns `ty::VariantDef` if `def` refers to a struct,