]> git.lizzy.rs Git - rust.git/blob - example/mini_core_hello_world.rs
Implement pow{f32,f64} intrinsics
[rust.git] / example / mini_core_hello_world.rs
1 // Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
2
3 #![feature(no_core, unboxed_closures, start, lang_items, box_syntax, slice_patterns, never_type, linkage)]
4 #![no_core]
5 #![allow(dead_code)]
6
7 extern crate mini_core;
8
9 use mini_core::*;
10 use mini_core::libc::*;
11
12 unsafe extern "C" fn my_puts(s: *const u8) {
13     puts(s);
14 }
15
16 #[lang = "termination"]
17 trait Termination {
18     fn report(self) -> i32;
19 }
20
21 impl Termination for () {
22     fn report(self) -> i32 {
23         unsafe {
24             NUM = 6 * 7 + 1 + (1u8 == 1u8) as u8; // 44
25             *NUM_REF as i32
26         }
27     }
28 }
29
30 trait SomeTrait {
31     fn object_safe(&self);
32 }
33
34 impl SomeTrait for &'static str {
35     fn object_safe(&self) {
36         unsafe {
37             puts(*self as *const str as *const u8);
38         }
39     }
40 }
41
42 struct NoisyDrop {
43     text: &'static str,
44     inner: NoisyDropInner,
45 }
46
47 struct NoisyDropInner;
48
49 impl Drop for NoisyDrop {
50     fn drop(&mut self) {
51         unsafe {
52             puts(self.text as *const str as *const u8);
53         }
54     }
55 }
56
57 impl Drop for NoisyDropInner {
58     fn drop(&mut self) {
59         unsafe {
60             puts("Inner got dropped!\0" as *const str as *const u8);
61         }
62     }
63 }
64
65 impl SomeTrait for NoisyDrop {
66     fn object_safe(&self) {}
67 }
68
69 enum Ordering {
70     Less = -1,
71     Equal = 0,
72     Greater = 1,
73 }
74
75 #[lang = "start"]
76 fn start<T: Termination + 'static>(
77     main: fn() -> T,
78     argc: isize,
79     argv: *const *const u8,
80 ) -> isize {
81     if argc == 3 {
82         unsafe { puts(*argv); }
83         unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const u8)); }
84         unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const u8)); }
85     }
86
87     main().report();
88     0
89 }
90
91 static mut NUM: u8 = 6 * 7;
92 static NUM_REF: &'static u8 = unsafe { &NUM };
93
94 macro_rules! assert {
95     ($e:expr) => {
96         if !$e {
97             panic(&(stringify!(! $e), file!(), line!(), 0));
98         }
99     };
100 }
101
102 macro_rules! assert_eq {
103     ($l:expr, $r: expr) => {
104         if $l != $r {
105             panic(&(stringify!($l != $r), file!(), line!(), 0));
106         }
107     }
108 }
109
110 struct Unique<T: ?Sized> {
111     pointer: *const T,
112     _marker: PhantomData<T>,
113 }
114
115 impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
116
117 fn take_f32(_f: f32) {}
118 fn take_unique(_u: Unique<()>) {}
119
120 fn return_u128_pair() -> (u128, u128) {
121     (0, 0)
122 }
123
124 fn call_return_u128_pair() {
125     return_u128_pair();
126 }
127
128 fn main() {
129     take_unique(Unique {
130         pointer: 0 as *const (),
131         _marker: PhantomData,
132     });
133     take_f32(0.1);
134
135     call_return_u128_pair();
136
137     let slice = &[0, 1] as &[i32];
138     let slice_ptr = slice as *const [i32] as *const i32;
139
140     // FIXME On macOS statics and promoted constants have the wrong alignment. This causes this
141     // assertion to fail.
142     if cfg!(not(target_os = "macos")) {
143         assert_eq!(slice_ptr as usize % 4, 0);
144     }
145
146     //return;
147
148     unsafe {
149         printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8);
150
151         let hello: &[u8] = b"Hello\0" as &[u8; 6];
152         let ptr: *const u8 = hello as *const [u8] as *const u8;
153         puts(ptr);
154
155         let world: Box<&str> = box "World!\0";
156         puts(*world as *const str as *const u8);
157         world as Box<dyn SomeTrait>;
158
159         assert_eq!(intrinsics::bitreverse(0b10101000u8), 0b00010101u8);
160
161         assert_eq!(intrinsics::bswap(0xabu8), 0xabu8);
162         assert_eq!(intrinsics::bswap(0xddccu16), 0xccddu16);
163         assert_eq!(intrinsics::bswap(0xffee_ddccu32), 0xccdd_eeffu32);
164         assert_eq!(intrinsics::bswap(0x1234_5678_ffee_ddccu64), 0xccdd_eeff_7856_3412u64);
165
166         assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
167
168         let chars = &['C', 'h', 'a', 'r', 's'];
169         let chars = chars as &[char];
170         assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5);
171
172         let a: &dyn SomeTrait = &"abc\0";
173         a.object_safe();
174
175         assert_eq!(intrinsics::size_of_val(a) as u8, 16);
176         assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
177
178         assert_eq!(intrinsics::min_align_of::<u16>() as u8, 2);
179         assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8);
180
181         assert!(!intrinsics::needs_drop::<u8>());
182         assert!(intrinsics::needs_drop::<NoisyDrop>());
183
184         Unique {
185             pointer: 0 as *const &str,
186             _marker: PhantomData,
187         } as Unique<dyn SomeTrait>;
188
189         struct MyDst<T: ?Sized>(T);
190
191         intrinsics::size_of_val(&MyDst([0u8; 4]) as &MyDst<[u8]>);
192
193         struct Foo {
194             x: u8,
195             y: !,
196         }
197
198         unsafe fn zeroed<T>() -> T {
199             intrinsics::init::<T>()
200         }
201
202         unsafe fn uninitialized<T>() -> T {
203             MaybeUninit { uninit: () }.value
204         }
205
206         zeroed::<(u8, u8)>();
207         #[allow(unreachable_code)]
208         {
209             if false {
210                 zeroed::<!>();
211                 zeroed::<Foo>();
212                 uninitialized::<Foo>();
213             }
214         }
215     }
216
217     let _ = box NoisyDrop {
218         text: "Boxed outer got dropped!\0",
219         inner: NoisyDropInner,
220     } as Box<dyn SomeTrait>;
221
222     const FUNC_REF: Option<fn()> = Some(main);
223     match FUNC_REF {
224         Some(_) => {},
225         None => assert!(false),
226     }
227
228     match Ordering::Less {
229         Ordering::Less => {},
230         _ => assert!(false),
231     }
232
233     [NoisyDropInner, NoisyDropInner];
234
235     let x = &[0u32, 42u32] as &[u32];
236     match x {
237         [] => assert_eq!(0u32, 1),
238         [_, ref y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize),
239     }
240
241     assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42);
242
243     extern {
244         #[linkage = "weak"]
245         static ABC: *const u8;
246     }
247
248     {
249         extern {
250             #[linkage = "weak"]
251             static ABC: *const u8;
252         }
253     }
254
255     unsafe { assert_eq!(ABC as usize, 0); }
256
257     &mut (|| Some(0 as *const ())) as &mut dyn FnMut() -> Option<*const ()>;
258
259     let f = 1000.0;
260     assert_eq!(f as u8, 255);
261     let f2 = -1000.0;
262     assert_eq!(f2 as i8, -128);
263     assert_eq!(f2 as u8, 0);
264
265     static ANOTHER_STATIC: &u8 = &A_STATIC;
266     assert_eq!(*ANOTHER_STATIC, 42);
267 }