pub fn abort() -> !;
pub fn size_of<T>() -> usize;
pub fn size_of_val<T: ?::Sized>(val: &T) -> usize;
+ pub fn min_align_of<T>() -> usize;
+ pub fn min_align_of_val<T: ?::Sized>(val: &T) -> usize;
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
pub fn transmute<T, U>(e: T) -> U;
pub fn uninit<T>() -> T;
static mut NUM: u8 = 6 * 7;
static NUM_REF: &'static u8 = unsafe { &NUM };
+macro_rules! assert {
+ ($e:expr) => {
+ if !$e {
+ panic(&(stringify!(! $e), file!(), line!(), 0));
+ }
+ };
+}
+
+macro_rules! assert_eq {
+ ($l:expr, $r: expr) => {
+ if $l != $r {
+ panic(&(stringify!($l != $r), file!(), line!(), 0));
+ }
+ }
+}
+
fn main() {
unsafe {
let hello: &[u8] = b"Hello\0" as &[u8; 6];
puts(*world as *const str as *const u8);
}
- if intrinsics::size_of_val(hello) as u8 != 6 {
- panic(&("", "", 0, 0));
- };
+ assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
let chars = &['C', 'h', 'a', 'r', 's'];
let chars = chars as &[char];
- if intrinsics::size_of_val(chars) as u8 != 4 * 5 {
- panic(&("", "", 0, 0));
- }
+ assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5);
let a: &dyn SomeTrait = &"abc\0";
a.object_safe();
- if intrinsics::size_of_val(a) as u8 != 16 {
- panic(&("", "", 0, 0));
- }
+ assert_eq!(intrinsics::size_of_val(a) as u8, 16);
+ assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
- if intrinsics::size_of_val(&0u32) as u8 != 4 {
- panic(&("", "", 0, 0));
- }
+ assert_eq!(intrinsics::min_align_of::<u16>() as u8, 2);
+ assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8);
- if intrinsics::needs_drop::<u8>() {
- panic(&("", "", 0, 0));
- }
-
- if !intrinsics::needs_drop::<NoisyDrop>() {
- panic(&("", "", 0, 0));
- }
+ assert!(!intrinsics::needs_drop::<u8>());
+ assert!(intrinsics::needs_drop::<NoisyDrop>());
}
let _ = NoisyDrop {
};
ret.write_cvalue(fx, CValue::ByVal(size, usize_layout));
}
- "type_id" => {
- assert_eq!(args.len(), 0);
- let type_id = fx.tcx.type_id_hash(substs.type_at(0));
- let type_id = CValue::const_val(fx, u64_layout.ty, type_id as i64);
- ret.write_cvalue(fx, type_id);
- }
"min_align_of" => {
assert_eq!(args.len(), 0);
let min_align = fx.layout_of(substs.type_at(0)).align.abi();
let min_align = CValue::const_val(fx, usize_layout.ty, min_align as i64);
ret.write_cvalue(fx, min_align);
}
+ "min_align_of_val" => {
+ assert_eq!(args.len(), 1);
+ let layout = fx.layout_of(substs.type_at(0));
+ let align = match &layout.ty.sty {
+ _ if !layout.is_unsized() => {
+ fx.bcx.ins().iconst(fx.module.pointer_type(), layout.align.abi() as i64)
+ }
+ ty::Slice(elem) => {
+ let align = fx.layout_of(elem).align.abi() as i64;
+ fx.bcx.ins().iconst(fx.module.pointer_type(), align)
+ }
+ ty::Dynamic(..) => crate::vtable::min_align_of_obj(fx, args[0]),
+ ty => unimplemented!("min_align_of_val for {:?}", ty),
+ };
+ ret.write_cvalue(fx, CValue::ByVal(align, usize_layout));
+ }
+ "type_id" => {
+ assert_eq!(args.len(), 0);
+ let type_id = fx.tcx.type_id_hash(substs.type_at(0));
+ let type_id = CValue::const_val(fx, u64_layout.ty, type_id as i64);
+ ret.write_cvalue(fx, type_id);
+ }
_ if intrinsic.starts_with("unchecked_") => {
assert_eq!(args.len(), 2);
let bin_op = match intrinsic {
)
}
+pub fn min_align_of_obj<'a, 'tcx: 'a>(
+ fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
+ val: CValue<'tcx>,
+) -> Value {
+ let (_ptr, vtable) = val.load_value_pair(fx);
+ let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
+ fx.bcx.ins().load(
+ pointer_ty(fx.tcx),
+ MemFlags::new(),
+ vtable,
+ (ALIGN_INDEX * usize_size) as i32,
+ )
+}
+
pub fn get_ptr_and_method_ref<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
arg: CValue<'tcx>,