#![feature( no_core, lang_items, intrinsics, unboxed_closures, extern_types, decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls, thread_local )] #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] #[lang = "sized"] pub trait Sized {} #[lang = "destruct"] pub trait Destruct {} #[lang = "tuple_trait"] pub trait Tuple {} #[lang = "unsize"] pub trait Unsize {} #[lang = "coerce_unsized"] pub trait CoerceUnsized {} impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} #[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn {} // &T -> &U impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} impl, U: ?Sized> DispatchFromDyn> for Box {} #[lang = "receiver"] pub trait Receiver {} impl Receiver for &T {} impl Receiver for &mut T {} impl Receiver for Box {} #[lang = "copy"] pub unsafe trait Copy {} unsafe impl Copy for bool {} unsafe impl Copy for u8 {} unsafe impl Copy for u16 {} unsafe impl Copy for u32 {} unsafe impl Copy for u64 {} unsafe impl Copy for u128 {} unsafe impl Copy for usize {} unsafe impl Copy for i8 {} unsafe impl Copy for i16 {} unsafe impl Copy for i32 {} unsafe impl Copy for isize {} unsafe impl Copy for f32 {} unsafe impl Copy for f64 {} unsafe impl Copy for char {} unsafe impl<'a, T: ?Sized> Copy for &'a T {} unsafe impl Copy for *const T {} unsafe impl Copy for *mut T {} unsafe impl Copy for Option {} #[lang = "sync"] pub unsafe trait Sync {} unsafe impl Sync for bool {} unsafe impl Sync for u8 {} unsafe impl Sync for u16 {} unsafe impl Sync for u32 {} unsafe impl Sync for u64 {} unsafe impl Sync for usize {} unsafe impl Sync for i8 {} unsafe impl Sync for i16 {} unsafe impl Sync for i32 {} unsafe impl Sync for isize {} unsafe impl Sync for char {} unsafe impl Sync for f32 {} unsafe impl<'a, T: ?Sized> Sync for &'a T {} unsafe impl Sync for [T; N] {} #[lang = "freeze"] unsafe auto trait Freeze {} unsafe impl Freeze for PhantomData {} unsafe impl Freeze for *const T {} unsafe impl Freeze for *mut T {} unsafe impl Freeze for &T {} unsafe impl Freeze for &mut T {} #[lang = "structural_peq"] pub trait StructuralPartialEq {} #[lang = "not"] pub trait Not { type Output; fn not(self) -> Self::Output; } impl Not for bool { type Output = bool; fn not(self) -> bool { !self } } #[lang = "mul"] pub trait Mul { type Output; #[must_use] fn mul(self, rhs: RHS) -> Self::Output; } impl Mul for u8 { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { self * rhs } } impl Mul for usize { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { self * rhs } } #[lang = "add"] pub 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 usize { 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 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 = "rem"] pub trait Rem { type Output; fn rem(self, rhs: RHS) -> Self::Output; } impl Rem for usize { type Output = Self; fn rem(self, rhs: Self) -> Self { self % rhs } } #[lang = "bitor"] pub trait BitOr { type Output; #[must_use] fn bitor(self, rhs: RHS) -> Self::Output; } impl BitOr for bool { type Output = bool; fn bitor(self, rhs: bool) -> bool { self | rhs } } impl<'a> BitOr for &'a bool { type Output = bool; fn bitor(self, rhs: bool) -> bool { *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 u128 { fn eq(&self, other: &u128) -> bool { (*self) == (*other) } fn ne(&self, other: &u128) -> 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) } } impl PartialEq for *const T { fn eq(&self, other: &*const T) -> bool { *self == *other } fn ne(&self, other: &*const T) -> bool { *self != *other } } impl PartialEq for Option { fn eq(&self, other: &Self) -> bool { match (self, other) { (Some(lhs), Some(rhs)) => *lhs == *rhs, (None, None) => true, _ => false, } } fn ne(&self, other: &Self) -> bool { match (self, other) { (Some(lhs), Some(rhs)) => *lhs != *rhs, (None, None) => false, _ => true, } } } #[lang = "shl"] pub trait Shl { type Output; #[must_use] fn shl(self, rhs: RHS) -> Self::Output; } impl Shl for u128 { type Output = u128; fn shl(self, rhs: u128) -> u128 { self << rhs } } #[lang = "neg"] pub trait Neg { type Output; fn neg(self) -> Self::Output; } impl Neg for i8 { type Output = i8; fn neg(self) -> i8 { -self } } impl Neg for i16 { type Output = i16; fn neg(self) -> i16 { self } } impl Neg for isize { type Output = isize; fn neg(self) -> isize { -self } } impl Neg for f32 { type Output = f32; fn neg(self) -> f32 { -self } } pub enum Option { Some(T), None, } pub use Option::*; #[lang = "phantom_data"] pub struct PhantomData; #[lang = "fn_once"] #[rustc_paren_sugar] pub trait FnOnce { #[lang = "fn_once_output"] type Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output; } #[lang = "fn_mut"] #[rustc_paren_sugar] pub trait FnMut: FnOnce { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; } #[lang = "panic"] #[track_caller] pub fn panic(_msg: &'static str) -> ! { unsafe { libc::puts("Panicking\n\0" as *const str as *const i8); intrinsics::abort(); } } macro_rules! panic_const { ($($lang:ident = $message:expr,)+) => { pub mod panic_const { use super::*; $( #[track_caller] #[lang = stringify!($lang)] pub fn $lang() -> ! { panic($message); } )+ } } } panic_const! { panic_const_add_overflow = "attempt to add with overflow", panic_const_sub_overflow = "attempt to subtract with overflow", panic_const_mul_overflow = "attempt to multiply with overflow", panic_const_div_overflow = "attempt to divide with overflow", panic_const_rem_overflow = "attempt to calculate the remainder with overflow", panic_const_neg_overflow = "attempt to negate with overflow", panic_const_shr_overflow = "attempt to shift right with overflow", panic_const_shl_overflow = "attempt to shift left with overflow", panic_const_div_by_zero = "attempt to divide by zero", panic_const_rem_by_zero = "attempt to calculate the remainder with a divisor of zero", } #[lang = "panic_bounds_check"] #[track_caller] 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(); } } #[lang = "panic_cannot_unwind"] #[track_caller] fn panic_cannot_unwind() -> ! { unsafe { libc::puts("panic in a function that cannot unwind\n\0" as *const str as *const i8); intrinsics::abort(); } } #[lang = "eh_personality"] fn eh_personality() -> ! { loop {} } #[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 = "unpin"] pub auto trait Unpin {} #[lang = "deref"] pub trait Deref { type Target: ?Sized; fn deref(&self) -> &Self::Target; } #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] pub struct NonNull(pub *const T); impl CoerceUnsized> for NonNull where T: Unsize {} impl DispatchFromDyn> for NonNull where T: Unsize {} pub struct Unique { pub pointer: NonNull, pub _marker: PhantomData, } impl CoerceUnsized> for Unique where T: Unsize {} impl DispatchFromDyn> for Unique where T: Unsize {} #[lang = "global_alloc_ty"] pub struct Global; #[lang = "owned_box"] pub struct Box(Unique, A); impl, U: ?Sized> CoerceUnsized> for Box {} impl Box { pub fn new(val: T) -> Box { unsafe { let size = intrinsics::size_of::(); let ptr = libc::malloc(size); intrinsics::copy(&val as *const T as *const u8, ptr, size); Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global) } } } impl Drop for Box { fn drop(&mut self) { // inner value is dropped by compiler unsafe { libc::free(self.0.pointer.0 as *mut u8); } } } impl Deref for Box { type Target = T; fn deref(&self) -> &Self::Target { &**self } } #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { libc::malloc(size) } #[lang = "drop"] pub trait Drop { fn drop(&mut self); } #[lang = "manually_drop"] #[repr(transparent)] pub struct ManuallyDrop { pub value: T, } #[lang = "maybe_uninit"] #[repr(transparent)] pub union MaybeUninit { pub uninit: (), pub value: ManuallyDrop, } pub mod intrinsics { extern "rust-intrinsic" { #[rustc_safe_intrinsic] pub fn abort() -> !; #[rustc_safe_intrinsic] pub fn size_of() -> usize; pub fn size_of_val(val: *const T) -> usize; #[rustc_safe_intrinsic] pub fn min_align_of() -> usize; pub fn min_align_of_val(val: *const T) -> usize; pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; pub fn ctlz_nonzero(x: T) -> T; #[rustc_safe_intrinsic] pub fn needs_drop() -> bool; #[rustc_safe_intrinsic] pub fn bitreverse(x: T) -> T; #[rustc_safe_intrinsic] pub fn bswap(x: T) -> T; pub fn write_bytes(dst: *mut T, val: u8, count: usize); } } pub mod libc { // With the new Universal CRT, msvc has switched to all the printf functions being inline wrapper // functions. legacy_stdio_definitions.lib which provides the printf wrapper functions as normal // symbols to link against. #[cfg_attr(unix, link(name = "c"))] #[cfg_attr(target_env = "msvc", link(name = "legacy_stdio_definitions"))] extern "C" { pub fn printf(format: *const i8, ...) -> i32; } #[cfg_attr(unix, link(name = "c"))] #[cfg_attr(target_env = "msvc", link(name = "msvcrt"))] extern "C" { pub fn puts(s: *const i8) -> i32; pub fn malloc(size: usize) -> *mut u8; pub fn free(ptr: *mut u8); pub fn memcpy(dst: *mut u8, src: *const u8, size: usize); pub fn memmove(dst: *mut u8, src: *const u8, size: usize); pub fn strncpy(dst: *mut u8, src: *const u8, size: usize); } } #[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] } } extern "C" { type VaListImpl; } #[lang = "va_list"] #[repr(transparent)] pub struct VaList<'a>(&'a mut VaListImpl); #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] pub macro stringify($($t:tt)*) { /* compiler built-in */ } #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] pub macro file() { /* compiler built-in */ } #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] pub macro line() { /* compiler built-in */ } #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] pub macro cfg() { /* compiler built-in */ } #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] pub macro asm() { /* compiler built-in */ } #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] pub macro global_asm() { /* compiler built-in */ } pub static A_STATIC: u8 = 42; #[lang = "panic_location"] struct PanicLocation { file: &'static str, line: u32, column: u32, } #[no_mangle] #[cfg(not(all(windows, target_env = "gnu")))] pub fn get_tls() -> u8 { #[thread_local] static A: u8 = 42; A }