about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlavio Percoco <flaper87@gmail.com>2015-02-20 23:42:53 +0100
committerFlavio Percoco <flaper87@gmail.com>2015-02-22 02:14:27 +0100
commitd021c55fb9a18b854cd70a3d67a260d4d71a14c3 (patch)
treec6a318a8cda3f3a21b13c47f656f5a31f4d63a47
parent3343e9c16976aabef9836e61213e64a0552ec051 (diff)
downloadrust-d021c55fb9a18b854cd70a3d67a260d4d71a14c3.tar.gz
rust-d021c55fb9a18b854cd70a3d67a260d4d71a14c3.zip
Restore the coherence visitor and fix fallouts
-rw-r--r--src/librustc_typeck/coherence/overlap.rs38
-rw-r--r--src/test/compile-fail/coherence-default-trait-impl.rs3
-rw-r--r--src/test/compile-fail/coherence-impls-builtin.rs1
-rw-r--r--src/test/compile-fail/recursion_limit.rs3
-rw-r--r--src/test/compile-fail/typeck-default-trait-impl-precedence.rs1
5 files changed, 42 insertions, 4 deletions
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index 14ca867a56c..366e934b4dd 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -17,12 +17,18 @@ use middle::infer::{self, new_infer_ctxt};
 use syntax::ast::{DefId};
 use syntax::ast::{LOCAL_CRATE};
 use syntax::ast;
+use syntax::ast_util;
+use syntax::visit;
 use syntax::codemap::Span;
 use util::ppaux::Repr;
 
 pub fn check(tcx: &ty::ctxt) {
-    let overlap = OverlapChecker { tcx: tcx };
+    let mut overlap = OverlapChecker { tcx: tcx };
     overlap.check_for_overlapping_impls();
+
+    // this secondary walk specifically checks for impls of defaulted
+    // traits, for which additional overlap rules exist
+    visit::walk_crate(&mut overlap, tcx.map.krate());
 }
 
 struct OverlapChecker<'cx, 'tcx:'cx> {
@@ -122,3 +128,33 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
         self.tcx.map.span(impl_did.node)
     }
 }
+
+
+impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
+    fn visit_item(&mut self, item: &'v ast::Item) {
+        match item.node {
+            ast::ItemDefaultImpl(_, _) => {
+                let impl_def_id = ast_util::local_def(item.id);
+                match ty::impl_trait_ref(self.tcx, impl_def_id) {
+                    Some(ref trait_ref) => {
+                        match ty::trait_default_impl(self.tcx, trait_ref.def_id) {
+                            Some(other_impl) if other_impl != impl_def_id => {
+                                self.report_overlap_error(trait_ref.def_id,
+                                                          other_impl,
+                                                          impl_def_id);
+                            }
+                            Some(_) => {}
+                            None => {
+                                self.tcx.sess.bug(
+                                          &format!("no default implementation recorded for `{:?}`",
+                                          item)[]);
+                            }
+                        }
+                    }
+                    _ => {}
+                }
+            }
+            _ => {}
+        }
+    }
+}
diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs
index ab653b3a554..6bcbefb904d 100644
--- a/src/test/compile-fail/coherence-default-trait-impl.rs
+++ b/src/test/compile-fail/coherence-default-trait-impl.rs
@@ -21,7 +21,4 @@ impl MyTrait for .. {}
 impl MyTrait for .. {}
 //~^ ERROR conflicting implementations for trait `MyTrait`
 
-impl MyTrait for (i32, i32) {}
-//~^ ERROR implementations for traits providing default implementations are only allowed on
-
 fn main() {}
diff --git a/src/test/compile-fail/coherence-impls-builtin.rs b/src/test/compile-fail/coherence-impls-builtin.rs
index 38730d241f6..3e132dcb11f 100644
--- a/src/test/compile-fail/coherence-impls-builtin.rs
+++ b/src/test/compile-fail/coherence-impls-builtin.rs
@@ -34,6 +34,7 @@ unsafe impl Send for [MyType] {}
 
 unsafe impl Send for &'static [NotSync] {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
+//~^^ ERROR conflicting implementations for trait `core::marker::Send`
 
 fn is_send<T: Send>() {}
 
diff --git a/src/test/compile-fail/recursion_limit.rs b/src/test/compile-fail/recursion_limit.rs
index 6cd984c071a..e8bc11317f2 100644
--- a/src/test/compile-fail/recursion_limit.rs
+++ b/src/test/compile-fail/recursion_limit.rs
@@ -47,4 +47,7 @@ fn main() {
     //~^^^^ ERROR overflow evaluating
     //~^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
     //~^^^^^^ NOTE required by `is_send`
+    //~^^^^^^^ ERROR overflow evaluating
+    //~^^^^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
+    //~^^^^^^^^^ NOTE required by `is_send`
 }
diff --git a/src/test/compile-fail/typeck-default-trait-impl-precedence.rs b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
index e519c3f2c2f..4006eb2e83e 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
@@ -29,4 +29,5 @@ impl Signed for i32 { }
 fn main() {
     is_defaulted::<&'static i32>();
     is_defaulted::<&'static u32>();
+    //~^ ERROR the trait `Signed` is not implemented for the type `u32`
 }