From d021c55fb9a18b854cd70a3d67a260d4d71a14c3 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Fri, 20 Feb 2015 23:42:53 +0100 Subject: [PATCH] Restore the coherence visitor and fix fallouts --- src/librustc_typeck/coherence/overlap.rs | 38 ++++++++++++++++++- .../coherence-default-trait-impl.rs | 3 -- .../compile-fail/coherence-impls-builtin.rs | 1 + src/test/compile-fail/recursion_limit.rs | 3 ++ .../typeck-default-trait-impl-precedence.rs | 1 + 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() {} 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` }