diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-02-20 13:34:13 -0500 |
|---|---|---|
| committer | Flavio Percoco <flaper87@gmail.com> | 2015-02-22 02:14:27 +0100 |
| commit | 3343e9c16976aabef9836e61213e64a0552ec051 (patch) | |
| tree | 0aed1c39affc63f07ee20e46406b866e653a26a5 | |
| parent | 6d1844c8065c5c680b0a86c83152902b47bc856c (diff) | |
| download | rust-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.rs | 57 | ||||
| -rw-r--r-- | src/test/compile-fail/typeck-default-trait-impl-precedence.rs | 32 |
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>(); +} |
