1
Fork 0

Run rustfmt 0.9.0-nightly (69ad879 2018-07-27)

This commit is contained in:
bjorn3 2018-07-31 12:25:16 +02:00
parent 82dbd07806
commit f001808249
7 changed files with 603 additions and 318 deletions

View file

@ -62,16 +62,8 @@ fn cmp_raw_ptr(a: *const u8, b: *const u8) -> bool {
fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
(
a as u8,
a as u16,
a as u32,
a as usize,
a as i8,
a as i16,
a as i32,
a as isize,
b as u8,
b as u32
a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8,
b as u32,
)
}
@ -86,9 +78,7 @@ fn debug_tuple() -> DebugTuple {
}
fn size_of<T>() -> usize {
unsafe {
intrinsics::size_of::<T>()
}
unsafe { intrinsics::size_of::<T>() }
}
fn use_size_of() -> usize {
@ -111,31 +101,27 @@ fn use_const() -> u8 {
}
fn call_closure_3arg() {
(|_, _, _| {
})(0u8, 42u16, 0u8)
(|_, _, _| {})(0u8, 42u16, 0u8)
}
fn call_closure_2arg() {
(|_, _| {
})(0u8, 42u16)
(|_, _| {})(0u8, 42u16)
}
struct IsNotEmpty;
impl<'a, 'b> FnOnce<(&'a &'b [u16], )> for IsNotEmpty {
impl<'a, 'b> FnOnce<(&'a &'b [u16],)> for IsNotEmpty {
type Output = bool;
#[inline]
extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u16], )) -> bool {
extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u16],)) -> bool {
self.call_mut(arg)
}
}
impl<'a, 'b> FnMut<(&'a &'b [u16], )> for IsNotEmpty {
impl<'a, 'b> FnMut<(&'a &'b [u16],)> for IsNotEmpty {
#[inline]
extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u16], )) -> bool {
extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u16],)) -> bool {
true
}
}

View file

@ -2,7 +2,7 @@
#![no_core]
#![allow(dead_code)]
#[lang="sized"]
#[lang = "sized"]
pub trait Sized {}
#[lang = "unsize"]
@ -11,9 +11,9 @@ pub trait Unsize<T: ?Sized> {}
#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {}
impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
#[lang="copy"]
#[lang = "copy"]
pub unsafe trait Copy {}
unsafe impl Copy for bool {}
@ -30,10 +30,10 @@ unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}
#[lang="freeze"]
#[lang = "freeze"]
trait Freeze {}
#[lang="mul"]
#[lang = "mul"]
pub trait Mul<RHS = Self> {
type Output;
@ -49,7 +49,7 @@ impl Mul for u8 {
}
}
#[lang="bitor"]
#[lang = "bitor"]
pub trait BitOr<RHS = Self> {
type Output;
@ -80,18 +80,30 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
}
impl PartialEq for u8 {
fn eq(&self, other: &u8) -> bool { (*self) == (*other) }
fn ne(&self, other: &u8) -> bool { (*self) != (*other) }
fn eq(&self, other: &u8) -> bool {
(*self) == (*other)
}
fn ne(&self, other: &u8) -> bool {
(*self) != (*other)
}
}
impl PartialEq for char {
fn eq(&self, other: &char) -> bool { (*self) == (*other) }
fn ne(&self, other: &char) -> bool { (*self) != (*other) }
fn eq(&self, other: &char) -> bool {
(*self) == (*other)
}
fn ne(&self, other: &char) -> bool {
(*self) != (*other)
}
}
impl<T: ?Sized> PartialEq for *const T {
fn eq(&self, other: &*const T) -> bool { *self == *other }
fn ne(&self, other: &*const T) -> bool { *self != *other }
fn eq(&self, other: &*const T) -> bool {
*self == *other
}
fn ne(&self, other: &*const T) -> bool {
*self != *other
}
}
#[lang = "fn_once"]
@ -104,11 +116,11 @@ pub trait FnOnce<Args> {
#[lang = "fn_mut"]
#[rustc_paren_sugar]
pub trait FnMut<Args> : FnOnce<Args> {
pub trait FnMut<Args>: FnOnce<Args> {
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}
#[lang="panic"]
#[lang = "panic"]
pub fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
loop {}
}

View file

@ -5,14 +5,22 @@ use rustc_target::spec::abi::Abi;
use crate::prelude::*;
pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_ty: Ty<'tcx>) -> Signature {
pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn_ty: Ty<'tcx>,
) -> Signature {
let sig = ty_fn_sig(tcx, fn_ty);
assert!(!sig.variadic, "Variadic function are not yet supported");
let (call_conv, inputs, _output): (CallConv, Vec<Ty>, Ty) = match sig.abi {
Abi::Rust => (CallConv::Fast, sig.inputs().to_vec(), sig.output()),
Abi::C => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
Abi::RustCall => {
println!("rust-call sig: {:?} inputs: {:?} output: {:?}", sig, sig.inputs(), sig.output());
println!(
"rust-call sig: {:?} inputs: {:?} output: {:?}",
sig,
sig.inputs(),
sig.output()
);
assert_eq!(sig.inputs().len(), 2);
let extra_args = match sig.inputs().last().unwrap().sty {
ty::TyTuple(ref tupled_arguments) => tupled_arguments,
@ -20,11 +28,7 @@ pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_ty: Ty<
};
let mut inputs: Vec<Ty> = vec![sig.inputs()[0]];
inputs.extend(extra_args.into_iter());
(
CallConv::Fast,
inputs,
sig.output(),
)
(CallConv::Fast, inputs, sig.output())
}
Abi::System => bug!("system abi should be selected elsewhere"),
Abi::RustIntrinsic => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
@ -50,10 +54,7 @@ pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_ty: Ty<
}
}
fn ty_fn_sig<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty: Ty<'tcx>
) -> ty::FnSig<'tcx> {
fn ty_fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> ty::FnSig<'tcx> {
let sig = match ty.sty {
ty::TyFnDef(..) |
// Shims currently have type TyFnPtr. Not sure this should remain.
@ -104,11 +105,16 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types());
let fn_ty = inst.ty(self.tcx);
let sig = cton_sig_from_fn_ty(self.tcx, fn_ty);
let def_path_based_names = ::rustc_mir::monomorphize::item::DefPathBasedNames::new(self.tcx, false, false);
let def_path_based_names =
::rustc_mir::monomorphize::item::DefPathBasedNames::new(self.tcx, false, false);
let mut name = String::new();
def_path_based_names.push_instance_as_string(inst, &mut name);
let func_id = self.module.declare_function(&name, Linkage::Import, &sig).unwrap();
self.module.declare_func_in_func(func_id, &mut self.bcx.func)
let func_id = self
.module
.declare_function(&name, Linkage::Import, &sig)
.unwrap();
self.module
.declare_func_in_func(func_id, &mut self.bcx.func)
}
fn lib_call(
@ -124,8 +130,13 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
call_conv: CallConv::SystemV,
argument_bytes: None,
};
let func_id = self.module.declare_function(&name, Linkage::Import, &sig).unwrap();
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
let func_id = self
.module
.declare_function(&name, Linkage::Import, &sig)
.unwrap();
let func_ref = self
.module
.declare_func_in_func(func_id, &mut self.bcx.func);
let call_inst = self.bcx.ins().call(func_ref, args);
if output_ty.is_none() {
return None;
@ -135,8 +146,20 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
Some(results[0])
}
pub fn easy_call(&mut self, name: &str, args: &[CValue<'tcx>], return_ty: Ty<'tcx>) -> CValue<'tcx> {
let (input_tys, args): (Vec<_>, Vec<_>) = args.into_iter().map(|arg| (self.cton_type(arg.layout().ty).unwrap(), arg.load_value(self))).unzip();
pub fn easy_call(
&mut self,
name: &str,
args: &[CValue<'tcx>],
return_ty: Ty<'tcx>,
) -> CValue<'tcx> {
let (input_tys, args): (Vec<_>, Vec<_>) = args
.into_iter()
.map(|arg| {
(
self.cton_type(arg.layout().ty).unwrap(),
arg.load_value(self),
)
}).unzip();
let return_layout = self.layout_of(return_ty);
let return_ty = if let TypeVariants::TyTuple(tup) = return_ty.sty {
if !tup.is_empty() {
@ -209,7 +232,8 @@ pub fn codegen_fn_prelude<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, start_ebb
}).collect::<Vec<(Local, ArgKind, Ty)>>();
let ret_layout = fx.layout_of(fx.return_type());
fx.local_map.insert(RETURN_PLACE, CPlace::Addr(ret_param, ret_layout));
fx.local_map
.insert(RETURN_PLACE, CPlace::Addr(ret_param, ret_layout));
for (local, arg_kind, ty) in func_params {
let layout = fx.layout_of(ty);
@ -284,17 +308,18 @@ pub fn codegen_call<'a, 'tcx: 'a>(
for (i, _) in tupled_arguments.iter().enumerate() {
args.push(pack_arg.value_field(fx, mir::Field::new(i)));
}
},
}
_ => bug!("argument to function with \"rust-call\" ABI is not a tuple"),
}
println!("{:?} {:?}", pack_arg.layout().ty, args.iter().map(|a|a.layout().ty).collect::<Vec<_>>());
println!(
"{:?} {:?}",
pack_arg.layout().ty,
args.iter().map(|a| a.layout().ty).collect::<Vec<_>>()
);
args
} else {
args
.into_iter()
.map(|arg| {
trans_operand(fx, arg)
})
args.into_iter()
.map(|arg| trans_operand(fx, arg))
.collect::<Vec<_>>()
};
@ -326,7 +351,11 @@ pub fn codegen_call<'a, 'tcx: 'a>(
let dst = args[1];
let count = args[2].load_value(fx);
let byte_amount = fx.bcx.ins().imul(count, elem_size);
fx.easy_call("memmove", &[dst, src, CValue::ByVal(byte_amount, usize_layout)], nil_ty);
fx.easy_call(
"memmove",
&[dst, src, CValue::ByVal(byte_amount, usize_layout)],
nil_ty,
);
unimplemented!("copy");
}
"discriminant_value" => {
@ -362,12 +391,24 @@ pub fn codegen_call<'a, 'tcx: 'a>(
_ => unimplemented!("intrinsic {}", intrinsic),
};
let res = match ret.layout().ty.sty {
TypeVariants::TyUint(_) => {
crate::base::trans_int_binop(fx, bin_op, args[0], args[1], ret.layout().ty, false, false)
}
TypeVariants::TyInt(_) => {
crate::base::trans_int_binop(fx, bin_op, args[0], args[1], ret.layout().ty, true, false)
}
TypeVariants::TyUint(_) => crate::base::trans_int_binop(
fx,
bin_op,
args[0],
args[1],
ret.layout().ty,
false,
false,
),
TypeVariants::TyInt(_) => crate::base::trans_int_binop(
fx,
bin_op,
args[0],
args[1],
ret.layout().ty,
true,
false,
),
_ => panic!(),
};
ret.write_cvalue(fx, res);
@ -402,7 +443,10 @@ pub fn codegen_call<'a, 'tcx: 'a>(
let uninit_val = uninit_place.to_cvalue(fx);
ret.write_cvalue(fx, uninit_val);
}
_ => fx.tcx.sess.fatal(&format!("unsupported intrinsic {}", intrinsic)),
_ => fx
.tcx
.sess
.fatal(&format!("unsupported intrinsic {}", intrinsic)),
}
if let Some((_, dest)) = *destination {
let ret_ebb = fx.get_ebb(dest);
@ -419,13 +463,15 @@ pub fn codegen_call<'a, 'tcx: 'a>(
None => fx.bcx.ins().iconst(types::I64, 0),
};
let call_args = Some(return_ptr).into_iter().chain(args.into_iter().map(|arg| {
if fx.cton_type(arg.layout().ty).is_some() {
arg.load_value(fx)
} else {
arg.force_stack(fx)
}
})).collect::<Vec<_>>();
let call_args = Some(return_ptr)
.into_iter()
.chain(args.into_iter().map(|arg| {
if fx.cton_type(arg.layout().ty).is_some() {
arg.load_value(fx)
} else {
arg.force_stack(fx)
}
})).collect::<Vec<_>>();
match func {
CValue::Func(func, _) => {
@ -434,7 +480,9 @@ pub fn codegen_call<'a, 'tcx: 'a>(
func => {
let func_ty = func.layout().ty;
let func = func.load_value(fx);
let sig = fx.bcx.import_signature(cton_sig_from_fn_ty(fx.tcx, func_ty));
let sig = fx
.bcx
.import_signature(cton_sig_from_fn_ty(fx.tcx, func_ty));
fx.bcx.ins().call_indirect(sig, func, &call_args);
}
}

View file

@ -1,6 +1,10 @@
use crate::prelude::*;
pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, context: &mut Context, mono_item: MonoItem<'tcx>) {
pub fn trans_mono_item<'a, 'tcx: 'a>(
cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>,
context: &mut Context,
mono_item: MonoItem<'tcx>,
) {
let tcx = cx.tcx;
match mono_item {
@ -11,7 +15,11 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
} => {
let mut mir = ::std::io::Cursor::new(Vec::new());
::rustc_mir::util::write_mir_pretty(tcx, Some(def_id), &mut mir).unwrap();
tcx.sess.warn(&format!("{:?}:\n\n{}", inst, String::from_utf8_lossy(&mir.into_inner())));
tcx.sess.warn(&format!(
"{:?}:\n\n{}",
inst,
String::from_utf8_lossy(&mir.into_inner())
));
let fn_ty = inst.ty(tcx);
let fn_ty = tcx.subst_and_normalize_erasing_regions(
@ -23,15 +31,23 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
let func_id = {
// WARNING: keep in sync with FunctionCx::get_function_ref
let def_path_based_names = ::rustc_mir::monomorphize::item::DefPathBasedNames::new(cx.tcx, false, false);
let def_path_based_names =
::rustc_mir::monomorphize::item::DefPathBasedNames::new(
cx.tcx, false, false,
);
let mut name = String::new();
def_path_based_names.push_instance_as_string(inst, &mut name);
cx.module.declare_function(&name, Linkage::Export, &sig).unwrap()
cx.module
.declare_function(&name, Linkage::Export, &sig)
.unwrap()
};
let mut f = Function::with_name_signature(ExternalName::user(0, func_id.index() as u32), sig);
let mut f = Function::with_name_signature(
ExternalName::user(0, func_id.index() as u32),
sig,
);
let comments = match trans_fn(cx, &mut f, inst){
let comments = match trans_fn(cx, &mut f, inst) {
Ok(comments) => comments,
Err(err) => {
tcx.sess.err(&err);
@ -41,7 +57,8 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
let mut writer = crate::pretty_clif::CommentWriter(comments);
let mut cton = String::new();
::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &f, None).unwrap();
::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &f, None)
.unwrap();
tcx.sess.warn(&cton);
let flags = settings::Flags::new(settings::builder());
@ -49,8 +66,15 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
Ok(_) => {}
Err(err) => {
tcx.sess.err(&format!("{:?}", err));
let pretty_error = ::cranelift::codegen::print_errors::pretty_verifier_error(&f, None, Some(Box::new(writer)), &err);
tcx.sess.fatal(&format!("cretonne verify error:\n{}", pretty_error));
let pretty_error =
::cranelift::codegen::print_errors::pretty_verifier_error(
&f,
None,
Some(Box::new(writer)),
&err,
);
tcx.sess
.fatal(&format!("cretonne verify error:\n{}", pretty_error));
}
}
@ -60,14 +84,27 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
context.clear();
}
inst => cx.tcx.sess.warn(&format!("Unimplemented instance {:?}", inst)),
}
MonoItem::Static(def_id) => cx.tcx.sess.err(&format!("Unimplemented static mono item {:?}", def_id)),
MonoItem::GlobalAsm(node_id) => cx.tcx.sess.err(&format!("Unimplemented global asm mono item {:?}", node_id)),
inst => cx
.tcx
.sess
.warn(&format!("Unimplemented instance {:?}", inst)),
},
MonoItem::Static(def_id) => cx
.tcx
.sess
.err(&format!("Unimplemented static mono item {:?}", def_id)),
MonoItem::GlobalAsm(node_id) => cx
.tcx
.sess
.err(&format!("Unimplemented global asm mono item {:?}", node_id)),
}
}
pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &mut Function, instance: Instance<'tcx>) -> Result<HashMap<Inst, String>, String> {
pub fn trans_fn<'a, 'tcx: 'a>(
cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>,
f: &mut Function,
instance: Instance<'tcx>,
) -> Result<HashMap<Inst, String>, String> {
let mir = cx.tcx.optimized_mir(instance.def_id());
let mut func_ctx = FunctionBuilderContext::new();
let mut bcx: FunctionBuilder<Variable> = FunctionBuilder::new(f, &mut func_ctx);
@ -98,7 +135,9 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
crate::abi::codegen_fn_prelude(fx, start_ebb);
fx.bcx.ins().jump(*fx.ebb_map.get(&START_BLOCK).unwrap(), &[]);
fx.bcx
.ins()
.jump(*fx.ebb_map.get(&START_BLOCK).unwrap(), &[]);
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
let ebb = fx.get_ebb(bb);
@ -110,7 +149,11 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
}
let mut terminator_head = "\n".to_string();
bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
bb_data
.terminator()
.kind
.fmt_head(&mut terminator_head)
.unwrap();
let inst = fx.bcx.func.layout.last_inst(ebb).unwrap();
fx.add_comment(inst, terminator_head);
@ -122,7 +165,13 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
TerminatorKind::Return => {
fx.bcx.ins().return_(&[]);
}
TerminatorKind::Assert { cond, expected, msg: _, target, cleanup: _ } => {
TerminatorKind::Assert {
cond,
expected,
msg: _,
target,
cleanup: _,
} => {
let cond = trans_operand(fx, cond).load_value(fx);
let target = fx.get_ebb(*target);
if *expected {
@ -133,7 +182,12 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
fx.bcx.ins().trap(TrapCode::User(!0));
}
TerminatorKind::SwitchInt { discr, switch_ty: _, values, targets } => {
TerminatorKind::SwitchInt {
discr,
switch_ty: _,
values,
targets,
} => {
let discr = trans_operand(fx, discr).load_value(fx);
let mut jt_data = JumpTableData::new();
for (i, value) in values.iter().enumerate() {
@ -145,15 +199,20 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
let otherwise_ebb = fx.get_ebb(targets[targets.len() - 1]);
fx.bcx.ins().jump(otherwise_ebb, &[]);
}
TerminatorKind::Call { func, args, destination, cleanup: _ } => {
TerminatorKind::Call {
func,
args,
destination,
cleanup: _,
} => {
crate::abi::codegen_call(fx, func, args, destination);
}
TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::Unreachable => {
fx.bcx.ins().trap(TrapCode::User(!0));
}
TerminatorKind::Yield { .. } |
TerminatorKind::FalseEdges { .. } |
TerminatorKind::FalseUnwind { .. } => {
TerminatorKind::Yield { .. }
| TerminatorKind::FalseEdges { .. }
| TerminatorKind::FalseUnwind { .. } => {
bug!("shouldn't exist at trans {:?}", bb_data.terminator());
}
TerminatorKind::Drop { target, .. } | TerminatorKind::DropAndReplace { target, .. } => {
@ -174,14 +233,21 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
Ok(fx.comments.clone())
}
fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &Statement<'tcx>) -> Result<(), String> {
fn trans_stmt<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
cur_ebb: Ebb,
stmt: &Statement<'tcx>,
) -> Result<(), String> {
fx.tcx.sess.warn(&format!("stmt {:?}", stmt));
let inst = fx.bcx.func.layout.last_inst(cur_ebb).unwrap();
fx.add_comment(inst, format!("{:?}", stmt));
match &stmt.kind {
StatementKind::SetDiscriminant { place, variant_index } => {
StatementKind::SetDiscriminant {
place,
variant_index,
} => {
let place = trans_place(fx, place);
let layout = place.layout();
if layout.for_variant(&*fx, *variant_index).abi == layout::Abi::Uninhabited {
@ -193,7 +259,10 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &
}
layout::Variants::Tagged { .. } => {
let ptr = place.place_field(fx, mir::Field::new(0));
let to = layout.ty.ty_adt_def().unwrap()
let to = layout
.ty
.ty_adt_def()
.unwrap()
.discriminant_for_variant(fx.tcx, *variant_index)
.val;
let discr = CValue::const_val(fx, ptr.layout().ty, to as u64 as i64);
@ -288,7 +357,7 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &
UnOp::Neg => match ty.sty {
TypeVariants::TyFloat(_) => fx.bcx.ins().fneg(val),
_ => unimplemented!("un op Neg for {:?}", ty),
}
},
};
lval.write_cvalue(fx, CValue::ByVal(res, layout));
}
@ -306,50 +375,66 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &
let operand = trans_operand(fx, operand);
let from_ty = operand.layout().ty;
match (&from_ty.sty, &to_ty.sty) {
(TypeVariants::TyRef(..), TypeVariants::TyRef(..)) |
(TypeVariants::TyRef(..), TypeVariants::TyRawPtr(..)) |
(TypeVariants::TyRawPtr(..), TypeVariants::TyRef(..)) |
(TypeVariants::TyRawPtr(..), TypeVariants::TyRawPtr(..)) => {
(TypeVariants::TyRef(..), TypeVariants::TyRef(..))
| (TypeVariants::TyRef(..), TypeVariants::TyRawPtr(..))
| (TypeVariants::TyRawPtr(..), TypeVariants::TyRef(..))
| (TypeVariants::TyRawPtr(..), TypeVariants::TyRawPtr(..)) => {
lval.write_cvalue(fx, operand.unchecked_cast_to(dest_layout));
}
(TypeVariants::TyChar, TypeVariants::TyUint(_)) |
(TypeVariants::TyUint(_), TypeVariants::TyInt(_)) |
(TypeVariants::TyUint(_), TypeVariants::TyUint(_)) => {
(TypeVariants::TyChar, TypeVariants::TyUint(_))
| (TypeVariants::TyUint(_), TypeVariants::TyInt(_))
| (TypeVariants::TyUint(_), TypeVariants::TyUint(_)) => {
let from = operand.load_value(fx);
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, false);
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
}
(TypeVariants::TyInt(_), TypeVariants::TyInt(_)) |
(TypeVariants::TyInt(_), TypeVariants::TyUint(_)) => {
(TypeVariants::TyInt(_), TypeVariants::TyInt(_))
| (TypeVariants::TyInt(_), TypeVariants::TyUint(_)) => {
let from = operand.load_value(fx);
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, true);
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
}
_ => return Err(format!("rval misc {:?} {:?}", operand, to_ty)),
}
},
Rvalue::Cast(CastKind::ClosureFnPointer, operand, ty) => unimplemented!("rval closure_fn_ptr {:?} {:?}", operand, ty),
Rvalue::Cast(CastKind::Unsize, operand, ty) => return Err(format!("rval unsize {:?} {:?}", operand, ty)),
}
Rvalue::Cast(CastKind::ClosureFnPointer, operand, ty) => {
unimplemented!("rval closure_fn_ptr {:?} {:?}", operand, ty)
}
Rvalue::Cast(CastKind::Unsize, operand, ty) => {
return Err(format!("rval unsize {:?} {:?}", operand, ty))
}
Rvalue::Discriminant(place) => {
let place = trans_place(fx, place).to_cvalue(fx);
let discr = trans_get_discriminant(fx, place, dest_layout);
lval.write_cvalue(fx, discr);
}
Rvalue::Repeat(operand, times) => unimplemented!("rval repeat {:?} {:?}", operand, times),
Rvalue::Repeat(operand, times) => {
unimplemented!("rval repeat {:?} {:?}", operand, times)
}
Rvalue::Len(lval) => return Err(format!("rval len {:?}", lval)),
Rvalue::NullaryOp(NullOp::Box, ty) => unimplemented!("rval box {:?}", ty),
Rvalue::NullaryOp(NullOp::SizeOf, ty) => unimplemented!("rval size_of {:?}", ty),
Rvalue::Aggregate(_, _) => bug!("shouldn't exist at trans {:?}", rval),
}
}
StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Nop | StatementKind::ReadForMatch(_) | StatementKind::Validate(_, _) | StatementKind::EndRegion(_) | StatementKind::UserAssertTy(_, _) => {}
StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Nop
| StatementKind::ReadForMatch(_)
| StatementKind::Validate(_, _)
| StatementKind::EndRegion(_)
| StatementKind::UserAssertTy(_, _) => {}
StatementKind::InlineAsm { .. } => fx.tcx.sess.fatal("Inline assembly is not supported"),
}
Ok(())
}
pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value: CValue<'tcx>, dest_layout: TyLayout<'tcx>) -> CValue<'tcx> {
pub fn trans_get_discriminant<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
value: CValue<'tcx>,
dest_layout: TyLayout<'tcx>,
) -> CValue<'tcx> {
let layout = value.layout();
if layout.abi == layout::Abi::Uninhabited {
@ -357,13 +442,12 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
}
match layout.variants {
layout::Variants::Single { index } => {
let discr_val = layout.ty.ty_adt_def().map_or(
index as u128,
|def| def.discriminant_for_variant(fx.tcx, index).val);
let discr_val = layout.ty.ty_adt_def().map_or(index as u128, |def| {
def.discriminant_for_variant(fx.tcx, index).val
});
return CValue::const_val(fx, dest_layout.ty, discr_val as u64 as i64);
}
layout::Variants::Tagged { .. } |
layout::Variants::NicheFilling { .. } => {},
layout::Variants::Tagged { .. } | layout::Variants::NicheFilling { .. } => {}
}
let discr = value.value_field(fx, mir::Field::new(0));
@ -374,7 +458,7 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
layout::Variants::Tagged { ref tag, .. } => {
let signed = match tag.value {
layout::Int(_, signed) => signed,
_ => false
_ => false,
};
let val = cton_intcast(fx, lldiscr, discr_ty, dest_layout.ty, signed);
return CValue::ByVal(val, dest_layout);
@ -388,9 +472,18 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
let niche_llty = fx.cton_type(discr_ty).unwrap();
if niche_variants.start() == niche_variants.end() {
let dest_cton_ty = fx.cton_type(dest_layout.ty).unwrap();
let b = fx.bcx.ins().icmp_imm(IntCC::Equal, lldiscr, niche_start as u64 as i64);
let if_true = fx.bcx.ins().iconst(dest_cton_ty, *niche_variants.start() as u64 as i64);
let if_false = fx.bcx.ins().iconst(dest_cton_ty, dataful_variant as u64 as i64);
let b = fx
.bcx
.ins()
.icmp_imm(IntCC::Equal, lldiscr, niche_start as u64 as i64);
let if_true = fx
.bcx
.ins()
.iconst(dest_cton_ty, *niche_variants.start() as u64 as i64);
let if_false = fx
.bcx
.ins()
.iconst(dest_cton_ty, dataful_variant as u64 as i64);
let val = fx.bcx.ins().select(b, if_true, if_false);
return CValue::ByVal(val, dest_layout);
} else {
@ -398,9 +491,16 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
let delta = niche_start.wrapping_sub(*niche_variants.start() as u128);
let delta = fx.bcx.ins().iconst(niche_llty, delta as u64 as i64);
let lldiscr = fx.bcx.ins().isub(lldiscr, delta);
let b = fx.bcx.ins().icmp_imm(IntCC::UnsignedLessThanOrEqual, lldiscr, *niche_variants.end() as u64 as i64);
let b = fx.bcx.ins().icmp_imm(
IntCC::UnsignedLessThanOrEqual,
lldiscr,
*niche_variants.end() as u64 as i64,
);
let if_true = cton_intcast(fx, lldiscr, discr_ty, dest_layout.ty, false);
let if_false = fx.bcx.ins().iconst(niche_llty, dataful_variant as u64 as i64);
let if_false = fx
.bcx
.ins()
.iconst(niche_llty, dataful_variant as u64 as i64);
let val = fx.bcx.ins().select(b, if_true, if_false);
return CValue::ByVal(val, dest_layout);
}
@ -447,7 +547,13 @@ macro_rules! binop_match {
}}
}
fn trans_bool_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>) -> CValue<'tcx> {
fn trans_bool_binop<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
bin_op: BinOp,
lhs: CValue<'tcx>,
rhs: CValue<'tcx>,
ty: Ty<'tcx>,
) -> CValue<'tcx> {
let res = binop_match! {
fx, bin_op, false, lhs, rhs, ty, "bool";
Add (_) bug;
@ -474,7 +580,15 @@ fn trans_bool_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
res
}
pub fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>, signed: bool, _checked: bool) -> CValue<'tcx> {
pub fn trans_int_binop<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
bin_op: BinOp,
lhs: CValue<'tcx>,
rhs: CValue<'tcx>,
ty: Ty<'tcx>,
signed: bool,
_checked: bool,
) -> CValue<'tcx> {
let res = binop_match! {
fx, bin_op, signed, lhs, rhs, ty, "int/uint";
Add (_) iadd;
@ -509,7 +623,13 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinO
res
}
fn trans_float_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>) -> CValue<'tcx> {
fn trans_float_binop<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
bin_op: BinOp,
lhs: CValue<'tcx>,
rhs: CValue<'tcx>,
ty: Ty<'tcx>,
) -> CValue<'tcx> {
let res = binop_match! {
fx, bin_op, false, lhs, rhs, ty, "float";
Add (_) fadd;
@ -544,7 +664,13 @@ fn trans_float_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
res
}
fn trans_char_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>) -> CValue<'tcx> {
fn trans_char_binop<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
bin_op: BinOp,
lhs: CValue<'tcx>,
rhs: CValue<'tcx>,
ty: Ty<'tcx>,
) -> CValue<'tcx> {
let res = binop_match! {
fx, bin_op, false, lhs, rhs, ty, "char";
Add (_) bug;
@ -571,7 +697,14 @@ fn trans_char_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
res
}
fn trans_ptr_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>, _checked: bool) -> CValue<'tcx> {
fn trans_ptr_binop<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
bin_op: BinOp,
lhs: CValue<'tcx>,
rhs: CValue<'tcx>,
ty: Ty<'tcx>,
_checked: bool,
) -> CValue<'tcx> {
binop_match! {
fx, bin_op, false, lhs, rhs, ty, "ptr";
Add (_) bug;
@ -596,41 +729,66 @@ fn trans_ptr_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, l
}
}
pub fn trans_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, place: &Place<'tcx>) -> CPlace<'tcx> {
pub fn trans_place<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
place: &Place<'tcx>,
) -> CPlace<'tcx> {
match place {
Place::Local(local) => fx.get_local_place(*local),
Place::Promoted(promoted) => crate::constant::trans_promoted(fx, promoted.0),
Place::Static(static_) => unimplemented!("static place {:?} ty {:?}", static_.def_id, static_.ty),
Place::Static(static_) => {
unimplemented!("static place {:?} ty {:?}", static_.def_id, static_.ty)
}
Place::Projection(projection) => {
let base = trans_place(fx, &projection.base);
match projection.elem {
ProjectionElem::Deref => {
CPlace::Addr(base.to_cvalue(fx).load_value(fx), fx.layout_of(place.ty(&*fx.mir, fx.tcx).to_ty(fx.tcx)))
}
ProjectionElem::Field(field, _ty) => {
base.place_field(fx, field)
}
ProjectionElem::Index(local) => unimplemented!("projection index {:?} {:?}", projection.base, local),
ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false } => unimplemented!("projection const index {:?} offset {:?} not from end", projection.base, offset),
ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true } => unimplemented!("projection const index {:?} offset {:?} from end", projection.base, offset),
ProjectionElem::Subslice { from, to } => unimplemented!("projection subslice {:?} from {} to {}", projection.base, from, to),
ProjectionElem::Downcast(_adt_def, variant) => {
base.downcast_variant(fx, variant)
ProjectionElem::Deref => CPlace::Addr(
base.to_cvalue(fx).load_value(fx),
fx.layout_of(place.ty(&*fx.mir, fx.tcx).to_ty(fx.tcx)),
),
ProjectionElem::Field(field, _ty) => base.place_field(fx, field),
ProjectionElem::Index(local) => {
unimplemented!("projection index {:?} {:?}", projection.base, local)
}
ProjectionElem::ConstantIndex {
offset,
min_length: _,
from_end: false,
} => unimplemented!(
"projection const index {:?} offset {:?} not from end",
projection.base,
offset
),
ProjectionElem::ConstantIndex {
offset,
min_length: _,
from_end: true,
} => unimplemented!(
"projection const index {:?} offset {:?} from end",
projection.base,
offset
),
ProjectionElem::Subslice { from, to } => unimplemented!(
"projection subslice {:?} from {} to {}",
projection.base,
from,
to
),
ProjectionElem::Downcast(_adt_def, variant) => base.downcast_variant(fx, variant),
}
}
}
}
pub fn trans_operand<'a, 'tcx>(fx: &mut FunctionCx<'a, 'tcx>, operand: &Operand<'tcx>) -> CValue<'tcx> {
pub fn trans_operand<'a, 'tcx>(
fx: &mut FunctionCx<'a, 'tcx>,
operand: &Operand<'tcx>,
) -> CValue<'tcx> {
match operand {
Operand::Move(place) |
Operand::Copy(place) => {
Operand::Move(place) | Operand::Copy(place) => {
let cplace = trans_place(fx, place);
cplace.to_cvalue(fx)
},
Operand::Constant(const_) => {
crate::constant::trans_constant(fx, const_)
}
Operand::Constant(const_) => crate::constant::trans_constant(fx, const_),
}
}

View file

@ -2,7 +2,7 @@ use std::fmt;
use rustc_target::spec::{HasTargetSpec, Target};
use cranelift_module::{Module, DataId};
use cranelift_module::{DataId, Module};
use crate::prelude::*;
@ -21,36 +21,33 @@ impl EntityRef for Variable {
}
}
pub fn cton_type_from_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> Option<types::Type> {
pub fn cton_type_from_ty<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty: Ty<'tcx>,
) -> Option<types::Type> {
Some(match ty.sty {
TypeVariants::TyBool => types::I8,
TypeVariants::TyUint(size) => {
match size {
UintTy::U8 => types::I8,
UintTy::U16 => types::I16,
UintTy::U32 => types::I32,
UintTy::U64 => types::I64,
UintTy::U128 => unimplemented!("u128"),
UintTy::Usize => types::I64,
}
}
TypeVariants::TyInt(size) => {
match size {
IntTy::I8 => types::I8,
IntTy::I16 => types::I16,
IntTy::I32 => types::I32,
IntTy::I64 => types::I64,
IntTy::I128 => unimplemented!("i128"),
IntTy::Isize => types::I64,
}
}
TypeVariants::TyUint(size) => match size {
UintTy::U8 => types::I8,
UintTy::U16 => types::I16,
UintTy::U32 => types::I32,
UintTy::U64 => types::I64,
UintTy::U128 => unimplemented!("u128"),
UintTy::Usize => types::I64,
},
TypeVariants::TyInt(size) => match size {
IntTy::I8 => types::I8,
IntTy::I16 => types::I16,
IntTy::I32 => types::I32,
IntTy::I64 => types::I64,
IntTy::I128 => unimplemented!("i128"),
IntTy::Isize => types::I64,
},
TypeVariants::TyChar => types::I32,
TypeVariants::TyFloat(size) => {
match size {
FloatTy::F32 => types::I32,
FloatTy::F64 => types::I64,
}
}
TypeVariants::TyFloat(size) => match size {
FloatTy::F32 => types::I32,
FloatTy::F64 => types::I64,
},
TypeVariants::TyFnPtr(_) => types::I64,
TypeVariants::TyRawPtr(TypeAndMut { ty, mutbl: _ }) | TypeVariants::TyRef(_, ty, _) => {
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
@ -59,7 +56,7 @@ pub fn cton_type_from_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>
return None;
}
}
TypeVariants::TyParam(_) => bug!("{:?}: {:?}", ty, ty.sty),
TypeVariants::TyParam(_) => bug!("{:?}: {:?}", ty, ty.sty),
_ => return None,
})
}
@ -68,7 +65,7 @@ fn codegen_field<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
base: Value,
layout: TyLayout<'tcx>,
field: mir::Field
field: mir::Field,
) -> (Value, TyLayout<'tcx>) {
let field_offset = layout.fields.offset(field.index());
let field_ty = layout.field(&*fx, field.index());
@ -91,13 +88,14 @@ pub enum CValue<'tcx> {
impl<'tcx> CValue<'tcx> {
pub fn layout(&self) -> TyLayout<'tcx> {
match *self {
CValue::ByRef(_, layout) |
CValue::ByVal(_, layout) |
CValue::Func(_, layout) => layout
CValue::ByRef(_, layout) | CValue::ByVal(_, layout) | CValue::Func(_, layout) => layout,
}
}
pub fn force_stack<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value where 'tcx: 'a {
pub fn force_stack<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value
where
'tcx: 'a,
{
match self {
CValue::ByRef(value, _layout) => value,
CValue::ByVal(value, layout) => {
@ -116,16 +114,19 @@ impl<'tcx> CValue<'tcx> {
}
}
pub fn load_value<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value where 'tcx: 'a{
pub fn load_value<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value
where
'tcx: 'a,
{
match self {
CValue::ByRef(addr, layout) => {
let cton_ty = fx.cton_type(layout.ty).expect(&format!("load_value of type {:?}", layout.ty));
let cton_ty = fx
.cton_type(layout.ty)
.expect(&format!("load_value of type {:?}", layout.ty));
fx.bcx.ins().load(cton_ty, MemFlags::new(), addr, 0)
}
CValue::ByVal(value, _layout) => value,
CValue::Func(func, _layout) => {
fx.bcx.ins().func_addr(types::I64, func)
}
CValue::Func(func, _layout) => fx.bcx.ins().func_addr(types::I64, func),
}
}
@ -137,7 +138,10 @@ impl<'tcx> CValue<'tcx> {
}
}
pub fn value_field<'a>(self, fx: &mut FunctionCx<'a, 'tcx>, field: mir::Field) -> CValue<'tcx> where 'tcx: 'a {
pub fn value_field<'a>(self, fx: &mut FunctionCx<'a, 'tcx>, field: mir::Field) -> CValue<'tcx>
where
'tcx: 'a,
{
let (base, layout) = match self {
CValue::ByRef(addr, layout) => (addr, layout),
_ => bug!("place_field for {:?}", self),
@ -147,7 +151,14 @@ impl<'tcx> CValue<'tcx> {
CValue::ByRef(field_ptr, field_layout)
}
pub fn const_val<'a>(fx: &mut FunctionCx<'a, 'tcx>, ty: Ty<'tcx>, const_val: i64) -> CValue<'tcx> where 'tcx: 'a {
pub fn const_val<'a>(
fx: &mut FunctionCx<'a, 'tcx>,
ty: Ty<'tcx>,
const_val: i64,
) -> CValue<'tcx>
where
'tcx: 'a,
{
let cton_ty = fx.cton_type(ty).unwrap();
let layout = fx.layout_of(ty);
CValue::ByVal(fx.bcx.ins().iconst(cton_ty, const_val), layout)
@ -172,12 +183,15 @@ pub enum CPlace<'tcx> {
impl<'a, 'tcx: 'a> CPlace<'tcx> {
pub fn layout(&self) -> TyLayout<'tcx> {
match *self {
CPlace::Var(_, layout) |
CPlace::Addr(_, layout) => layout,
CPlace::Var(_, layout) | CPlace::Addr(_, layout) => layout,
}
}
pub fn from_stack_slot(fx: &mut FunctionCx<'a, 'tcx>, stack_slot: StackSlot, ty: Ty<'tcx>) -> CPlace<'tcx> {
pub fn from_stack_slot(
fx: &mut FunctionCx<'a, 'tcx>,
stack_slot: StackSlot,
ty: Ty<'tcx>,
) -> CPlace<'tcx> {
let layout = fx.layout_of(ty);
CPlace::Addr(fx.bcx.ins().stack_addr(types::I64, stack_slot, 0), layout)
}
@ -198,23 +212,25 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
pub fn write_cvalue(self, fx: &mut FunctionCx<'a, 'tcx>, from: CValue<'tcx>) {
match (&self.layout().ty.sty, &from.layout().ty.sty) {
(TypeVariants::TyRef(_, t, dest_mut), TypeVariants::TyRef(_, u, src_mut)) if (
if *dest_mut != ::rustc::hir::Mutability::MutImmutable && src_mut != dest_mut {
(TypeVariants::TyRef(_, t, dest_mut), TypeVariants::TyRef(_, u, src_mut))
if (if *dest_mut != ::rustc::hir::Mutability::MutImmutable && src_mut != dest_mut {
false
} else if t != u {
false
} else {
true
}
) => {
}) =>
{
// &mut T -> &T is allowed
// &'a T -> &'b T is allowed
}
_ => {
assert_eq!(
self.layout().ty, from.layout().ty,
self.layout().ty,
from.layout().ty,
"Can't write value of incompatible type to place {:?} {:?}\n\n{:#?}",
self.layout().ty.sty, from.layout().ty.sty,
self.layout().ty.sty,
from.layout().ty.sty,
fx,
);
}
@ -224,7 +240,7 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
CPlace::Var(var, _) => {
let data = from.load_value(fx);
fx.bcx.def_var(var, data)
},
}
CPlace::Addr(addr, layout) => {
let size = layout.size.bytes() as i32;
@ -235,17 +251,26 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
let from = from.expect_byref();
let mut offset = 0;
while size - offset >= 8 {
let byte = fx.bcx.ins().load(types::I64, MemFlags::new(), from.0, offset);
let byte = fx
.bcx
.ins()
.load(types::I64, MemFlags::new(), from.0, offset);
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
offset += 8;
}
while size - offset >= 4 {
let byte = fx.bcx.ins().load(types::I32, MemFlags::new(), from.0, offset);
let byte = fx
.bcx
.ins()
.load(types::I32, MemFlags::new(), from.0, offset);
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
offset += 4;
}
while offset < size {
let byte = fx.bcx.ins().load(types::I8, MemFlags::new(), from.0, offset);
let byte = fx
.bcx
.ins()
.load(types::I8, MemFlags::new(), from.0, offset);
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
offset += 1;
}
@ -275,7 +300,13 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
}
}
pub fn cton_intcast<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, val: Value, from: Ty<'tcx>, to: Ty<'tcx>, signed: bool) -> Value {
pub fn cton_intcast<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
val: Value,
from: Ty<'tcx>,
to: Ty<'tcx>,
signed: bool,
) -> Value {
let from = fx.cton_type(from).unwrap();
let to = fx.cton_type(to).unwrap();
if from == to {
@ -352,7 +383,8 @@ impl<'a, 'tcx> HasTargetSpec for &'a FunctionCx<'a, 'tcx> {
impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
pub fn monomorphize<T>(&self, value: &T) -> T
where T: TypeFoldable<'tcx>
where
T: TypeFoldable<'tcx>,
{
self.tcx.subst_and_normalize_erasing_regions(
self.param_substs,

View file

@ -1,29 +1,37 @@
use crate::prelude::*;
use rustc::ty::Const;
use rustc::mir::interpret::{ConstValue, GlobalId, AllocId, read_target_uint};
use rustc_mir::interpret::{CompileTimeEvaluator, Memory, MemoryKind};
use cranelift_module::*;
use crate::prelude::*;
use rustc::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalId};
use rustc::ty::Const;
use rustc_mir::interpret::{CompileTimeEvaluator, Memory, MemoryKind};
pub fn trans_promoted<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, promoted: Promoted) -> CPlace<'tcx> {
pub fn trans_promoted<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
promoted: Promoted,
) -> CPlace<'tcx> {
let const_ = fx
.tcx
.const_eval(ParamEnv::reveal_all().and(GlobalId {
instance: fx.instance,
promoted: Some(promoted),
}))
.unwrap();
})).unwrap();
let const_ = force_eval_const(fx, const_);
trans_const_place(fx, const_)
}
pub fn trans_constant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, constant: &Constant<'tcx>) -> CValue<'tcx> {
pub fn trans_constant<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
constant: &Constant<'tcx>,
) -> CValue<'tcx> {
let const_ = fx.monomorphize(&constant.literal);
let const_ = force_eval_const(fx, const_);
trans_const_value(fx, const_)
}
fn force_eval_const<'a, 'tcx: 'a>(fx: &FunctionCx<'a, 'tcx>, const_: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
fn force_eval_const<'a, 'tcx: 'a>(
fx: &FunctionCx<'a, 'tcx>,
const_: &'tcx Const<'tcx>,
) -> &'tcx Const<'tcx> {
match const_.val {
ConstValue::Unevaluated(def_id, ref substs) => {
let param_env = ParamEnv::reveal_all();
@ -33,12 +41,15 @@ fn force_eval_const<'a, 'tcx: 'a>(fx: &FunctionCx<'a, 'tcx>, const_: &'tcx Const
promoted: None,
};
fx.tcx.const_eval(param_env.and(cid)).unwrap()
},
}
_ => const_,
}
}
fn trans_const_value<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx Const<'tcx>) -> CValue<'tcx> {
fn trans_const_value<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
const_: &'tcx Const<'tcx>,
) -> CValue<'tcx> {
let ty = fx.monomorphize(&const_.ty);
let layout = fx.layout_of(ty);
match ty.sty {
@ -58,13 +69,14 @@ fn trans_const_value<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx
let func_ref = fx.get_function_ref(Instance::new(def_id, substs));
CValue::Func(func_ref, layout)
}
_ => {
trans_const_place(fx, const_).to_cvalue(fx)
}
_ => trans_const_place(fx, const_).to_cvalue(fx),
}
}
fn trans_const_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx Const<'tcx>) -> CPlace<'tcx> {
fn trans_const_place<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
const_: &'tcx Const<'tcx>,
) -> CPlace<'tcx> {
let ty = fx.monomorphize(&const_.ty);
let layout = fx.layout_of(ty);
if true {
@ -75,7 +87,9 @@ fn trans_const_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx
let mut memory = Memory::<CompileTimeEvaluator>::new(fx.tcx.at(DUMMY_SP), ());
let alloc = fx.tcx.const_value_to_allocation(const_);
//println!("const value: {:?} allocation: {:?}", value, alloc);
let alloc_id = memory.allocate_value(alloc.clone(), MemoryKind::Stack).unwrap();
let alloc_id = memory
.allocate_value(alloc.clone(), MemoryKind::Stack)
.unwrap();
let data_id = get_global_for_alloc_id(fx, &memory, alloc_id);
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
// TODO: does global_value return a ptr of a val?
@ -84,14 +98,19 @@ fn trans_const_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx
}
// If ret.1 is true, then the global didn't exist before
fn define_global_for_alloc_id(fx: &mut FunctionCx, alloc_id: AllocId, todo: &mut HashMap<AllocId, DataId>) -> (DataId, bool) {
fn define_global_for_alloc_id(
fx: &mut FunctionCx,
alloc_id: AllocId,
todo: &mut HashMap<AllocId, DataId>,
) -> (DataId, bool) {
use std::collections::hash_map::Entry;
match fx.constants.entry(alloc_id) {
Entry::Occupied(mut occ) => {
(*occ.get_mut(), false)
}
Entry::Occupied(mut occ) => (*occ.get_mut(), false),
Entry::Vacant(vac) => {
let data_id = fx.module.declare_data(&alloc_id.0.to_string(), Linkage::Local, false).unwrap();
let data_id = fx
.module
.declare_data(&alloc_id.0.to_string(), Linkage::Local, false)
.unwrap();
todo.insert(alloc_id, data_id);
vac.insert(data_id);
(data_id, true)
@ -99,7 +118,11 @@ fn define_global_for_alloc_id(fx: &mut FunctionCx, alloc_id: AllocId, todo: &mut
}
}
fn get_global_for_alloc_id(fx: &mut FunctionCx, memory: &Memory<CompileTimeEvaluator>, alloc_id: AllocId) -> DataId {
fn get_global_for_alloc_id(
fx: &mut FunctionCx,
memory: &Memory<CompileTimeEvaluator>,
alloc_id: AllocId,
) -> DataId {
if let Some(data_id) = fx.constants.get(&alloc_id) {
return *data_id;
}
@ -108,13 +131,22 @@ fn get_global_for_alloc_id(fx: &mut FunctionCx, memory: &Memory<CompileTimeEvalu
let mut done = HashSet::new();
define_global_for_alloc_id(fx, alloc_id, &mut todo);
while let Some((alloc_id, data_id)) = { let next = todo.drain().next(); next } {
println!("cur: {:?}:{:?} todo: {:?} done: {:?}", alloc_id, data_id, todo, done);
while let Some((alloc_id, data_id)) = {
let next = todo.drain().next();
next
} {
println!(
"cur: {:?}:{:?} todo: {:?} done: {:?}",
alloc_id, data_id, todo, done
);
let alloc = memory.get(alloc_id).unwrap();
let mut data_ctx = DataContext::new();
data_ctx.define(alloc.bytes.to_vec().into_boxed_slice(), Writability::Readonly);
data_ctx.define(
alloc.bytes.to_vec().into_boxed_slice(),
Writability::Readonly,
);
for &(offset, reloc) in alloc.relocations.iter() {
let data_id = define_global_for_alloc_id(fx, reloc, &mut todo).0;

View file

@ -4,82 +4,81 @@
extern crate syntax;
#[macro_use]
extern crate rustc;
extern crate rustc_mir;
extern crate rustc_codegen_utils;
extern crate rustc_target;
extern crate rustc_incremental;
extern crate rustc_mir;
extern crate rustc_target;
#[macro_use]
extern crate rustc_data_structures;
extern crate ar;
extern crate faerie;
//extern crate goblin;
extern crate target_lexicon;
extern crate cranelift;
extern crate cranelift_faerie;
extern crate cranelift_module;
extern crate cranelift_simplejit;
extern crate cranelift_faerie;
extern crate target_lexicon;
use std::any::Any;
use std::sync::{mpsc, Arc};
use std::path::Path;
use std::fs::File;
use std::path::Path;
use std::sync::{mpsc, Arc};
use syntax::symbol::Symbol;
use rustc::session::{
CompileIncomplete,
config::{
CrateType,
OutputFilenames,
},
};
use rustc::middle::cstore::MetadataLoader;
use rustc::dep_graph::DepGraph;
use rustc::middle::cstore::MetadataLoader;
use rustc::session::{
config::{CrateType, OutputFilenames},
CompileIncomplete,
};
use rustc::ty::query::Providers;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use rustc_codegen_utils::link::{out_filename, build_link_meta};
use rustc_codegen_utils::link::{build_link_meta, out_filename};
use rustc_data_structures::owning_ref::{self, OwningRef};
use syntax::symbol::Symbol;
use cranelift::codegen::settings;
use cranelift_faerie::*;
mod abi;
mod base;
mod constant;
mod common;
mod constant;
mod pretty_clif;
mod prelude {
pub use std::any::Any;
pub use std::collections::{HashMap, HashSet};
pub use syntax::codemap::DUMMY_SP;
pub use syntax::ast::{IntTy, UintTy, FloatTy};
pub use rustc::hir::def_id::{DefId, LOCAL_CRATE};
pub use rustc::mir;
pub use rustc::mir::*;
pub use rustc::mir::interpret::AllocId;
pub use rustc::mir::*;
pub use rustc::session::Session;
pub use rustc::ty::layout::{self, LayoutOf, TyLayout, Size};
pub use rustc::ty::layout::{self, LayoutOf, Size, TyLayout};
pub use rustc::ty::{
self, subst::Substs, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt,
TypeFoldable, TypeVariants, TypeAndMut,
TypeAndMut, TypeFoldable, TypeVariants,
};
pub use rustc_data_structures::{indexed_vec::Idx, sync::Lrc};
pub use rustc_mir::monomorphize::{MonoItem, collector};
pub use rustc_mir::monomorphize::{collector, MonoItem};
pub use syntax::ast::{FloatTy, IntTy, UintTy};
pub use syntax::codemap::DUMMY_SP;
pub use cranelift::codegen::ir::{
condcodes::IntCC, function::Function, ExternalName, FuncRef, StackSlot, Inst
condcodes::IntCC, function::Function, ExternalName, FuncRef, Inst, StackSlot,
};
pub use cranelift::codegen::Context;
pub use cranelift::prelude::*;
pub use cranelift_module::{Module, Backend, DataContext, FuncId, DataId, Linkage, Writability};
pub use cranelift_simplejit::{SimpleJITBuilder, SimpleJITBackend};
pub use cranelift_module::{
Backend, DataContext, DataId, FuncId, Linkage, Module, Writability,
};
pub use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
pub use crate::abi::*;
pub use crate::base::{trans_operand, trans_place};
pub use crate::common::Variable;
pub use crate::common::*;
pub use crate::base::{trans_operand, trans_place};
pub use crate::CodegenCx;
}
@ -95,14 +94,18 @@ pub struct CodegenCx<'a, 'tcx: 'a, B: Backend + 'a> {
struct CraneliftMetadataLoader;
impl MetadataLoader for CraneliftMetadataLoader {
fn get_rlib_metadata(&self, _target: &rustc_target::spec::Target, path: &Path) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
let mut archive = ar::Archive::new(File::open(path).map_err(|e|format!("{:?}", e))?);
fn get_rlib_metadata(
&self,
_target: &rustc_target::spec::Target,
path: &Path,
) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
let mut archive = ar::Archive::new(File::open(path).map_err(|e| format!("{:?}", e))?);
// Iterate over all entries in the archive:
while let Some(entry_result) = archive.next_entry() {
let mut entry = entry_result.map_err(|e|format!("{:?}", e))?;
let mut entry = entry_result.map_err(|e| format!("{:?}", e))?;
if entry.header().identifier() == b".rustc.clif_metadata" {
let mut buf = Vec::new();
::std::io::copy(&mut entry, &mut buf).map_err(|e|format!("{:?}", e))?;
::std::io::copy(&mut entry, &mut buf).map_err(|e| format!("{:?}", e))?;
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
return Ok(rustc_erase_owner!(buf.map_owner_box()));
}
@ -112,7 +115,11 @@ impl MetadataLoader for CraneliftMetadataLoader {
//self.get_dylib_metadata(target, path)
}
fn get_dylib_metadata(&self, _target: &rustc_target::spec::Target, _path: &Path) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
fn get_dylib_metadata(
&self,
_target: &rustc_target::spec::Target,
_path: &Path,
) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
//use goblin::Object;
//let buffer = ::std::fs::read(path).map_err(|e|format!("{:?}", e))?;
@ -149,13 +156,15 @@ impl CodegenBackend for CraneliftCodegenBackend {
fn init(&self, sess: &Session) {
for cty in sess.opts.crate_types.iter() {
match *cty {
CrateType::CrateTypeRlib | CrateType::CrateTypeDylib |
CrateType::CrateTypeExecutable => {},
CrateType::CrateTypeRlib
| CrateType::CrateTypeDylib
| CrateType::CrateTypeExecutable => {}
_ => {
sess.parse_sess.span_diagnostic.warn(
&format!("LLVM unsupported, so output type {} is not supported", cty)
);
},
sess.parse_sess.span_diagnostic.warn(&format!(
"LLVM unsupported, so output type {} is not supported",
cty
));
}
}
}
}
@ -167,9 +176,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
fn provide(&self, providers: &mut Providers) {
rustc_codegen_utils::symbol_names::provide(providers);
providers.target_features_whitelist = |_tcx, _cnum| {
Lrc::new(Default::default())
};
providers.target_features_whitelist = |_tcx, _cnum| Lrc::new(Default::default());
providers.is_reachable_non_generic = |_tcx, _defid| true;
providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
}
@ -180,7 +187,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
fn codegen_crate<'a, 'tcx>(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_rx: mpsc::Receiver<Box<Any + Send>>
_rx: mpsc::Receiver<Box<Any + Send>>,
) -> Box<Any> {
use rustc_mir::monomorphize::item::MonoItem;
@ -188,24 +195,22 @@ impl CodegenBackend for CraneliftCodegenBackend {
rustc_codegen_utils::symbol_names_test::report_symbol_names(tcx);
rustc_incremental::assert_dep_graph(tcx);
rustc_incremental::assert_module_sources::assert_module_sources(tcx);
rustc_mir::monomorphize::assert_symbols_are_distinct(tcx,
collector::collect_crate_mono_items(
tcx,
collector::MonoItemCollectionMode::Eager
).0.iter()
rustc_mir::monomorphize::assert_symbols_are_distinct(
tcx,
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager)
.0
.iter(),
);
//::rustc::middle::dependency_format::calculate(tcx);
let _ = tcx.link_args(LOCAL_CRATE);
let _ = tcx.native_libraries(LOCAL_CRATE);
for mono_item in
collector::collect_crate_mono_items(
tcx,
collector::MonoItemCollectionMode::Eager
).0 {
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
{
match mono_item {
MonoItem::Fn(inst) => {
let def_id = inst.def_id();
if def_id.is_local() {
if def_id.is_local() {
let _ = inst.def.is_inline(tcx);
let _ = tcx.codegen_fn_attrs(def_id);
}
@ -221,7 +226,9 @@ impl CodegenBackend for CraneliftCodegenBackend {
let mut flags_builder = settings::builder();
flags_builder.enable("is_pic").unwrap();
let flags = settings::Flags::new(flags_builder);
let isa = cranelift::codegen::isa::lookup(target_lexicon::Triple::host()).unwrap().finish(flags);
let isa = cranelift::codegen::isa::lookup(target_lexicon::Triple::host())
.unwrap()
.finish(flags);
let mut module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
let mut context = Context::new();
@ -233,10 +240,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
};
for mono_item in
collector::collect_crate_mono_items(
tcx,
collector::MonoItemCollectionMode::Eager
).0 {
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
{
base::trans_mono_item(&mut cx, &mut context, mono_item)
}
}
@ -249,11 +254,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
tcx.sess.warn("Finalized everything");
for mono_item in
collector::collect_crate_mono_items(
tcx,
collector::MonoItemCollectionMode::Eager
).0 {
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
{
let inst = match mono_item {
MonoItem::Fn(inst) => inst,
_ => continue,
@ -266,17 +268,21 @@ impl CodegenBackend for CraneliftCodegenBackend {
let fn_ty = inst.ty(tcx);
let sig = cton_sig_from_fn_ty(tcx, fn_ty);
let def_path_based_names = ::rustc_mir::monomorphize::item::DefPathBasedNames::new(tcx, false, false);
let def_path_based_names =
::rustc_mir::monomorphize::item::DefPathBasedNames::new(tcx, false, false);
let mut name = String::new();
def_path_based_names.push_instance_as_string(inst, &mut name);
let func_id = module.declare_function(&name, Linkage::Import, &sig).unwrap();
let func_id = module
.declare_function(&name, Linkage::Import, &sig)
.unwrap();
let finalized_function: *const u8 = module.finalize_function(func_id);
/*let f: extern "C" fn(&mut u32) = unsafe { ::std::mem::transmute(finalized_function) };
let mut res = 0u32;
f(&mut res);
tcx.sess.warn(&format!("ret_42 returned {}", res));*/
let f: extern "C" fn(&mut bool, &u8, bool) = unsafe { ::std::mem::transmute(finalized_function) };
let f: extern "C" fn(&mut bool, &u8, bool) =
unsafe { ::std::mem::transmute(finalized_function) };
let mut res = false;
f(&mut res, &3, false);
tcx.sess.warn(&format!("option_unwrap_or returned {}", res));
@ -290,9 +296,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
isa,
"some_file.o".to_string(),
FaerieTrapCollection::Disabled,
FaerieBuilder::default_libcall_names()
)
.unwrap()
FaerieBuilder::default_libcall_names(),
).unwrap(),
);
Box::new(OngoingCodegen {
@ -309,30 +314,42 @@ impl CodegenBackend for CraneliftCodegenBackend {
_dep_graph: &DepGraph,
outputs: &OutputFilenames,
) -> Result<(), CompileIncomplete> {
let ongoing_codegen = *ongoing_codegen.downcast::<OngoingCodegen>()
let ongoing_codegen = *ongoing_codegen
.downcast::<OngoingCodegen>()
.expect("Expected CraneliftCodegenBackend's OngoingCodegen, found Box<Any>");
let mut artifact = ongoing_codegen.product.artifact;
let metadata = ongoing_codegen.metadata;
artifact.declare_with(
".rustc.clif_metadata",
faerie::artifact::Decl::Data {
global: true,
writeable: false
},
metadata.clone(),
).unwrap();
artifact
.declare_with(
".rustc.clif_metadata",
faerie::artifact::Decl::Data {
global: true,
writeable: false,
},
metadata.clone(),
).unwrap();
for &crate_type in sess.opts.crate_types.iter() {
if crate_type != CrateType::CrateTypeRlib /*&& crate_type != CrateType::CrateTypeDylib*/ {
if crate_type != CrateType::CrateTypeRlib
/*&& crate_type != CrateType::CrateTypeDylib*/
{
sess.fatal(&format!("Unsupported crate type: {:?}", crate_type));
}
let output_name =
out_filename(sess, crate_type, &outputs, &ongoing_codegen.crate_name.as_str());
let output_name = out_filename(
sess,
crate_type,
&outputs,
&ongoing_codegen.crate_name.as_str(),
);
let file = File::create(&output_name).unwrap();
let mut builder = ar::Builder::new(file);
builder.append(&ar::Header::new(b".rustc.clif_metadata".to_vec(), metadata.len() as u64), ::std::io::Cursor::new(metadata.clone())).unwrap();
builder
.append(
&ar::Header::new(b".rustc.clif_metadata".to_vec(), metadata.len() as u64),
::std::io::Cursor::new(metadata.clone()),
).unwrap();
//artifact.write(file).unwrap();
}