about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-02-20 13:34:13 -0500
committerFlavio Percoco <flaper87@gmail.com>2015-02-22 02:14:27 +0100
commit3343e9c16976aabef9836e61213e64a0552ec051 (patch)
tree0aed1c39affc63f07ee20e46406b866e653a26a5
parent6d1844c8065c5c680b0a86c83152902b47bc856c (diff)
downloadrust-3343e9c16976aabef9836e61213e64a0552ec051.tar.gz
rust-3343e9c16976aabef9836e61213e64a0552ec051.zip
Add new test for impl precedence and remove unnecessary coherence rules that prevent the test from compiling.
-rw-r--r--src/librustc_typeck/coherence/overlap.rs57
-rw-r--r--src/test/compile-fail/typeck-default-trait-impl-precedence.rs32
2 files changed, 33 insertions, 56 deletions
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index 9accfe7749e..14ca867a56c 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -17,18 +17,12 @@ 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 mut overlap = OverlapChecker { tcx: tcx };
+    let 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> {
@@ -128,52 +122,3 @@ 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::ItemImpl(_, ast::ImplPolarity::Positive, _, Some(ref ast_trait_ref), _, _) => {
-                let trait_ref = ty::node_id_to_trait_ref(self.tcx, ast_trait_ref.ref_id);
-                match ty::trait_default_impl(self.tcx, trait_ref.def_id) {
-                    Some(default_impl) => {
-                        match trait_ref.self_ty().sty {
-                            ty::ty_struct(..) | ty::ty_enum(..) => {},
-                            _ => {
-                                let impl_def_id = ast_util::local_def(item.id);
-                                span_err!(self.tcx.sess, self.span_of_impl(impl_def_id), E0319,
-                                          "implementations for traits providing default \
-                                           implementations are only allowed on structs and enums");
-
-                                self.report_overlap_note(impl_def_id, default_impl);
-                            }
-                        }
-                    }
-                    None => {}
-                }
-            }
-            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/typeck-default-trait-impl-precedence.rs b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
new file mode 100644
index 00000000000..e519c3f2c2f
--- /dev/null
+++ b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
@@ -0,0 +1,32 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that declaring that `&T` is `Defaulted` if `T:Signed` implies
+// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In
+// other words, the `..` impl only applies if there are no existing
+// impls whose types unify.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait Defaulted : MarkerTrait { }
+impl Defaulted for .. { }
+impl<'a,T:Signed> Defaulted for &'a T { }
+impl<'a,T:Signed> Defaulted for &'a mut T { }
+fn is_defaulted<T:Defaulted>() { }
+
+trait Signed : MarkerTrait { }
+impl Signed for i32 { }
+
+fn main() {
+    is_defaulted::<&'static i32>();
+    is_defaulted::<&'static u32>();
+}