Rollup merge of #30590 - nagisa:mir-constval-function, r=luqmana

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.

Fixes https://github.com/rust-lang/rust/issues/29572

cc @oli-obk
This commit is contained in:
Simonas Kazlauskas 2015-12-31 17:28:57 +02:00 committed by Simonas Kazlauskas
commit 1aa4abdb3b
3 changed files with 46 additions and 36 deletions

View File

@ -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())

View File

@ -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>)

View File

@ -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);
}
}