Rollup merge of #40602 - oli-obk:fn_const, r=eddyb
Represent function pointers in mir-constants as a Value instead of Item r? @eddyb
This commit is contained in:
commit
6cf5988651
@ -983,16 +983,16 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
}
|
||||
|
||||
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) },
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@
|
||||
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::*;
|
||||
@ -784,9 +785,8 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
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())],
|
||||
|
@ -714,9 +714,8 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
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),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -743,14 +742,24 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
-> 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) => {
|
||||
@ -758,7 +767,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
// 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,
|
||||
@ -770,17 +779,11 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,9 +132,8 @@ pub fn trait_method(&mut self,
|
||||
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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
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};
|
||||
@ -335,7 +336,9 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
||||
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]
|
||||
)
|
||||
|
@ -568,11 +568,6 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
|
||||
});
|
||||
}
|
||||
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() {
|
||||
|
@ -15,6 +15,7 @@
|
||||
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};
|
||||
@ -526,7 +527,9 @@ fn check_call_inputs(&mut self,
|
||||
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()
|
||||
}
|
||||
|
@ -525,8 +525,8 @@ fn destructor_call_block<'a>(&mut self, (succ, unwind): (BasicBlock, Option<Basi
|
||||
}],
|
||||
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,
|
||||
@ -629,7 +629,7 @@ fn unelaborated_free_block<'a>(
|
||||
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
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
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;
|
||||
@ -109,7 +110,9 @@ fn visit_terminator_kind(&mut self,
|
||||
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() => {
|
||||
|
@ -101,9 +101,12 @@ pub fn from_constval<'a>(ccx: &CrateContext<'a, 'tcx>,
|
||||
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),
|
||||
};
|
||||
@ -476,13 +479,6 @@ fn const_operand(&self, operand: &mir::Operand<'tcx>, span: Span)
|
||||
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.
|
||||
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 substs = self.monomorphize(&substs);
|
||||
MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new())
|
||||
}
|
||||
@ -924,13 +920,6 @@ pub fn trans_constant(&mut self,
|
||||
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.
|
||||
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);
|
||||
}
|
||||
|
||||
let substs = self.monomorphize(&substs);
|
||||
MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user