// Compiler: // // Run-time: // status: 0 // stdout: 42 // 7 // 5 // 10 #![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] #![allow(internal_features)] #![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 i32 {} impl Copy for u8 {} impl Copy for i8 {} impl Copy for i16 {} #[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" { #[rustc_safe_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 } } #[track_caller] #[lang = "panic_const_add_overflow"] pub fn panic_const_add_overflow() -> ! { panic("attempt to add with overflow"); } #[track_caller] #[lang = "panic_const_sub_overflow"] pub fn panic_const_sub_overflow() -> ! { panic("attempt to subtract with overflow"); } /* * Code */ static mut ONE: usize = 1; fn make_array() -> [u8; 3] { [42, 10, 5] } #[start] fn main(argc: isize, _argv: *const *const u8) -> isize { let array = [42, 7, 5]; let array2 = make_array(); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE - 1]); libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE]); libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE + 1]); libc::printf(b"%d\n\0" as *const u8 as *const i8, array2[argc as usize] as u32); } 0 }