diff --git a/src/librustc/middle/traits/specialize/mod.rs b/src/librustc/middle/traits/specialize/mod.rs index 5939128719c0..6fd61741268b 100644 --- a/src/librustc/middle/traits/specialize/mod.rs +++ b/src/librustc/middle/traits/specialize/mod.rs @@ -41,6 +41,7 @@ pub struct Overlap<'a, 'tcx: 'a> { /// Given a subst for the requested impl, translate it to a subst /// appropriate for the actual item definition (whether it be in that impl, /// a parent impl, or the trait). +// // When we have selected one impl, but are actually using item definitions from // a parent impl providing a default, we need a way to translate between the // type parameters of the two impls. Here the `source_impl` is the one we've @@ -153,6 +154,11 @@ pub fn specializes(tcx: &ty::ctxt, impl1_def_id: DefId, impl2_def_id: DefId) -> // // See RFC 1210 for more details and justification. + // Currently we do not allow e.g. a negative impl to specialize a positive one + if tcx.trait_impl_polarity(impl1_def_id) != tcx.trait_impl_polarity(impl2_def_id) { + return false + } + let mut infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); // Skiolemize impl1: we want to prove that "for all types matched by impl1, diff --git a/src/test/compile-fail/specialization-negative-impl.rs b/src/test/compile-fail/specialization-polarity.rs old mode 100644 new mode 100755 similarity index 66% rename from src/test/compile-fail/specialization-negative-impl.rs rename to src/test/compile-fail/specialization-polarity.rs index 9aec614012e4..27a3e31491b8 --- a/src/test/compile-fail/specialization-negative-impl.rs +++ b/src/test/compile-fail/specialization-polarity.rs @@ -8,19 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Make sure specialization cannot change impl polarity + #![feature(optin_builtin_traits)] #![feature(specialization)] -struct TestType(T); +trait Foo {} -// TODO: nail down the rules here with @nikomatsakis +impl Foo for .. {} -unsafe impl Send for TestType {} -impl !Send for TestType {} +impl Foo for T {} +impl !Foo for u8 {} //~ ERROR E0119 -fn assert_send() {} +trait Bar {} -fn main() { - assert_send::>(); - assert_send::>(); //~ ERROR -} +impl Bar for .. {} + +impl !Bar for T {} +impl Bar for u8 {} //~ ERROR E0119 + +fn main() {}