Skip to content

Commit

Permalink
Various adjustments to historic tests and documents.
Browse files Browse the repository at this point in the history
  • Loading branch information
crlf0710 committed Aug 2, 2021
1 parent a144333 commit 3cb625e
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 198 deletions.
13 changes: 7 additions & 6 deletions src/doc/unstable-book/src/language-features/trait-upcasting.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# `trait_upcasting`

The tracking issue for this feature is: [#31436]
The tracking issue for this feature is: [#65991]

[#65991]: https://github.com/rust-lang/rust/issues/65991

------------------------

The `trait_upcasting` feature adds support for trait upcasting. This allows a
trait object of type `dyn Foo` to be cast to a trait object of type `dyn Bar`
so long as `Foo: Bar`.
The `trait_upcasting` feature adds support for trait upcasting coercion. This allows a
trait object of type `dyn Bar` to be cast to a trait object of type `dyn Foo`
so long as `Bar: Foo`.

```rust,edition2018
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo {}
Expand All @@ -21,6 +22,6 @@ impl Foo for i32 {}
impl<T: Foo + ?Sized> Bar for T {}
let foo: &dyn Foo = &123;
let bar: &dyn Bar = foo;
let bar: &dyn Bar = &123;
let foo: &dyn Foo = bar;
```
49 changes: 28 additions & 21 deletions src/test/ui/traits/trait-upcasting/basic.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,59 @@
// run-pass

#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 { 10 }
fn a(&self) -> i32 {
10
}

fn z(&self) -> i32 { 11 }
fn z(&self) -> i32 {
11
}

fn y(&self) -> i32 { 12 }
fn y(&self) -> i32 {
12
}
}

trait Bar: Foo {
fn b(&self) -> i32 { 20 }
fn b(&self) -> i32 {
20
}

fn w(&self) -> i32 { 21 }
fn w(&self) -> i32 {
21
}
}

trait Baz: Bar {
fn c(&self) -> i32 { 30 }
fn c(&self) -> i32 {
30
}
}

impl Foo for i32 {
fn a(&self) -> i32 { 100 }
fn a(&self) -> i32 {
100
}
}

impl Bar for i32 {
fn b(&self) -> i32 { 200 }
fn b(&self) -> i32 {
200
}
}

impl Baz for i32 {
fn c(&self) -> i32 { 300 }
fn c(&self) -> i32 {
300
}
}

fn main() {
let baz: &dyn Baz = &1;
let _: &dyn std::fmt::Debug = baz;
let _: &(dyn Send + Sync) = baz;
let _: &dyn Send = baz;
let _: &dyn Sync = baz;
assert_eq!(*baz, 1);
assert_eq!(baz.a(), 100);
assert_eq!(baz.b(), 200);
Expand All @@ -48,9 +64,6 @@ fn main() {

let bar: &dyn Bar = baz;
let _: &dyn std::fmt::Debug = bar;
let _: &(dyn Send + Sync) = bar;
let _: &dyn Send = bar;
let _: &dyn Sync = bar;
assert_eq!(*bar, 1);
assert_eq!(bar.a(), 100);
assert_eq!(bar.b(), 200);
Expand All @@ -60,19 +73,13 @@ fn main() {

let foo: &dyn Foo = baz;
let _: &dyn std::fmt::Debug = foo;
let _: &(dyn Send + Sync) = foo;
let _: &dyn Send = foo;
let _: &dyn Sync = foo;
assert_eq!(*foo, 1);
assert_eq!(foo.a(), 100);
assert_eq!(foo.z(), 11);
assert_eq!(foo.y(), 12);

let foo: &dyn Foo = bar;
let _: &dyn std::fmt::Debug = foo;
let _: &(dyn Send + Sync) = foo;
let _: &dyn Send = foo;
let _: &dyn Sync = foo;
assert_eq!(*foo, 1);
assert_eq!(foo.a(), 100);
assert_eq!(foo.z(), 11);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
trait A: B + A {}
//~^ ERROR cycle detected when computing the supertraits of `A` [E0391]
//~^ ERROR cycle detected when computing the super predicates of `A` [E0391]

trait B {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
error[E0391]: cycle detected when computing the supertraits of `A`
error[E0391]: cycle detected when computing the super predicates of `A`
--> $DIR/cyclic-trait-resolution.rs:1:1
|
LL | trait A: B + A {}
| ^^^^^^^^^^^^^^
|
note: ...which requires computing the super traits of `A`...
--> $DIR/cyclic-trait-resolution.rs:1:14
|
LL | trait A: B + A {}
| ^
|
= note: ...which again requires computing the supertraits of `A`, completing the cycle
= note: ...which again requires computing the super predicates of `A`, completing the cycle
note: cycle used when collecting item types in top-level module
--> $DIR/cyclic-trait-resolution.rs:1:1
|
Expand Down
67 changes: 37 additions & 30 deletions src/test/ui/traits/trait-upcasting/diamond.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,75 @@
// run-pass

#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 { 10 }
fn a(&self) -> i32 {
10
}

fn z(&self) -> i32 { 11 }
fn z(&self) -> i32 {
11
}

fn y(&self) -> i32 { 12 }
fn y(&self) -> i32 {
12
}
}

trait Bar1: Foo {
fn b(&self) -> i32 { 20 }
fn b(&self) -> i32 {
20
}

fn w(&self) -> i32 { 21 }
fn w(&self) -> i32 {
21
}
}

trait Bar2: Foo {
fn c(&self) -> i32 { 30 }
fn c(&self) -> i32 {
30
}

fn v(&self) -> i32 { 31 }
fn v(&self) -> i32 {
31
}
}

trait Baz: Bar1 + Bar2 {
fn d(&self) -> i32 { 40 }
fn d(&self) -> i32 {
40
}
}

impl Foo for i32 {
fn a(&self) -> i32 { 100 }
fn a(&self) -> i32 {
100
}
}

impl Bar1 for i32 {
fn b(&self) -> i32 { 200 }
fn b(&self) -> i32 {
200
}
}

impl Bar2 for i32 {
fn c(&self) -> i32 { 300 }
fn c(&self) -> i32 {
300
}
}

impl Baz for i32 {
fn d(&self) -> i32 { 400 }
fn d(&self) -> i32 {
400
}
}

fn main() {
let baz: &dyn Baz = &1;
let _: &dyn std::fmt::Debug = baz;
let _: &(dyn Send + Sync) = baz;
let _: &dyn Send = baz;
let _: &dyn Sync = baz;
assert_eq!(*baz, 1);
assert_eq!(baz.a(), 100);
assert_eq!(baz.b(), 200);
Expand All @@ -60,9 +82,6 @@ fn main() {

let bar1: &dyn Bar1 = baz;
let _: &dyn std::fmt::Debug = bar1;
let _: &(dyn Send + Sync) = bar1;
let _: &dyn Send = bar1;
let _: &dyn Sync = bar1;
assert_eq!(*bar1, 1);
assert_eq!(bar1.a(), 100);
assert_eq!(bar1.b(), 200);
Expand All @@ -72,9 +91,6 @@ fn main() {

let bar2: &dyn Bar2 = baz;
let _: &dyn std::fmt::Debug = bar2;
let _: &(dyn Send + Sync) = bar2;
let _: &dyn Send = bar2;
let _: &dyn Sync = bar2;
assert_eq!(*bar2, 1);
assert_eq!(bar2.a(), 100);
assert_eq!(bar2.c(), 300);
Expand All @@ -84,25 +100,16 @@ fn main() {

let foo: &dyn Foo = baz;
let _: &dyn std::fmt::Debug = foo;
let _: &(dyn Send + Sync) = foo;
let _: &dyn Send = foo;
let _: &dyn Sync = foo;
assert_eq!(*foo, 1);
assert_eq!(foo.a(), 100);

let foo: &dyn Foo = bar1;
let _: &dyn std::fmt::Debug = foo;
let _: &(dyn Send + Sync) = foo;
let _: &dyn Send = foo;
let _: &dyn Sync = foo;
assert_eq!(*foo, 1);
assert_eq!(foo.a(), 100);

let foo: &dyn Foo = bar2;
let _: &dyn std::fmt::Debug = foo;
let _: &(dyn Send + Sync) = foo;
let _: &dyn Send = foo;
let _: &dyn Sync = foo;
assert_eq!(*foo, 1);
assert_eq!(foo.a(), 100);
}
Loading

0 comments on commit 3cb625e

Please sign in to comment.