// Compiler: // // Run-time: // status: 0 // stdout: true // 1 #![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)] #![no_std] #![no_core] /* * Core */ // Because we don't have core yet. #[lang = "sized"] pub trait Sized {} #[lang = "copy"] trait Copy { } impl Copy for isize {} impl Copy for usize {} impl Copy for u64 {} impl Copy for i32 {} impl Copy for u32 {} impl Copy for bool {} impl Copy for u16 {} impl Copy for i16 {} impl Copy for char {} impl Copy for i8 {} impl Copy for u8 {} #[lang = "receiver"] trait Receiver { } #[lang = "freeze"] pub(crate) unsafe auto trait Freeze {} mod libc { #[link(name = "c")] extern "C" { pub fn printf(format: *const i8, ...) -> i32; pub fn puts(s: *const u8) -> i32; } } #[lang = "index"] pub trait Index { type Output: ?Sized; fn index(&self, index: Idx) -> &Self::Output; } impl Index for [T; 3] { type Output = T; fn index(&self, index: usize) -> &Self::Output { &self[index] } } impl Index for [T] { type Output = T; fn index(&self, index: usize) -> &Self::Output { &self[index] } } #[lang = "drop_in_place"] #[allow(unconditional_recursion)] pub unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. drop_in_place(to_drop); } #[lang = "panic"] #[track_caller] #[no_mangle] pub fn panic(_msg: &'static str) -> ! { unsafe { libc::puts("Panicking\0" as *const str as *const u8); intrinsics::abort(); } } #[lang = "panic_location"] struct PanicLocation { file: &'static str, line: u32, column: u32, } #[lang = "panic_bounds_check"] #[track_caller] #[no_mangle] fn panic_bounds_check(index: usize, len: usize) -> ! { unsafe { 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); intrinsics::abort(); } } mod intrinsics { extern "rust-intrinsic" { pub fn abort() -> !; } } #[lang = "add"] trait Add { type Output; fn add(self, rhs: RHS) -> Self::Output; } impl Add for u8 { type Output = Self; fn add(self, rhs: Self) -> Self { self + rhs } } impl Add for i8 { type Output = Self; fn add(self, rhs: Self) -> Self { self + rhs } } impl Add for i32 { type Output = Self; fn add(self, rhs: Self) -> Self { self + rhs } } impl Add for usize { type Output = Self; fn add(self, rhs: Self) -> Self { self + rhs } } impl Add for isize { type Output = Self; fn add(self, rhs: Self) -> Self { self + rhs } } #[lang = "sub"] pub trait Sub { type Output; fn sub(self, rhs: RHS) -> Self::Output; } impl Sub for usize { type Output = Self; fn sub(self, rhs: Self) -> Self { self - rhs } } impl Sub for isize { type Output = Self; fn sub(self, rhs: Self) -> Self { self - rhs } } impl Sub for u8 { type Output = Self; fn sub(self, rhs: Self) -> Self { self - rhs } } impl Sub for i8 { type Output = Self; fn sub(self, rhs: Self) -> Self { self - rhs } } impl Sub for i16 { type Output = Self; fn sub(self, rhs: Self) -> Self { self - rhs } } #[lang = "eq"] pub trait PartialEq { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool; } impl PartialEq for u8 { fn eq(&self, other: &u8) -> bool { (*self) == (*other) } fn ne(&self, other: &u8) -> bool { (*self) != (*other) } } impl PartialEq for u16 { fn eq(&self, other: &u16) -> bool { (*self) == (*other) } fn ne(&self, other: &u16) -> bool { (*self) != (*other) } } impl PartialEq for u32 { fn eq(&self, other: &u32) -> bool { (*self) == (*other) } fn ne(&self, other: &u32) -> bool { (*self) != (*other) } } impl PartialEq for u64 { fn eq(&self, other: &u64) -> bool { (*self) == (*other) } fn ne(&self, other: &u64) -> bool { (*self) != (*other) } } impl PartialEq for usize { fn eq(&self, other: &usize) -> bool { (*self) == (*other) } fn ne(&self, other: &usize) -> bool { (*self) != (*other) } } impl PartialEq for i8 { fn eq(&self, other: &i8) -> bool { (*self) == (*other) } fn ne(&self, other: &i8) -> bool { (*self) != (*other) } } impl PartialEq for i32 { fn eq(&self, other: &i32) -> bool { (*self) == (*other) } fn ne(&self, other: &i32) -> bool { (*self) != (*other) } } impl PartialEq for isize { fn eq(&self, other: &isize) -> bool { (*self) == (*other) } fn ne(&self, other: &isize) -> bool { (*self) != (*other) } } impl PartialEq for char { fn eq(&self, other: &char) -> bool { (*self) == (*other) } fn ne(&self, other: &char) -> bool { (*self) != (*other) } } /* * Code */ #[start] fn main(argc: isize, _argv: *const *const u8) -> isize { unsafe { if argc == 1 { libc::printf(b"true\n\0" as *const u8 as *const i8); } let string = match argc { 1 => b"1\n\0", 2 => b"2\n\0", 3 => b"3\n\0", 4 => b"4\n\0", 5 => b"5\n\0", _ => b"_\n\0", }; libc::printf(string as *const u8 as *const i8); } 0 }