}
impl<'tcx> Operand<'tcx> {
- pub fn item<'a>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
- def_id: DefId,
- substs: &'tcx Substs<'tcx>,
- span: Span)
- -> Self
- {
+ pub fn function_handle<'a>(
+ tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
+ def_id: DefId,
+ substs: &'tcx Substs<'tcx>,
+ span: Span,
+ ) -> Self {
Operand::Constant(Constant {
span: span,
ty: tcx.item_type(def_id).subst(tcx, substs),
- literal: Literal::Item { def_id, substs }
+ literal: Literal::Value { value: ConstVal::Function(def_id, substs) },
})
}
use build::{BlockAnd, BlockAndExtension, Builder, CFG};
use rustc::middle::region::{CodeExtent, CodeExtentData};
use rustc::middle::lang_items;
+use rustc::middle::const_val::ConstVal;
use rustc::ty::subst::{Kind, Subst};
use rustc::ty::{Ty, TyCtxt};
use rustc::mir::*;
func: Operand::Constant(Constant {
span: data.span,
ty: tcx.item_type(free_func).subst(tcx, substs),
- literal: Literal::Item {
- def_id: free_func,
- substs: substs
+ literal: Literal::Value {
+ value: ConstVal::Function(free_func, substs),
}
}),
args: vec![Operand::Consume(data.value.clone())],
ty: callee.ty,
span: expr.span,
kind: ExprKind::Literal {
- literal: Literal::Item {
- def_id: callee.def_id,
- substs: callee.substs,
+ literal: Literal::Value {
+ value: ConstVal::Function(callee.def_id, callee.substs),
},
},
}
-> ExprKind<'tcx> {
let substs = cx.tables().node_id_item_substs(expr.id)
.unwrap_or_else(|| cx.tcx.intern_substs(&[]));
- let def_id = match def {
+ match def {
// A regular function, constructor function or a constant.
Def::Fn(def_id) |
Def::Method(def_id) |
Def::StructCtor(def_id, CtorKind::Fn) |
- Def::VariantCtor(def_id, CtorKind::Fn) |
+ Def::VariantCtor(def_id, CtorKind::Fn) => ExprKind::Literal {
+ literal: Literal::Value {
+ value: ConstVal::Function(def_id, substs),
+ },
+ },
+
Def::Const(def_id) |
- Def::AssociatedConst(def_id) => def_id,
+ Def::AssociatedConst(def_id) => ExprKind::Literal {
+ literal: Literal::Item {
+ def_id: def_id,
+ substs: substs,
+ },
+ },
Def::StructCtor(def_id, CtorKind::Const) |
Def::VariantCtor(def_id, CtorKind::Const) => {
// A unit struct/variant which is used as a value.
// We return a completely different ExprKind here to account for this special case.
ty::TyAdt(adt_def, substs) => {
- return ExprKind::Adt {
+ ExprKind::Adt {
adt_def: adt_def,
variant_index: adt_def.variant_index_with_id(def_id),
substs: substs,
}
}
- Def::Static(node_id, _) => return ExprKind::StaticRef { id: node_id },
+ Def::Static(node_id, _) => ExprKind::StaticRef { id: node_id },
- Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def),
+ Def::Local(..) | Def::Upvar(..) => convert_var(cx, expr, def),
_ => span_bug!(expr.span, "def `{:?}` not yet implemented", def),
- };
- ExprKind::Literal {
- literal: Literal::Item {
- def_id: def_id,
- substs: substs,
- },
}
}
let method_ty = self.tcx.item_type(item.def_id);
let method_ty = method_ty.subst(self.tcx, substs);
return (method_ty,
- Literal::Item {
- def_id: item.def_id,
- substs: substs,
+ Literal::Value {
+ value: ConstVal::Function(item.def_id, substs),
});
}
}
use rustc::hir::def_id::DefId;
use rustc::infer;
use rustc::middle::region::ROOT_CODE_EXTENT;
+use rustc::middle::const_val::ConstVal;
use rustc::mir::*;
use rustc::mir::transform::MirSource;
use rustc::ty::{self, Ty};
Operand::Constant(Constant {
span: span,
ty: tcx.item_type(def_id).subst(tcx, param_env.free_substs),
- literal: Literal::Item { def_id, substs: param_env.free_substs },
+ literal: Literal::Value {
+ value: ConstVal::Function(def_id, param_env.free_substs),
+ },
}),
vec![rcvr]
)
});
}
Operand::Constant(ref constant) => {
- // Only functions and methods can have these types.
- if let ty::TyFnDef(..) = constant.ty.sty {
- return;
- }
-
if let Literal::Item { def_id, substs } = constant.literal {
// Don't peek inside generic (associated) constants.
if substs.types().next().is_some() {
use rustc::traits::{self, Reveal};
use rustc::ty::fold::TypeFoldable;
use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
+use rustc::middle::const_val::ConstVal;
use rustc::mir::*;
use rustc::mir::tcx::LvalueTy;
use rustc::mir::transform::{MirPass, MirSource, Pass};
fn is_box_free(&self, operand: &Operand<'tcx>) -> bool {
match operand {
&Operand::Constant(Constant {
- literal: Literal::Item { def_id, .. }, ..
+ literal: Literal::Value {
+ value: ConstVal::Function(def_id, _), ..
+ }, ..
}) => {
Some(def_id) == self.tcx().lang_items.box_free_fn()
}
}],
terminator: Some(Terminator {
kind: TerminatorKind::Call {
- func: Operand::item(tcx, drop_fn.def_id, substs,
- self.source_info.span),
+ func: Operand::function_handle(tcx, drop_fn.def_id, substs,
+ self.source_info.span),
args: vec![Operand::Consume(Lvalue::Local(ref_lvalue))],
destination: Some((unit_temp, succ)),
cleanup: unwind,
let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
let call = TerminatorKind::Call {
- func: Operand::item(tcx, free_func, substs, self.source_info.span),
+ func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
args: vec![Operand::Consume(self.lvalue.clone())],
destination: Some((unit_temp, target)),
cleanup: None
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use rustc::mir::{self, Location, TerminatorKind};
+use rustc::middle::const_val::ConstVal;
+use rustc::mir::{self, Location, TerminatorKind, Literal};
use rustc::mir::visit::{Visitor, LvalueContext};
use rustc::mir::traversal;
use common;
match *kind {
mir::TerminatorKind::Call {
func: mir::Operand::Constant(mir::Constant {
- literal: mir::Literal::Item { def_id, .. }, ..
+ literal: Literal::Value {
+ value: ConstVal::Function(def_id, _), ..
+ }, ..
}),
ref args, ..
} if Some(def_id) == self.cx.ccx.tcx().lang_items.box_free_fn() => {
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(_) | ConstVal::Tuple(_) |
- ConstVal::Array(..) | ConstVal::Repeat(..) |
+ ConstVal::Array(..) | ConstVal::Repeat(..) => {
+ bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv)
+ }
ConstVal::Function(..) => {
- bug!("MIR must not use `{:?}` (which refers to a local ID)", cv)
+ let llty = type_of::type_of(ccx, ty);
+ return Const::new(C_null(llty), ty);
}
ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false),
};
let ty = self.monomorphize(&constant.ty);
match constant.literal.clone() {
mir::Literal::Item { def_id, substs } => {
- // Shortcut for zero-sized types, including function item
- // types, which would not work with MirConstContext.
+ // Shortcut for zero-sized types
+ // which would not work with MirConstContext.
if common::type_is_zero_size(self.ccx, ty) {
let llty = type_of::type_of(self.ccx, ty);
return Ok(Const::new(C_null(llty), ty));
let ty = self.monomorphize(&constant.ty);
let result = match constant.literal.clone() {
mir::Literal::Item { def_id, substs } => {
- // Shortcut for zero-sized types, including function item
- // types, which would not work with MirConstContext.
+ // Shortcut for zero-sized types
+ // which would not work with MirConstContext.
if common::type_is_zero_size(bcx.ccx, ty) {
let llty = type_of::type_of(bcx.ccx, ty);
return Const::new(C_null(llty), ty);