Skip to content

Commit

Permalink
Add basic specialization tests, including for default item
Browse files Browse the repository at this point in the history
inheritance. Updates some of the coherence tests as well.
  • Loading branch information
aturon committed Mar 14, 2016
1 parent 7e42a78 commit 1077ff2
Show file tree
Hide file tree
Showing 15 changed files with 570 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/test/auxiliary/go_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ pub fn go_once<G:GoOnce>(this: G, arg: isize) {
impl<G> GoMut for G
where G : Go
{
fn go_mut(&mut self, arg: isize) {
default fn go_mut(&mut self, arg: isize) {
go(&*self, arg)
}
}

impl<G> GoOnce for G
where G : GoMut
{
fn go_once(mut self, arg: isize) {
default fn go_once(mut self, arg: isize) {
go_mut(&mut self, arg)
}
}
80 changes: 80 additions & 0 deletions src/test/auxiliary/specialization_cross_crate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2015 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.

pub trait Foo {
fn foo(&self) -> &'static str;
}

impl<T> Foo for T {
default fn foo(&self) -> &'static str {
"generic"
}
}

impl<T: Clone> Foo for T {
default fn foo(&self) -> &'static str {
"generic Clone"
}
}

impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
default fn foo(&self) -> &'static str {
"generic pair"
}
}

impl<T: Clone> Foo for (T, T) {
default fn foo(&self) -> &'static str {
"generic uniform pair"
}
}

impl Foo for (u8, u32) {
default fn foo(&self) -> &'static str {
"(u8, u32)"
}
}

impl Foo for (u8, u8) {
default fn foo(&self) -> &'static str {
"(u8, u8)"
}
}

impl<T: Clone> Foo for Vec<T> {
default fn foo(&self) -> &'static str {
"generic Vec"
}
}

impl Foo for Vec<i32> {
fn foo(&self) -> &'static str {
"Vec<i32>"
}
}

impl Foo for String {
fn foo(&self) -> &'static str {
"String"
}
}

impl Foo for i32 {
fn foo(&self) -> &'static str {
"i32"
}
}

pub trait MyMarker {}
impl<T: Clone + MyMarker> Foo for T {
default fn foo(&self) -> &'static str {
"generic Clone + MyMarker"
}
}
49 changes: 49 additions & 0 deletions src/test/auxiliary/specialization_cross_crate_defaults.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2015 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.


#![feature(specialization)]

// First, test only use of explicit `default` items:

pub trait Foo {
fn foo(&self) -> bool;
}

impl<T> Foo for T {
default fn foo(&self) -> bool { false }
}

impl Foo for i32 {}

impl Foo for i64 {
fn foo(&self) -> bool { true }
}

// Next, test mixture of explicit `default` and provided methods:

pub trait Bar {
fn bar(&self) -> i32 { 0 }
}

impl<T> Bar for T {} // use the provided method

impl Bar for i32 {
fn bar(&self) -> i32 { 1 }
}
impl<'a> Bar for &'a str {}

impl<T> Bar for Vec<T> {
default fn bar(&self) -> i32 { 2 }
}
impl Bar for Vec<i32> {}
impl Bar for Vec<i64> {
fn bar(&self) -> i32 { 3 }
}
18 changes: 18 additions & 0 deletions src/test/compile-fail/coherence-no-direct-lifetime-dispatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2015 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.

// Test that you cannot *directly* dispatch on lifetime requirements

trait MyTrait {}

impl<T> MyTrait for T {}
impl<T: 'static> MyTrait for T {} //~ ERROR E0119

fn main() {}
24 changes: 7 additions & 17 deletions src/test/compile-fail/coherence-overlap-messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,18 @@ impl<U> Foo for U {}

trait Bar {}

impl<T> Bar for T {} //~ ERROR conflicting implementations of trait `Bar` for type `u8`:
impl Bar for u8 {}
impl<T> Bar for (T, u8) {} //~ ERROR conflicting implementations of trait `Bar` for type `(u8, u8)`:
impl<T> Bar for (u8, T) {}

trait Baz<T> {}

impl<T, U> Baz<U> for T {} //~ ERROR conflicting implementations of trait `Baz<_>` for type `u8`:
impl<T> Baz<u8> for T {} //~ ERROR conflicting implementations of trait `Baz<u8>` for type `u8`:
impl<T> Baz<T> for u8 {}

trait Quux<T> {}
trait Quux<U, V> {}

impl<T, U> Quux<U> for T {} //~ ERROR conflicting implementations of trait `Quux<_>`:
impl<T> Quux<T> for T {}

trait Qaar<T> {}

impl<T, U> Qaar<U> for T {} //~ ERROR conflicting implementations of trait `Qaar<u8>`:
impl<T> Qaar<u8> for T {}

trait Qaax<T> {}

impl<T, U> Qaax<U> for T {}
//~^ ERROR conflicting implementations of trait `Qaax<u8>` for type `u32`:
impl Qaax<u8> for u32 {}
impl<T, U, V> Quux<U, V> for T {} //~ ERROR conflicting implementations of trait `Quux<_, _>`:
impl<T, U> Quux<U, U> for T {}
impl<T, V> Quux<T, V> for T {}

fn main() {}
23 changes: 23 additions & 0 deletions src/test/compile-fail/specialization-negative-impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2015 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.

#![feature(optin_builtin_traits)]

struct TestType<T>(T);

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

fn assert_send<T: Send>() {}

fn main() {
assert_send::<TestType<()>>();
assert_send::<TestType<u8>>(); //~ ERROR
}
20 changes: 20 additions & 0 deletions src/test/compile-fail/specialization-overlap-negative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2015 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.

#![feature(optin_builtin_traits)]

trait MyTrait {}

struct TestType<T>(::std::marker::PhantomData<T>);

unsafe impl<T: Clone> Send for TestType<T> {}
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0119

fn main() {}
23 changes: 23 additions & 0 deletions src/test/compile-fail/specialization-overlap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2015 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 Foo {}
impl<T: Clone> Foo for T {}
impl<T> Foo for Vec<T> {} //~ ERROR E0119

trait Bar {}
impl<T> Bar for (T, u8) {}
impl<T> Bar for (u8, T) {} //~ ERROR E0119

trait Baz<U> {}
impl<T> Baz<T> for u8 {}
impl<T> Baz<u8> for T {} //~ ERROR E0119

fn main() {}
29 changes: 29 additions & 0 deletions src/test/run-pass/specialization-allowed-cross-crate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2014 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.

// aux-build:go_trait.rs

extern crate go_trait;

use go_trait::{Go,GoMut};
use std::fmt::Debug;
use std::default::Default;

struct MyThingy;

impl Go for MyThingy {
fn go(&self, arg: isize) { }
}

impl GoMut for MyThingy {
fn go_mut(&mut self, arg: isize) { }
}

fn main() { }
33 changes: 33 additions & 0 deletions src/test/run-pass/specialization-assoc-fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2015 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 Foo {
fn mk() -> Self;
}

impl<T: Default> Foo for T {
default fn mk() -> T {
T::default()
}
}

impl Foo for Vec<u8> {
fn mk() -> Vec<u8> {
vec![0]
}
}

fn main() {
let v1: Vec<i32> = Foo::mk();
let v2: Vec<u8> = Foo::mk();

assert!(v1.len() == 0);
assert!(v2.len() == 1);
}
Loading

0 comments on commit 1077ff2

Please sign in to comment.