mirror of https://github.com/rust-lang/rust
62 lines
1.7 KiB
Rust
62 lines
1.7 KiB
Rust
//@ run-pass
|
|
#![feature(arbitrary_self_types)]
|
|
|
|
use std::ptr;
|
|
|
|
trait Foo {
|
|
fn foo(self: *const Self) -> &'static str;
|
|
|
|
unsafe fn bar(self: *const Self) -> i64;
|
|
|
|
unsafe fn complicated(self: *const *const Self) -> i64 where Self: Sized {
|
|
(*self).bar()
|
|
}
|
|
}
|
|
|
|
impl Foo for i32 {
|
|
fn foo(self: *const Self) -> &'static str {
|
|
"I'm an i32!"
|
|
}
|
|
|
|
unsafe fn bar(self: *const Self) -> i64 {
|
|
*self as i64
|
|
}
|
|
}
|
|
|
|
impl Foo for u32 {
|
|
fn foo(self: *const Self) -> &'static str {
|
|
"I'm a u32!"
|
|
}
|
|
|
|
unsafe fn bar(self: *const Self) -> i64 {
|
|
*self as i64
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let null_i32 = ptr::null::<i32>() as *const dyn Foo;
|
|
let null_u32 = ptr::null::<u32>() as *const dyn Foo;
|
|
|
|
assert_eq!("I'm an i32!", null_i32.foo());
|
|
assert_eq!("I'm a u32!", null_u32.foo());
|
|
|
|
let valid_i32 = 5i32;
|
|
let valid_i32_thin = &valid_i32 as *const i32;
|
|
assert_eq!("I'm an i32!", valid_i32_thin.foo());
|
|
assert_eq!(5, unsafe { valid_i32_thin.bar() });
|
|
assert_eq!(5, unsafe { (&valid_i32_thin as *const *const i32).complicated() });
|
|
let valid_i32_fat = valid_i32_thin as *const dyn Foo;
|
|
assert_eq!("I'm an i32!", valid_i32_fat.foo());
|
|
assert_eq!(5, unsafe { valid_i32_fat.bar() });
|
|
|
|
let valid_u32 = 18u32;
|
|
let valid_u32_thin = &valid_u32 as *const u32;
|
|
assert_eq!("I'm a u32!", valid_u32_thin.foo());
|
|
assert_eq!(18, unsafe { valid_u32_thin.bar() });
|
|
assert_eq!(18, unsafe { (&valid_u32_thin as *const *const u32).complicated() });
|
|
let valid_u32_fat = valid_u32_thin as *const dyn Foo;
|
|
assert_eq!("I'm a u32!", valid_u32_fat.foo());
|
|
assert_eq!(18, unsafe { valid_u32_fat.bar() });
|
|
|
|
}
|