]> git.lizzy.rs Git - rust.git/commitdiff
Further update with response to feedback
authorSean Griffin <sean@seantheprogrammer.com>
Fri, 17 Mar 2017 16:43:15 +0000 (12:43 -0400)
committerCorey Farwell <coreyf@rwell.org>
Sat, 15 Apr 2017 02:04:53 +0000 (22:04 -0400)
src/librustc/traits/select.rs
src/librustc/traits/specialize/mod.rs
src/librustc/traits/specialize/specialization_graph.rs
src/librustc/ty/mod.rs
src/test/compile-fail/auxiliary/trait_impl_conflict.rs

index 67d50210ba39adb94a909c475424607ba445f5d4..410eb2b84849e0a830bb0dddf9b90cb7d386cc7d 100644 (file)
@@ -1736,7 +1736,8 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
                 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);
                     }
                 }
 
index 6455de48a299dfe54568d554d48110e4274d2aa0..50a4d982832ace739c8c78b7afac69938d07f6c7 100644 (file)
@@ -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 &&
index 87abe681d39380491bc761cd3c78aefb96e3fd9a..6e2c16c82aeb42274fd30c21a4a058a66d607e00 100644 (file)
@@ -113,9 +113,8 @@ fn insert(&mut self,
                                                         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);
index e9bcb80cff25e6b9d363ec81e7eefe429e876e0a..2ae77046a90ed776a8f4464172f6725905cc183e 100644 (file)
@@ -2227,14 +2227,20 @@ pub fn impl_trait_ref(self, id: DefId) -> Option<TraitRef<'gcx>> {
         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,
index c3ecbb014dc6b0aac1dfa9e077383a15e86b79cd..3190ce430ad67ca41fc32553745bc6b016e52678 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 pub trait Foo {
+    fn foo() {}
 }
 
 impl Foo for isize {