| // { dg-require-effective-target lp64 } | |
| #![feature(no_core, lang_items, intrinsics)] | |
| #![no_core] | |
| #[lang = "sized"] | |
| pub trait Sized {} | |
| #[lang = "coerce_unsized"] | |
| pub trait CoerceUnsized<T: ?Sized> { | |
| // Due to our current architecture, coercion rules are hardcoded; | |
| // therefore, this lang item is currently non-functional. | |
| } | |
| extern "rust-intrinsic" { | |
| fn size_of_val<T: ?Sized>(_: *const T) -> usize; | |
| } | |
| pub struct TailStruct<T: ?Sized> { | |
| pub a: i32, | |
| pub tail: T, | |
| } | |
| pub fn _coerce(s: &TailStruct<[i32; 3]>) -> &TailStruct<[i32]> { | |
| s as &TailStruct<[i32]> | |
| } | |
| pub trait MyTrait { | |
| fn dummy(&self) -> i32; | |
| } | |
| impl MyTrait for i64 { | |
| fn dummy(&self) -> i32 { | |
| 0 | |
| } | |
| } | |
| impl MyTrait for [i32; 3] { | |
| fn dummy(&self) -> i32 { | |
| 0 | |
| } | |
| } | |
| pub fn sovt(s: &TailStruct<dyn MyTrait>) -> usize { | |
| unsafe { size_of_val(s as *const TailStruct<dyn MyTrait>) } | |
| } | |
| pub fn sov1(s: &[i32]) -> usize { | |
| unsafe { size_of_val(s as *const [i32]) } | |
| } | |
| pub fn sov2(s: &TailStruct<[i32]>) -> usize { | |
| unsafe { size_of_val(s as *const TailStruct<[i32]>) } | |
| } | |
| pub fn sov3(s: &TailStruct<TailStruct<[i32]>>) -> usize { | |
| unsafe { size_of_val(s as *const TailStruct<TailStruct<[i32]>>) } | |
| } | |
| fn main() -> i32 { | |
| let t = [1, 2, 3]; | |
| let t1 = &t as &[i32]; | |
| let s1: TailStruct<[i32; 3]> = TailStruct { a: 10, tail: t }; | |
| let s2_tail: TailStruct<[i32; 3]> = TailStruct { a: 10, tail: t }; | |
| let s2: TailStruct<TailStruct<[i32; 3]>> = TailStruct { | |
| a: 20, | |
| tail: s2_tail, | |
| }; | |
| let a = sov1(t1); | |
| let b = sov2(&s1); | |
| let c = sov3(&s2); | |
| let d = sov1(&s1.tail); | |
| let e = sov2(&s2.tail); | |
| let s3 = TailStruct { | |
| a: 10, | |
| tail: 10_i64, | |
| }; | |
| let s4 = TailStruct { a: 20, tail: t }; | |
| let r1: &TailStruct<dyn MyTrait> = &s3; | |
| let r2: &TailStruct<dyn MyTrait> = &s4; | |
| let f = sovt(r1); | |
| let g = sovt(r2); | |
| let slice_ok = a == 12 && b == 16 && c == 20 && d == a && e == b; | |
| let trait_ok = f == 12 && g == 16; | |
| if slice_ok && trait_ok { | |
| 0 | |
| } else { | |
| 1 | |
| } | |
| } |