mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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:
commit
1aa4abdb3b
@ -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())
|
||||
|
@ -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>)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user