Skip to content

Commit e5f444d

Browse files
sgrifnikomatsakis
authored andcommitted
Put overlapping impls behind feature gate, add tests
I've added some explicit tests that negative impls are allowed to overlap, and also to make sure that the feature doesn't interfere with specialization. I've not added an explicit test for positive overlapping with negative, as that's already tested elsewhere.
1 parent c3d49c9 commit e5f444d

7 files changed

+59
-0
lines changed

src/librustc/ty/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
21612161
/// Returns true if the impls are the same polarity and are implementing
21622162
/// a trait which contains no items
21632163
pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool {
2164+
if !self.sess.features.borrow().overlapping_marker_traits {
2165+
return false;
2166+
}
21642167
let trait1_is_empty = self.impl_trait_ref(def_id1)
21652168
.map_or(false, |trait_ref| {
21662169
self.associated_item_def_ids(trait_ref.def_id).is_empty()

src/libsyntax/feature_gate.rs

+3
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ declare_features! (
342342

343343
// See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work.
344344
(active, rvalue_static_promotion, "1.15.1", Some(38865)),
345+
346+
// Allows overlapping impls of marker traits
347+
(active, overlapping_marker_traits, "1.18.0", Some(29864)),
345348
);
346349

347350
declare_features! (

src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#![feature(optin_builtin_traits)]
12+
#![feature(overlapping_marker_traits)]
1213

1314
trait MyTrait {}
1415

src/test/compile-fail/coherence-impls-send.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#![feature(optin_builtin_traits)]
12+
#![feature(overlapping_marker_traits)]
1213

1314
use std::marker::Copy;
1415

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait MyMarker {}
12+
13+
impl<T> MyMarker for T {}
14+
impl<T> MyMarker for Vec<T> {}
15+
//~^ ERROR E0119
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(overlapping_marker_traits)]
12+
#![feature(specialization)]
13+
14+
trait MyMarker {}
15+
16+
impl<T> MyMarker for T {}
17+
impl<T> MyMarker for Vec<T> {}
18+
19+
fn foo<T: MyMarker>(t: T) -> T {
20+
t
21+
}
22+
23+
fn main() {
24+
assert_eq!(1, foo(1));
25+
assert_eq!(2.0, foo(2.0));
26+
assert_eq!(vec![1], foo(vec![1]));
27+
}

src/test/run-pass/overlap-permitted-for-marker-traits.rs

+7
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(overlapping_marker_traits)]
12+
#![feature(optin_builtin_traits)]
13+
1114
trait MyMarker {}
1215

1316
impl<T: Copy> MyMarker for T {}
1417
impl<T: Eq> MyMarker for T {}
1518

19+
struct MyStruct;
20+
impl !Send for MyStruct {}
21+
impl !Send for MyStruct {}
22+
1623
fn foo<T: MyMarker>(t: T) -> T {
1724
t
1825
}

0 commit comments

Comments
 (0)