Skip to content

Commit

Permalink
Forbid cross-polarity specializations
Browse files Browse the repository at this point in the history
  • Loading branch information
aturon committed Mar 14, 2016
1 parent 2651f8c commit 386f8ee
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
6 changes: 6 additions & 0 deletions src/librustc/middle/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
22 changes: 13 additions & 9 deletions ...pile-fail/specialization-negative-impl.rs → ...t/compile-fail/specialization-polarity.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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>(T);
trait Foo {}

impl Foo for .. {}

impl<T> Foo for T {}
impl !Foo for u8 {} //~ ERROR E0119

// TODO: nail down the rules here with @nikomatsakis
trait Bar {}

unsafe impl<T> Send for TestType<T> {}
impl !Send for TestType<u8> {}
impl Bar for .. {}

fn assert_send<T: Send>() {}
impl<T> !Bar for T {}
impl Bar for u8 {} //~ ERROR E0119

fn main() {
assert_send::<TestType<()>>();
assert_send::<TestType<u8>>(); //~ ERROR
}
fn main() {}

0 comments on commit 386f8ee

Please sign in to comment.