1 // Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
4 no_core
, unboxed_closures
, start
, lang_items
, box_syntax
, never_type
, linkage
,
5 extern_types
, thread_local
8 #![allow(dead_code, non_camel_case_types)]
10 extern crate mini_core
;
13 use mini_core
::libc
::*;
15 unsafe extern "C" fn my_puts(s
: *const u8) {
19 #[lang = "termination"]
21 fn report(self) -> i32;
24 impl Termination
for () {
25 fn report(self) -> i32 {
27 NUM
= 6 * 7 + 1 + (1u8 == 1u8) as u8; // 44
34 fn object_safe(&self);
37 impl SomeTrait
for &'
static str {
38 fn object_safe(&self) {
40 puts(*self as *const str as *const u8);
47 inner
: NoisyDropInner
,
50 struct NoisyDropUnsized
{
51 inner
: NoisyDropInner
,
55 struct NoisyDropInner
;
57 impl Drop
for NoisyDrop
{
60 puts(self.text
as *const str as *const u8);
65 impl Drop
for NoisyDropInner
{
68 puts("Inner got dropped!\0" as *const str as *const u8);
73 impl SomeTrait
for NoisyDrop
{
74 fn object_safe(&self) {}
84 fn start
<T
: Termination
+ '
static>(
87 argv
: *const *const u8,
90 unsafe { puts(*argv); }
91 unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const u8)); }
92 unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const u8)); }
99 static mut NUM
: u8 = 6 * 7;
100 static NUM_REF
: &'
static u8 = unsafe { &NUM }
;
102 macro_rules
! assert
{
105 panic(stringify
!(! $e
));
110 macro_rules
! assert_eq
{
111 ($l
:expr
, $r
: expr
) => {
113 panic(stringify
!($l
!= $r
));
118 struct Unique
<T
: ?Sized
> {
120 _marker
: PhantomData
<T
>,
123 impl<T
: ?Sized
, U
: ?Sized
> CoerceUnsized
<Unique
<U
>> for Unique
<T
> where T
: Unsize
<U
> {}
125 unsafe fn zeroed
<T
>() -> T
{
126 let mut uninit
= MaybeUninit { uninit: () }
;
127 intrinsics
::write_bytes(&mut uninit
.value
.value
as *mut T
, 0, 1);
131 fn take_f32(_f
: f32) {}
132 fn take_unique(_u
: Unique
<()>) {}
134 fn return_u128_pair() -> (u128
, u128
) {
138 fn call_return_u128_pair() {
144 pointer
: 0 as *const (),
145 _marker
: PhantomData
,
149 //call_return_u128_pair();
151 let slice
= &[0, 1] as &[i32];
152 let slice_ptr
= slice
as *const [i32] as *const i32;
154 assert_eq
!(slice_ptr
as usize % 4, 0);
159 printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8);
161 let hello
: &[u8] = b
"Hello\0" as &[u8; 6];
162 let ptr
: *const u8 = hello
as *const [u8] as *const u8;
165 let world
: Box
<&str> = box "World!\0";
166 puts(*world
as *const str as *const u8);
167 world
as Box
<dyn SomeTrait
>;
169 assert_eq
!(intrinsics
::bitreverse(0b10101000u8), 0b00010101u8);
171 assert_eq
!(intrinsics
::bswap(0xabu8), 0xabu8);
172 assert_eq
!(intrinsics
::bswap(0xddccu16), 0xccddu16);
173 assert_eq
!(intrinsics
::bswap(0xffee_ddccu32), 0xccdd_eeffu32);
174 assert_eq
!(intrinsics
::bswap(0x1234_5678_ffee_ddccu64), 0xccdd_eeff_7856_3412u64);
176 assert_eq
!(intrinsics
::size_of_val(hello
) as u8, 6);
178 let chars
= &['C'
, 'h'
, 'a'
, 'r'
, 's'
];
179 let chars
= chars
as &[char];
180 assert_eq
!(intrinsics
::size_of_val(chars
) as u8, 4 * 5);
182 let a
: &dyn SomeTrait
= &"abc\0";
185 assert_eq
!(intrinsics
::size_of_val(a
) as u8, 16);
186 assert_eq
!(intrinsics
::size_of_val(&0u32) as u8, 4);
188 assert_eq
!(intrinsics
::min_align_of
::<u16>() as u8, 2);
189 assert_eq
!(intrinsics
::min_align_of_val(&a
) as u8, intrinsics
::min_align_of
::<&str>() as u8);
191 assert
!(!intrinsics
::needs_drop
::<u8>());
192 assert
!(!intrinsics
::needs_drop
::<[u8]>());
193 assert
!(intrinsics
::needs_drop
::<NoisyDrop
>());
194 assert
!(intrinsics
::needs_drop
::<NoisyDropUnsized
>());
197 pointer
: 0 as *const &str,
198 _marker
: PhantomData
,
199 } as Unique
<dyn SomeTrait
>;
201 struct MyDst
<T
: ?Sized
>(T
);
203 intrinsics
::size_of_val(&MyDst([0u8; 4]) as &MyDst
<[u8]>);
210 unsafe fn uninitialized
<T
>() -> T
{
211 MaybeUninit { uninit: () }
.value
.value
214 zeroed
::<(u8, u8)>();
215 #[allow(unreachable_code)]
220 uninitialized
::<Foo
>();
225 let _
= box NoisyDrop
{
226 text
: "Boxed outer got dropped!\0",
227 inner
: NoisyDropInner
,
228 } as Box
<dyn SomeTrait
>;
230 const FUNC_REF
: Option
<fn()> = Some(main
);
233 None
=> assert
!(false),
236 match Ordering
::Less
{
237 Ordering
::Less
=> {}
,
241 [NoisyDropInner
, NoisyDropInner
];
243 let x
= &[0u32, 42u32] as &[u32];
245 [] => assert_eq
!(0u32, 1),
246 [_
, ref y @
..] => assert_eq
!(&x
[1] as *const u32 as usize, &y
[0] as *const u32 as usize),
249 assert_eq
!(((|()| 42u8) as fn(()) -> u8)(()), 42);
253 static ABC
: *const u8;
259 static ABC
: *const u8;
263 // TODO(antoyo): to make this work, support weak linkage.
264 //unsafe { assert_eq!(ABC as usize, 0); }
266 &mut (|| Some(0 as *const ())) as &mut dyn FnMut() -> Option
<*const ()>;
269 assert_eq
!(f
as u8, 255);
271 assert_eq
!(f2
as i8, -128);
272 assert_eq
!(f2
as u8, 0);
274 static ANOTHER_STATIC
: &u8 = &A_STATIC
;
275 assert_eq
!(*ANOTHER_STATIC
, 42);
277 check_niche_behavior();
283 struct ExternTypeWrapper
{
287 let nullptr
= 0 as *const ();
288 let extern_nullptr
= nullptr
as *const ExternTypeWrapper
;
289 extern_nullptr
as *const ();
290 let slice_ptr
= &[] as *const [u8];
291 slice_ptr
as *const u8;
306 type pthread_t
= c_ulong
;
309 struct pthread_attr_t
{
313 #[link(name = "pthread")]
315 fn pthread_attr_init(attr
: *mut pthread_attr_t
) -> c_int
;
318 native
: *mut pthread_t
,
319 attr
: *const pthread_attr_t
,
320 f
: extern "C" fn(_
: *mut c_void
) -> *mut c_void
,
326 value
: *mut *mut c_void
332 static mut TLS
: u8 = 42;
335 extern "C" fn mutate_tls(_
: *mut c_void
) -> *mut c_void
{
343 let mut attr
: pthread_attr_t
= zeroed();
344 let mut thread
: pthread_t
= 0;
348 if pthread_attr_init(&mut attr
) != 0 {
352 if pthread_create(&mut thread
, &attr
, mutate_tls
, 0 as *mut c_void
) != 0 {
356 let mut res
= 0 as *mut c_void
;
357 pthread_join(thread
, &mut res
);
359 // TLS of main thread must not have been changed by the other thread.
362 puts("TLS works!\n\0" as *const str as *const u8);
366 // Copied ui/issues/issue-61696.rs
368 pub enum Infallible {}
370 // The check that the `bool` field of `V1` is encoding a "niche variant"
371 // (i.e. not `V1`, so `V3` or `V4`) used to be mathematically incorrect,
372 // causing valid `V1` values to be interpreted as other variants.
375 V2 { f: Infallible }
,
380 // Computing the discriminant used to be done using the niche type (here `u8`,
381 // from the `bool` field of `V1`), overflowing for variants with large enough
382 // indices (`V3` and `V4`), causing them to be interpreted as other variants.
386 /*_00*/ _01(X
), _02(X
), _03(X
), _04(X
), _05(X
), _06(X
), _07(X
),
387 _08(X
), _09(X
), _0A(X
), _0B(X
), _0C(X
), _0D(X
), _0E(X
), _0F(X
),
388 _10(X
), _11(X
), _12(X
), _13(X
), _14(X
), _15(X
), _16(X
), _17(X
),
389 _18(X
), _19(X
), _1A(X
), _1B(X
), _1C(X
), _1D(X
), _1E(X
), _1F(X
),
390 _20(X
), _21(X
), _22(X
), _23(X
), _24(X
), _25(X
), _26(X
), _27(X
),
391 _28(X
), _29(X
), _2A(X
), _2B(X
), _2C(X
), _2D(X
), _2E(X
), _2F(X
),
392 _30(X
), _31(X
), _32(X
), _33(X
), _34(X
), _35(X
), _36(X
), _37(X
),
393 _38(X
), _39(X
), _3A(X
), _3B(X
), _3C(X
), _3D(X
), _3E(X
), _3F(X
),
394 _40(X
), _41(X
), _42(X
), _43(X
), _44(X
), _45(X
), _46(X
), _47(X
),
395 _48(X
), _49(X
), _4A(X
), _4B(X
), _4C(X
), _4D(X
), _4E(X
), _4F(X
),
396 _50(X
), _51(X
), _52(X
), _53(X
), _54(X
), _55(X
), _56(X
), _57(X
),
397 _58(X
), _59(X
), _5A(X
), _5B(X
), _5C(X
), _5D(X
), _5E(X
), _5F(X
),
398 _60(X
), _61(X
), _62(X
), _63(X
), _64(X
), _65(X
), _66(X
), _67(X
),
399 _68(X
), _69(X
), _6A(X
), _6B(X
), _6C(X
), _6D(X
), _6E(X
), _6F(X
),
400 _70(X
), _71(X
), _72(X
), _73(X
), _74(X
), _75(X
), _76(X
), _77(X
),
401 _78(X
), _79(X
), _7A(X
), _7B(X
), _7C(X
), _7D(X
), _7E(X
), _7F(X
),
402 _80(X
), _81(X
), _82(X
), _83(X
), _84(X
), _85(X
), _86(X
), _87(X
),
403 _88(X
), _89(X
), _8A(X
), _8B(X
), _8C(X
), _8D(X
), _8E(X
), _8F(X
),
404 _90(X
), _91(X
), _92(X
), _93(X
), _94(X
), _95(X
), _96(X
), _97(X
),
405 _98(X
), _99(X
), _9A(X
), _9B(X
), _9C(X
), _9D(X
), _9E(X
), _9F(X
),
406 _A0(X
), _A1(X
), _A2(X
), _A3(X
), _A4(X
), _A5(X
), _A6(X
), _A7(X
),
407 _A8(X
), _A9(X
), _AA(X
), _AB(X
), _AC(X
), _AD(X
), _AE(X
), _AF(X
),
408 _B0(X
), _B1(X
), _B2(X
), _B3(X
), _B4(X
), _B5(X
), _B6(X
), _B7(X
),
409 _B8(X
), _B9(X
), _BA(X
), _BB(X
), _BC(X
), _BD(X
), _BE(X
), _BF(X
),
410 _C0(X
), _C1(X
), _C2(X
), _C3(X
), _C4(X
), _C5(X
), _C6(X
), _C7(X
),
411 _C8(X
), _C9(X
), _CA(X
), _CB(X
), _CC(X
), _CD(X
), _CE(X
), _CF(X
),
412 _D0(X
), _D1(X
), _D2(X
), _D3(X
), _D4(X
), _D5(X
), _D6(X
), _D7(X
),
413 _D8(X
), _D9(X
), _DA(X
), _DB(X
), _DC(X
), _DD(X
), _DE(X
), _DF(X
),
414 _E0(X
), _E1(X
), _E2(X
), _E3(X
), _E4(X
), _E5(X
), _E6(X
), _E7(X
),
415 _E8(X
), _E9(X
), _EA(X
), _EB(X
), _EC(X
), _ED(X
), _EE(X
), _EF(X
),
416 _F0(X
), _F1(X
), _F2(X
), _F3(X
), _F4(X
), _F5(X
), _F6(X
), _F7(X
),
417 _F8(X
), _F9(X
), _FA(X
), _FB(X
), _FC(X
), _FD(X
), _FE(X
), _FF(X
),
423 fn check_niche_behavior () {
424 if let E1
::V2 { .. }
= (E1
::V1 { f: true }
) {
428 if let E2
::V1 { .. }
= E2
::V3
::<Infallible
> {