support default impl for specialization

a `default impl` need not include all items from the trait
    a `default impl` alone does not mean that a type implements the trait
This commit is contained in:
Gianni Ciccarelli 2017-10-12 17:38:44 +00:00
parent 29c8276cee
commit f5c55ff379
30 changed files with 870 additions and 33 deletions

View file

@ -0,0 +1,16 @@
// 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.
#![feature(specialization)]
pub trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str;
}

View file

@ -0,0 +1,22 @@
// 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.
#![feature(specialization)]
pub trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str;
}
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic"
}
}

View file

@ -0,0 +1,23 @@
// 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:foo_trait_default_impl.rs
#![feature(specialization)]
extern crate foo_trait_default_impl;
use foo_trait_default_impl::*;
struct MyStruct;
fn main() {
MyStruct.foo_two(); //~ NOTE the function call is here
}

View file

@ -0,0 +1,30 @@
// 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:foo_trait.rs
#![feature(specialization)]
extern crate foo_trait;
use foo_trait::{Foo};
struct MyStruct;
default impl Foo for MyStruct {
fn foo_one(&self) -> &'static str {
"generic"
}
}
//~^^^^^ HELP implement it inside this `default impl`
fn main() {
MyStruct.foo_two(); //~ NOTE the function call is here
}

View file

@ -0,0 +1,30 @@
// 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.
#![feature(specialization)]
trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str;
}
//~^^^^ HELP provide a default method implementation inside this `trait`
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic"
}
}
//~^^^^^ HELP implement it inside this `default impl`
struct MyStruct;
fn main() {
MyStruct.foo_two(); //~ NOTE the function call is here
}

View file

@ -0,0 +1,47 @@
// 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.
// error-pattern: the trait bound `MyStruct: Draw` is not satisfied
#![feature(specialization)]
trait Draw {
fn draw(&self);
fn draw2(&self);
}
struct Screen {
pub components: Vec<Box<Draw>>,
}
impl Screen {
pub fn run(&self) {
for component in self.components.iter() {
component.draw();
}
}
}
default impl<T> Draw for T {
fn draw(&self) {
println!("draw");
}
}
struct MyStruct;
fn main() {
let screen = Screen {
components: vec![
Box::new(MyStruct)
]
};
screen.run();
}

View file

@ -0,0 +1,34 @@
// 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.
// error-pattern: the trait bound `MyStruct: Foo` is not satisfied
#![feature(specialization)]
trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str;
}
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic"
}
}
fn foo<T: Foo>(x: T) -> &'static str {
x.foo_one()
}
struct MyStruct;
fn main() {
println!("{:?}", foo(MyStruct));
}

View file

@ -0,0 +1,38 @@
// 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.
// error-pattern: the trait bound `MyStruct: Foo` is not satisfied
#![feature(specialization)]
trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str;
}
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic"
}
}
struct FooS;
impl FooS{
fn foo<T: Foo>(&self, x: T) -> &'static str{
x.foo_one()
}
}
struct MyStruct;
fn main() {
println!("{:?}", FooS.foo(MyStruct));
}

View file

@ -0,0 +1,40 @@
// 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.
// error-pattern: the trait bound `MyStruct: SuperFoo` is not satisfied
#![feature(specialization)]
trait SuperFoo {
fn super_foo_one(&self) -> &'static str;
fn super_foo_two(&self) -> &'static str;
}
trait Foo: SuperFoo {
fn foo(&self) -> &'static str;
}
default impl<T> SuperFoo for T {
fn super_foo_one(&self) -> &'static str {
"generic"
}
}
struct MyStruct;
impl Foo for MyStruct {
fn foo(&self) -> &'static str {
"foo"
}
}
fn main() {
println!("{:?}", MyStruct.foo());
}

View file

@ -0,0 +1,34 @@
// 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.
#![feature(specialization)]
trait Foo<T> {
fn dummy(&self, t: T);
}
trait Bar<A> {
fn method<B>(&self) where A: Foo<B>;
}
struct S;
struct X;
default impl Foo<X> for X {}
impl Bar<X> for isize {
fn method<U>(&self) where X: Foo<U> {
}
}
fn main() {
1.method::<X>();
//~^ ERROR the trait bound `X: Foo<X>` is not satisfied
}

View file

@ -0,0 +1,48 @@
// 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.
// error-pattern: the trait bound `MyStruct: Draw` is not satisfied
#![feature(specialization)]
trait Draw {
fn draw(&self);
fn draw2(&self);
}
struct Screen<T: Draw> {
pub components: Vec<T>,
}
impl<T> Screen<T>
where T: Draw {
pub fn run(&self) {
for component in self.components.iter() {
component.draw();
}
}
}
default impl Draw for MyStruct {
fn draw(&self) {
println!("draw");
}
}
struct MyStruct;
fn main() {
let screen = Screen {
components: vec![
MyStruct
]
};
screen.run();
}

View file

@ -0,0 +1,30 @@
// 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.
#![feature(specialization)]
pub trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str {
"generic Trait"
}
}
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic"
}
}
default impl<T: Clone> Foo for T {
fn foo_two(&self) -> &'static str {
"generic Clone"
}
}

View file

@ -0,0 +1,40 @@
// 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.
#![feature(specialization)]
trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str;
}
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic one"
}
fn foo_two(&self) -> &'static str {
"generic two"
}
}
fn foo_one<T: Foo>(x: T) -> &'static str {
x.foo_one()
}
fn foo_two<T: Foo>(x: T) -> &'static str {
x.foo_two()
}
struct MyStruct;
fn main() {
assert!(foo_one(MyStruct) == "generic one");
assert!(foo_two(MyStruct) == "generic two");
}

View file

@ -0,0 +1,25 @@
// 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:foo_trait.rs
#![feature(specialization)]
extern crate foo_trait;
use foo_trait::*;
struct MyStruct;
fn main() {
assert!(MyStruct.foo_one() == "generic");
assert!(0u8.foo_two() == "generic Clone");
assert!(MyStruct.foo_two() == "generic Trait");
}

View file

@ -0,0 +1,38 @@
// 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.
#![feature(specialization)]
trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str {
"generic Trait"
}
}
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic"
}
}
default impl<T: Clone> Foo for T {
fn foo_two(&self) -> &'static str {
"generic Clone"
}
}
struct MyStruct;
fn main() {
assert!(MyStruct.foo_one() == "generic");
assert!(0u8.foo_two() == "generic Clone");
assert!(MyStruct.foo_two() == "generic Trait");
}

View file

@ -0,0 +1,35 @@
// 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.
#![feature(specialization)]
trait Foo {
fn foo_one(&self) -> &'static str;
fn foo_two(&self) -> &'static str;
}
default impl<T> Foo for T {
fn foo_one(&self) -> &'static str {
"generic"
}
}
default impl<T: Clone> Foo for T {
fn foo_two(&self) -> &'static str {
"generic Clone"
}
}
struct MyStruct;
fn main() {
assert!(MyStruct.foo_one() == "generic");
assert!(0u8.foo_two() == "generic Clone");
}