From e137c2ad0a4436693a21637edb89424fc7546377 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 28 Dec 2015 21:18:24 +0200 Subject: [PATCH] [MIR] Translate ConstVal::Function This moves back (essentially reverts #30265) into MIR-specific translation code, but keeps the funcition split out, since it is expected to eventually become recursive. --- src/librustc_trans/trans/consts.rs | 33 ------------------- src/librustc_trans/trans/mir/constant.rs | 42 ++++++++++++++++++++++-- src/test/run-pass/mir_refs_correct.rs | 7 ++++ 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 0fafe08178a27..fe7d29297a960 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -31,7 +31,6 @@ use trans::{adt, closure, debuginfo, expr, inline, machine}; use trans::base::{self, push_ctxt}; use trans::common::{self, type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt}; use trans::common::{CrateContext, C_integral, C_floating, C_bool, C_str_slice, C_bytes, val_ty}; -use trans::common::C_floating_f64; use trans::common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, VariantInfo, C_uint}; use trans::common::{type_is_fat_ptr, Field, C_vector, C_array, C_null, ExprId, MethodCallKey}; use trans::declare; @@ -108,38 +107,6 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit) } } -pub fn trans_constval<'blk, 'tcx>(bcx: common::Block<'blk, 'tcx>, - cv: &ConstVal, - ty: Ty<'tcx>, - param_substs: &'tcx Substs<'tcx>) - -> ValueRef -{ - let ccx = bcx.ccx(); - let llty = type_of::type_of(ccx, ty); - match *cv { - ConstVal::Float(v) => C_floating_f64(v, llty), - ConstVal::Bool(v) => C_bool(ccx, v), - ConstVal::Int(v) => C_integral(llty, v as u64, true), - ConstVal::Uint(v) => C_integral(llty, v, false), - ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()), - ConstVal::ByteStr(ref v) => addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"), - ConstVal::Struct(id) | ConstVal::Tuple(id) => { - let expr = bcx.tcx().map.expect_expr(id); - match const_expr(ccx, expr, param_substs, None, TrueConst::Yes) { - Ok((val, _)) => val, - Err(e) => panic!("const eval failure: {}", e.description()), - } - }, - ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => { - let expr = bcx.tcx().map.expect_expr(id); - expr::trans(bcx, expr).datum.val - }, - ConstVal::Function(_) => { - unimplemented!() - }, - } -} - pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef { unsafe { llvm::LLVMConstPointerCast(val, ty.to_ref()) diff --git a/src/librustc_trans/trans/mir/constant.rs b/src/librustc_trans/trans/mir/constant.rs index 70a56990efd03..12839df87b159 100644 --- a/src/librustc_trans/trans/mir/constant.rs +++ b/src/librustc_trans/trans/mir/constant.rs @@ -9,11 +9,14 @@ // except according to those terms. use back::abi; +use llvm::ValueRef; +use middle::subst::Substs; use middle::ty::{Ty, HasTypeFlags}; use rustc::middle::const_eval::ConstVal; use rustc::mir::repr as mir; -use trans::consts; -use trans::common::{self, Block}; +use trans::common::{self, Block, C_bool, C_bytes, C_floating_f64, C_integral, C_str_slice}; +use trans::consts::{self, TrueConst}; +use trans::{type_of, expr}; use super::operand::{OperandRef, OperandValue}; @@ -27,7 +30,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { -> OperandRef<'tcx> { let ccx = bcx.ccx(); - let val = consts::trans_constval(bcx, cv, ty, bcx.fcx.param_substs); + let val = self.trans_constval_inner(bcx, cv, ty, bcx.fcx.param_substs); let val = if common::type_is_immediate(ccx, ty) { OperandValue::Immediate(val) } else if common::type_is_fat_ptr(bcx.tcx(), ty) { @@ -46,6 +49,39 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { } } + /// Translate ConstVal into a bare LLVM ValueRef. + fn trans_constval_inner(&mut self, + bcx: common::Block<'bcx, 'tcx>, + cv: &ConstVal, + ty: Ty<'tcx>, + param_substs: &'tcx Substs<'tcx>) + -> ValueRef + { + let ccx = bcx.ccx(); + let llty = type_of::type_of(ccx, ty); + match *cv { + ConstVal::Float(v) => C_floating_f64(v, llty), + ConstVal::Bool(v) => C_bool(ccx, v), + ConstVal::Int(v) => C_integral(llty, v as u64, true), + ConstVal::Uint(v) => C_integral(llty, v, false), + ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()), + ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"), + ConstVal::Struct(id) | ConstVal::Tuple(id) => { + let expr = bcx.tcx().map.expect_expr(id); + match consts::const_expr(ccx, expr, param_substs, None, TrueConst::Yes) { + Ok((val, _)) => val, + Err(e) => panic!("const eval failure: {}", e.description()), + } + }, + ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => { + let expr = bcx.tcx().map.expect_expr(id); + expr::trans(bcx, expr).datum.val + }, + ConstVal::Function(did) => + self.trans_fn_ref(bcx, ty, param_substs, did).immediate() + } + } + pub fn trans_constant(&mut self, bcx: Block<'bcx, 'tcx>, constant: &mir::Constant<'tcx>) diff --git a/src/test/run-pass/mir_refs_correct.rs b/src/test/run-pass/mir_refs_correct.rs index b46ec0d8764d9..93953e3f58ae0 100644 --- a/src/test/run-pass/mir_refs_correct.rs +++ b/src/test/run-pass/mir_refs_correct.rs @@ -68,6 +68,7 @@ enum CEnum { const C: u8 = 84; const C2: [u8; 5] = [42; 5]; const C3: [u8; 3] = [42, 41, 40]; +const C4: fn(u8) -> S = S; fn regular() -> u8 { 21 @@ -198,6 +199,11 @@ fn t23() -> (CEnum, CEnum) { (CEnum::A, CEnum::B) } +#[rustc_mir] +fn t24() -> fn(u8) -> S { + C4 +} + fn main(){ unsafe { assert_eq!(t1()(), regular()); @@ -240,5 +246,6 @@ fn main(){ assert_eq!(t21(), Unit); assert_eq!(t22(), None); assert_eq!(t23(), (CEnum::A, CEnum::B)); + assert_eq!(t24(), C4); } }