mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-12 00:24:03 +00:00
d301f40c84
For example, if `trait Foo: Bar`, and we try to call a method from `Bar` on `dyn Foo`, encode the callsite as passing a `dyn Bar`, not a `dyn Foo`.
74 lines
1.5 KiB
Rust
74 lines
1.5 KiB
Rust
#![feature(trait_upcasting)]
|
|
// Check that super-traits are callable.
|
|
|
|
//@ revisions: cfi kcfi
|
|
// FIXME(#122848) Remove only-linux once OSX CFI binaries work
|
|
//@ only-linux
|
|
//@ [cfi] needs-sanitizer-cfi
|
|
//@ [kcfi] needs-sanitizer-kcfi
|
|
//@ compile-flags: -C target-feature=-crt-static
|
|
//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
|
|
//@ [cfi] compile-flags: -Z sanitizer=cfi
|
|
//@ [kcfi] compile-flags: -Z sanitizer=kcfi
|
|
//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off
|
|
//@ run-pass
|
|
|
|
trait Parent1 {
|
|
type P1;
|
|
fn p1(&self) -> Self::P1;
|
|
}
|
|
|
|
trait Parent2 {
|
|
type P2;
|
|
fn p2(&self) -> Self::P2;
|
|
}
|
|
|
|
trait Child : Parent1 + Parent2 {
|
|
type C;
|
|
fn c(&self) -> Self::C;
|
|
}
|
|
|
|
struct Foo;
|
|
|
|
impl Parent1 for Foo {
|
|
type P1 = u16;
|
|
fn p1(&self) -> Self::P1 {
|
|
println!("p1");
|
|
1
|
|
}
|
|
}
|
|
|
|
impl Parent2 for Foo {
|
|
type P2 = u32;
|
|
fn p2(&self) -> Self::P2 {
|
|
println!("p2");
|
|
2
|
|
}
|
|
}
|
|
|
|
impl Child for Foo {
|
|
type C = u8;
|
|
fn c(&self) -> Self::C {
|
|
println!("c");
|
|
0
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
// Child can access its own methods and super methods.
|
|
let x = &Foo as &dyn Child<C=u8,P1=u16,P2=u32>;
|
|
x.c();
|
|
x.p1();
|
|
x.p2();
|
|
// Parents can be created and access their methods.
|
|
let y = &Foo as &dyn Parent1<P1=u16>;
|
|
y.p1();
|
|
let z = &Foo as &dyn Parent2<P2=u32>;
|
|
z.p2();
|
|
// Trait upcasting works
|
|
let x1 = x as &dyn Parent1<P1=u16>;
|
|
x1.p1();
|
|
let x2 = x as &dyn Parent2<P2=u32>;
|
|
x2.p2();
|
|
}
|