1 // Compiler:
2 //
3 // Run-time:
4 //   status: 0
5 //   stdout: true
6 //     1
7 
8 #![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
9 
10 #![no_std]
11 #![no_core]
12 
13 /*
14  * Core
15  */
16 
17 // Because we don't have core yet.
18 #[lang = "sized"]
19 pub trait Sized {}
20 
21 #[lang = "copy"]
22 trait Copy {
23 }
24 
25 impl Copy for isize {}
26 impl Copy for usize {}
27 impl Copy for u64 {}
28 impl Copy for i32 {}
29 impl Copy for u32 {}
30 impl Copy for bool {}
31 impl Copy for u16 {}
32 impl Copy for i16 {}
33 impl Copy for char {}
34 impl Copy for i8 {}
35 impl Copy for u8 {}
36 
37 #[lang = "receiver"]
38 trait Receiver {
39 }
40 
41 #[lang = "freeze"]
42 pub(crate) unsafe auto trait Freeze {}
43 
44 mod libc {
45     #[link(name = "c")]
46     extern "C" {
printf(format: *const i8, ...) -> i3247         pub fn printf(format: *const i8, ...) -> i32;
puts(s: *const u8) -> i3248         pub fn puts(s: *const u8) -> i32;
49     }
50 }
51 
52 #[lang = "index"]
53 pub trait Index<Idx: ?Sized> {
54     type Output: ?Sized;
index(&self, index: Idx) -> &Self::Output55     fn index(&self, index: Idx) -> &Self::Output;
56 }
57 
58 impl<T> Index<usize> for [T; 3] {
59     type Output = T;
60 
index(&self, index: usize) -> &Self::Output61     fn index(&self, index: usize) -> &Self::Output {
62         &self[index]
63     }
64 }
65 
66 impl<T> Index<usize> for [T] {
67     type Output = T;
68 
index(&self, index: usize) -> &Self::Output69     fn index(&self, index: usize) -> &Self::Output {
70         &self[index]
71     }
72 }
73 
74 #[lang = "drop_in_place"]
75 #[allow(unconditional_recursion)]
drop_in_place<T: ?Sized>(to_drop: *mut T)76 pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
77     // Code here does not matter - this is replaced by the
78     // real drop glue by the compiler.
79     drop_in_place(to_drop);
80 }
81 
82 #[lang = "panic"]
83 #[track_caller]
84 #[no_mangle]
panic(_msg: &str) -> !85 pub fn panic(_msg: &str) -> ! {
86     unsafe {
87         libc::puts("Panicking\0" as *const str as *const u8);
88         intrinsics::abort();
89     }
90 }
91 
92 #[lang = "panic_location"]
93 struct PanicLocation {
94     file: &'static str,
95     line: u32,
96     column: u32,
97 }
98 
99 #[lang = "panic_bounds_check"]
100 #[track_caller]
101 #[no_mangle]
panic_bounds_check(index: usize, len: usize) -> !102 fn panic_bounds_check(index: usize, len: usize) -> ! {
103     unsafe {
104         libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
105         intrinsics::abort();
106     }
107 }
108 
109 mod intrinsics {
110     extern "rust-intrinsic" {
abort() -> !111         pub fn abort() -> !;
112     }
113 }
114 
115 #[lang = "add"]
116 trait Add<RHS = Self> {
117     type Output;
118 
add(self, rhs: RHS) -> Self::Output119     fn add(self, rhs: RHS) -> Self::Output;
120 }
121 
122 impl Add for u8 {
123     type Output = Self;
124 
add(self, rhs: Self) -> Self125     fn add(self, rhs: Self) -> Self {
126         self + rhs
127     }
128 }
129 
130 impl Add for i8 {
131     type Output = Self;
132 
add(self, rhs: Self) -> Self133     fn add(self, rhs: Self) -> Self {
134         self + rhs
135     }
136 }
137 
138 impl Add for i32 {
139     type Output = Self;
140 
add(self, rhs: Self) -> Self141     fn add(self, rhs: Self) -> Self {
142         self + rhs
143     }
144 }
145 
146 impl Add for usize {
147     type Output = Self;
148 
add(self, rhs: Self) -> Self149     fn add(self, rhs: Self) -> Self {
150         self + rhs
151     }
152 }
153 
154 impl Add for isize {
155     type Output = Self;
156 
add(self, rhs: Self) -> Self157     fn add(self, rhs: Self) -> Self {
158         self + rhs
159     }
160 }
161 
162 #[lang = "sub"]
163 pub trait Sub<RHS = Self> {
164     type Output;
165 
sub(self, rhs: RHS) -> Self::Output166     fn sub(self, rhs: RHS) -> Self::Output;
167 }
168 
169 impl Sub for usize {
170     type Output = Self;
171 
sub(self, rhs: Self) -> Self172     fn sub(self, rhs: Self) -> Self {
173         self - rhs
174     }
175 }
176 
177 impl Sub for isize {
178     type Output = Self;
179 
sub(self, rhs: Self) -> Self180     fn sub(self, rhs: Self) -> Self {
181         self - rhs
182     }
183 }
184 
185 impl Sub for u8 {
186     type Output = Self;
187 
sub(self, rhs: Self) -> Self188     fn sub(self, rhs: Self) -> Self {
189         self - rhs
190     }
191 }
192 
193 impl Sub for i8 {
194     type Output = Self;
195 
sub(self, rhs: Self) -> Self196     fn sub(self, rhs: Self) -> Self {
197         self - rhs
198     }
199 }
200 
201 impl Sub for i16 {
202     type Output = Self;
203 
sub(self, rhs: Self) -> Self204     fn sub(self, rhs: Self) -> Self {
205         self - rhs
206     }
207 }
208 
209 #[lang = "eq"]
210 pub trait PartialEq<Rhs: ?Sized = Self> {
eq(&self, other: &Rhs) -> bool211     fn eq(&self, other: &Rhs) -> bool;
ne(&self, other: &Rhs) -> bool212     fn ne(&self, other: &Rhs) -> bool;
213 }
214 
215 impl PartialEq for u8 {
eq(&self, other: &u8) -> bool216     fn eq(&self, other: &u8) -> bool {
217         (*self) == (*other)
218     }
ne(&self, other: &u8) -> bool219     fn ne(&self, other: &u8) -> bool {
220         (*self) != (*other)
221     }
222 }
223 
224 impl PartialEq for u16 {
eq(&self, other: &u16) -> bool225     fn eq(&self, other: &u16) -> bool {
226         (*self) == (*other)
227     }
ne(&self, other: &u16) -> bool228     fn ne(&self, other: &u16) -> bool {
229         (*self) != (*other)
230     }
231 }
232 
233 impl PartialEq for u32 {
eq(&self, other: &u32) -> bool234     fn eq(&self, other: &u32) -> bool {
235         (*self) == (*other)
236     }
ne(&self, other: &u32) -> bool237     fn ne(&self, other: &u32) -> bool {
238         (*self) != (*other)
239     }
240 }
241 
242 
243 impl PartialEq for u64 {
eq(&self, other: &u64) -> bool244     fn eq(&self, other: &u64) -> bool {
245         (*self) == (*other)
246     }
ne(&self, other: &u64) -> bool247     fn ne(&self, other: &u64) -> bool {
248         (*self) != (*other)
249     }
250 }
251 
252 impl PartialEq for usize {
eq(&self, other: &usize) -> bool253     fn eq(&self, other: &usize) -> bool {
254         (*self) == (*other)
255     }
ne(&self, other: &usize) -> bool256     fn ne(&self, other: &usize) -> bool {
257         (*self) != (*other)
258     }
259 }
260 
261 impl PartialEq for i8 {
eq(&self, other: &i8) -> bool262     fn eq(&self, other: &i8) -> bool {
263         (*self) == (*other)
264     }
ne(&self, other: &i8) -> bool265     fn ne(&self, other: &i8) -> bool {
266         (*self) != (*other)
267     }
268 }
269 
270 impl PartialEq for i32 {
eq(&self, other: &i32) -> bool271     fn eq(&self, other: &i32) -> bool {
272         (*self) == (*other)
273     }
ne(&self, other: &i32) -> bool274     fn ne(&self, other: &i32) -> bool {
275         (*self) != (*other)
276     }
277 }
278 
279 impl PartialEq for isize {
eq(&self, other: &isize) -> bool280     fn eq(&self, other: &isize) -> bool {
281         (*self) == (*other)
282     }
ne(&self, other: &isize) -> bool283     fn ne(&self, other: &isize) -> bool {
284         (*self) != (*other)
285     }
286 }
287 
288 impl PartialEq for char {
eq(&self, other: &char) -> bool289     fn eq(&self, other: &char) -> bool {
290         (*self) == (*other)
291     }
ne(&self, other: &char) -> bool292     fn ne(&self, other: &char) -> bool {
293         (*self) != (*other)
294     }
295 }
296 
297 /*
298  * Code
299  */
300 
301 #[start]
main(argc: isize, _argv: *const *const u8) -> isize302 fn main(argc: isize, _argv: *const *const u8) -> isize {
303     unsafe {
304         if argc == 1 {
305             libc::printf(b"true\n\0" as *const u8 as *const i8);
306         }
307 
308         let string =
309             match argc {
310                 1 => b"1\n\0",
311                 2 => b"2\n\0",
312                 3 => b"3\n\0",
313                 4 => b"4\n\0",
314                 5 => b"5\n\0",
315                 _ => b"_\n\0",
316             };
317         libc::printf(string as *const u8 as *const i8);
318     }
319     0
320 }
321