-// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
-
-#![feature(
- no_core, unboxed_closures, start, lang_items, box_syntax, never_type, linkage,
- extern_types, thread_local
-)]
+#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, box_syntax)]
#![no_core]
#![allow(dead_code, non_camel_case_types)]
use mini_core::*;
use mini_core::libc::*;
-unsafe extern "C" fn my_puts(s: *const u8) {
- puts(s);
+macro_rules! assert {
+ ($e:expr) => {
+ if !$e {
+ panic(stringify!(! $e));
+ }
+ };
+}
+
+macro_rules! assert_eq {
+ ($l:expr, $r: expr) => {
+ if $l != $r {
+ panic(stringify!($l != $r));
+ }
+ }
}
#[lang = "termination"]
fn report(self) -> i32 {
unsafe {
NUM = 6 * 7 + 1 + (1u8 == 1u8) as u8; // 44
- *NUM_REF as i32
+ assert_eq!(*NUM_REF as i32, 44);
}
+ 0
}
}
impl SomeTrait for &'static str {
fn object_safe(&self) {
unsafe {
- puts(*self as *const str as *const u8);
+ puts(*self as *const str as *const i8);
}
}
}
impl Drop for NoisyDrop {
fn drop(&mut self) {
unsafe {
- puts(self.text as *const str as *const u8);
+ puts(self.text as *const str as *const i8);
}
}
}
impl Drop for NoisyDropInner {
fn drop(&mut self) {
unsafe {
- puts("Inner got dropped!\0" as *const str as *const u8);
+ puts("Inner got dropped!\0" as *const str as *const i8);
}
}
}
argv: *const *const u8,
) -> isize {
if argc == 3 {
- unsafe { puts(*argv); }
- unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const u8)); }
- unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const u8)); }
+ unsafe { puts(*argv as *const i8); }
+ unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const i8)); }
+ unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const i8)); }
}
- main().report();
- 0
+ main().report() as isize
}
static mut NUM: u8 = 6 * 7;
static NUM_REF: &'static u8 = unsafe { &NUM };
-macro_rules! assert {
- ($e:expr) => {
- if !$e {
- panic(stringify!(! $e));
- }
- };
-}
-
-macro_rules! assert_eq {
- ($l:expr, $r: expr) => {
- if $l != $r {
- panic(stringify!($l != $r));
- }
- }
-}
-
-struct Unique<T: ?Sized> {
- pointer: *const T,
- _marker: PhantomData<T>,
-}
-
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
unsafe fn zeroed<T>() -> T {
let mut uninit = MaybeUninit { uninit: () };
return_u128_pair();
}
+#[allow(unreachable_code)] // FIXME false positive
fn main() {
take_unique(Unique {
- pointer: 0 as *const (),
+ pointer: unsafe { NonNull(1 as *mut ()) },
_marker: PhantomData,
});
take_f32(0.1);
printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8);
let hello: &[u8] = b"Hello\0" as &[u8; 6];
- let ptr: *const u8 = hello as *const [u8] as *const u8;
+ let ptr: *const i8 = hello as *const [u8] as *const i8;
puts(ptr);
let world: Box<&str> = box "World!\0";
- puts(*world as *const str as *const u8);
+ puts(*world as *const str as *const i8);
world as Box<dyn SomeTrait>;
assert_eq!(intrinsics::bitreverse(0b10101000u8), 0b00010101u8);
assert!(intrinsics::needs_drop::<NoisyDrop>());
Unique {
- pointer: 0 as *const &str,
+ pointer: NonNull(1 as *mut &str),
_marker: PhantomData,
} as Unique<dyn SomeTrait>;
assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42);
- extern {
- #[linkage = "weak"]
- static ABC: *const u8;
- }
-
+ #[cfg(not(any(jit, windows)))]
{
extern {
- #[linkage = "weak"]
+ #[linkage = "extern_weak"]
static ABC: *const u8;
}
- }
- unsafe { assert_eq!(ABC as usize, 0); }
+ {
+ extern {
+ #[linkage = "extern_weak"]
+ static ABC: *const u8;
+ }
+ }
+
+ unsafe { assert_eq!(ABC as usize, 0); }
+ }
&mut (|| Some(0 as *const ())) as &mut dyn FnMut() -> Option<*const ()>;
assert_eq!(f2 as i8, -128);
assert_eq!(f2 as u8, 0);
+ let amount = 0;
+ assert_eq!(1u128 << amount, 1);
+
static ANOTHER_STATIC: &u8 = &A_STATIC;
assert_eq!(*ANOTHER_STATIC, 42);
let slice_ptr = &[] as *const [u8];
slice_ptr as *const u8;
- #[cfg(not(jit))]
+ let repeat = [Some(42); 2];
+ assert_eq!(repeat[0], Some(42));
+ assert_eq!(repeat[1], Some(42));
+
+ from_decimal_string();
+
+ #[cfg(not(any(jit, windows)))]
test_tls();
+
+ #[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
+ unsafe {
+ global_asm_test();
+ }
+
+ // Both statics have a reference that points to the same anonymous allocation.
+ static REF1: &u8 = &42;
+ static REF2: &u8 = REF1;
+ assert_eq!(*REF1, *REF2);
+}
+
+#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
+extern "C" {
+ fn global_asm_test();
+}
+
+#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
+global_asm! {
+ "
+ .global global_asm_test
+ global_asm_test:
+ // comment that would normally be removed by LLVM
+ ret
+ "
}
#[repr(C)]
// TLS of main thread must not have been changed by the other thread.
assert_eq!(TLS, 42);
- puts("TLS works!\n\0" as *const str as *const u8);
+ puts("TLS works!\n\0" as *const str as *const i8);
}
}
intrinsics::abort();
}
}
+
+fn from_decimal_string() {
+ loop {
+ let multiplier = 1;
+
+ take_multiplier_ref(&multiplier);
+
+ if multiplier == 1 {
+ break;
+ }
+
+ unreachable();
+ }
+}
+
+fn take_multiplier_ref(_multiplier: &u128) {}
+
+fn unreachable() -> ! {
+ panic("unreachable")
+}