return r;
}
+ if tcx.impl_always_allowed_to_overlap(impl1_def_id)
+ && tcx.impl_always_allowed_to_overlap(impl2_def_id) {
+ return true;
+ }
+
// The feature gate should prevent introducing new specializations, but not
// taking advantage of upstream ones.
if !tcx.sess.features.borrow().specialization &&
possible_sibling,
impl_def_id);
if let Some(impl_header) = overlap {
+ if tcx.impl_always_allowed_to_overlap(impl_def_id)
+ && tcx.impl_always_allowed_to_overlap(possible_sibling) {
+ return Ok((true, true));
+ }
+
let le = specializes(tcx, impl_def_id, possible_sibling);
let ge = specializes(tcx, possible_sibling, impl_def_id);
queries::impl_trait_ref::get(self, DUMMY_SP, id)
}
+ /// Returns true if the impl is positive and is for a triat which contains
+ /// no items
+ pub fn impl_always_allowed_to_overlap(self, def_id: DefId) -> bool {
+ self.trait_impl_polarity(def_id) == hir::ImplPolarity::Positive
+ && self.impl_trait_ref(def_id)
+ .map_or(false, |trait_ref| {
+ self.associated_item_def_ids(trait_ref.def_id).is_empty()
+ })
+ }
+
// Returns `ty::VariantDef` if `def` refers to a struct,
// or variant or their constructors, panics otherwise.
pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-trait MyTrait {}
+trait MyTrait { fn foo() {} }
impl Drop for MyTrait {
//~^ ERROR E0120
//~^ ERROR conflicting implementations of trait `std::marker::Send`
unsafe impl<T:'static> Send for TestType<T> {}
-//~^ ERROR conflicting implementations of trait `std::marker::Send`
impl !Send for TestType<i32> {}
+//~^ ERROR conflicting implementations of trait `std::marker::Send`
fn main() {}
#![feature(optin_builtin_traits)]
-trait MyTrait {}
+trait MyTrait { fn foo() {} }
impl MyTrait for .. {}
//~^ ERROR redundant default implementations of trait `MyTrait`
unsafe impl Send for &'static [NotSync] {}
//~^ ERROR E0117
-//~| ERROR E0119
fn main() {
}
// Test that you cannot *directly* dispatch on lifetime requirements
-trait MyTrait {}
+trait MyTrait { fn foo() {} }
impl<T> MyTrait for T {}
impl<T: 'static> MyTrait for T {} //~ ERROR E0119
// Seems pretty basic, but then there was issue #24241. :)
trait From<U> {
+ fn foo() {}
}
impl <T> From<T> for T {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-trait Foo {}
+trait Foo { fn foo() {} }
impl<T> Foo for T {}
impl<U> Foo for U {} //~ ERROR conflicting implementations of trait `Foo`:
-trait Bar {}
+trait Bar { fn bar() {} }
impl<T> Bar for (T, u8) {}
impl<T> Bar for (u8, T) {} //~ ERROR conflicting implementations of trait `Bar` for type `(u8, u8)`:
-trait Baz<T> {}
+trait Baz<T> { fn baz() {} }
impl<T> Baz<u8> for T {}
impl<T> Baz<T> for u8 {} //~ ERROR conflicting implementations of trait `Baz<u8>` for type `u8`:
-trait Quux<U, V> {}
+trait Quux<U, V> { fn quux() {} }
impl<T, U, V> Quux<U, V> for T {}
impl<T, U> Quux<U, U> for T {} //~ ERROR conflicting implementations of trait `Quux<_, _>`:
// due to the orphan rules. Therefore, `A::Item` may yet turn out to
// be `i32`.
-pub trait Foo<P> {}
+pub trait Foo<P> { fn foo() {} }
pub trait Bar {
type Output: 'static;
use std::marker::PhantomData;
-pub trait Foo<P> {}
+pub trait Foo<P> { fn foo() {} }
impl <P, T: Foo<P>> Foo<P> for Option<T> {}
use std::marker::PhantomData;
-pub trait Foo<P> {}
+pub trait Foo<P> { fn foo() {} }
pub trait Bar {
type Output: 'static;
struct MyType { x: i32 }
-trait MyTrait { }
+trait MyTrait { fn foo() {} }
impl<T: lib::MyCopy> MyTrait for T { }
// `MyFundamentalStruct` is declared fundamental, so we can test that
struct MyType { x: i32 }
-trait MyTrait { }
+trait MyTrait { fn foo() {} }
impl<T: lib::MyCopy> MyTrait for T { }
// `MyFundamentalStruct` is declared fundamental, so we can test that
struct MyType { x: i32 }
-trait MyTrait { }
+trait MyTrait { fn foo() {} }
impl<T: lib::MyCopy> MyTrait for T { }
struct MyType { x: i32 }
-trait MyTrait { }
+trait MyTrait { fn foo() {} }
impl<T: lib::MyCopy> MyTrait for T { }
// `MyStruct` is not declared fundamental, therefore this would
struct MyType { x: i32 }
-trait MyTrait { }
+trait MyTrait { fn foo() {} }
impl<T: lib::MyCopy> MyTrait for T { }
// Tuples are not fundamental, therefore this would require that
#![feature(specialization)]
-trait Foo {}
+trait Foo { fn foo() {} }
impl<T: Clone> Foo for T {}
impl<T> Foo for Vec<T> {} //~ ERROR E0119
-trait Bar {}
+trait Bar { fn bar() {} }
impl<T> Bar for (T, u8) {}
impl<T> Bar for (u8, T) {} //~ ERROR E0119
-trait Baz<U> {}
+trait Baz<U> { fn baz() {} }
impl<T> Baz<T> for u8 {}
impl<T> Baz<u8> for T {} //~ ERROR E0119
-trait Qux {}
+trait Qux { fn qux() {} }
impl<T: Clone> Qux for T {}
impl<T: Eq> Qux for T {} //~ ERROR E0119
--- /dev/null
+// Copyright 2017 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.
+
+trait MyMarker {}
+
+impl<T: Copy> MyMarker for T {}
+impl<T: Eq> MyMarker for T {}
+
+fn foo<T: MyMarker>(t: T) -> T {
+ t
+}
+
+fn main() {
+ assert_eq!(1, foo(1));
+ assert_eq!(vec![1], foo(vec![1]));
+}