diff options
| author | Sean Griffin <sean@seantheprogrammer.com> | 2017-03-17 12:43:15 -0400 |
|---|---|---|
| committer | Corey Farwell <coreyf@rwell.org> | 2017-04-14 22:04:53 -0400 |
| commit | c81c958e984b92222909e2ba5c74a2260a44bdae (patch) | |
| tree | 6e1532f5663b9c6d4ed4538da5b992d2ca959827 | |
| parent | ddcca79d25fffd6604fba593b1ca642a9dfa5727 (diff) | |
| download | rust-c81c958e984b92222909e2ba5c74a2260a44bdae.tar.gz rust-c81c958e984b92222909e2ba5c74a2260a44bdae.zip | |
Further update with response to feedback
| -rw-r--r-- | src/librustc/traits/select.rs | 3 | ||||
| -rw-r--r-- | src/librustc/traits/specialize/mod.rs | 5 | ||||
| -rw-r--r-- | src/librustc/traits/specialize/specialization_graph.rs | 5 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 22 | ||||
| -rw-r--r-- | src/test/compile-fail/auxiliary/trait_impl_conflict.rs | 1 |
5 files changed, 19 insertions, 17 deletions
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 67d50210ba3..410eb2b8484 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1736,7 +1736,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { 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); } } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 6455de48a29..50a4d982832 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -155,11 +155,6 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, 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 && diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 87abe681d39..6e2c16c82ae 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -113,9 +113,8 @@ impl<'a, 'gcx, 'tcx> Children { 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); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e9bcb80cff2..2ae77046a90 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2227,14 +2227,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { 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, diff --git a/src/test/compile-fail/auxiliary/trait_impl_conflict.rs b/src/test/compile-fail/auxiliary/trait_impl_conflict.rs index c3ecbb014dc..3190ce430ad 100644 --- a/src/test/compile-fail/auxiliary/trait_impl_conflict.rs +++ b/src/test/compile-fail/auxiliary/trait_impl_conflict.rs @@ -9,6 +9,7 @@ // except according to those terms. pub trait Foo { + fn foo() {} } impl Foo for isize { |
