Skip to content

Commit 386f8ee

Browse files
committed
Forbid cross-polarity specializations
1 parent 2651f8c commit 386f8ee

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

src/librustc/middle/traits/specialize/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub struct Overlap<'a, 'tcx: 'a> {
4141
/// Given a subst for the requested impl, translate it to a subst
4242
/// appropriate for the actual item definition (whether it be in that impl,
4343
/// a parent impl, or the trait).
44+
//
4445
// When we have selected one impl, but are actually using item definitions from
4546
// a parent impl providing a default, we need a way to translate between the
4647
// 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) ->
153154
//
154155
// See RFC 1210 for more details and justification.
155156

157+
// Currently we do not allow e.g. a negative impl to specialize a positive one
158+
if tcx.trait_impl_polarity(impl1_def_id) != tcx.trait_impl_polarity(impl2_def_id) {
159+
return false
160+
}
161+
156162
let mut infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
157163

158164
// Skiolemize impl1: we want to prove that "for all types matched by impl1,

src/test/compile-fail/specialization-negative-impl.rs renamed to src/test/compile-fail/specialization-polarity.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,23 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// Make sure specialization cannot change impl polarity
12+
1113
#![feature(optin_builtin_traits)]
1214
#![feature(specialization)]
1315

14-
struct TestType<T>(T);
16+
trait Foo {}
17+
18+
impl Foo for .. {}
19+
20+
impl<T> Foo for T {}
21+
impl !Foo for u8 {} //~ ERROR E0119
1522

16-
// TODO: nail down the rules here with @nikomatsakis
23+
trait Bar {}
1724

18-
unsafe impl<T> Send for TestType<T> {}
19-
impl !Send for TestType<u8> {}
25+
impl Bar for .. {}
2026

21-
fn assert_send<T: Send>() {}
27+
impl<T> !Bar for T {}
28+
impl Bar for u8 {} //~ ERROR E0119
2229

23-
fn main() {
24-
assert_send::<TestType<()>>();
25-
assert_send::<TestType<u8>>(); //~ ERROR
26-
}
30+
fn main() {}

0 commit comments

Comments
 (0)