From b0d9afbc04483a8c19f15e13e3a61ce11892536d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 7 Mar 2017 16:09:01 +0100 Subject: [PATCH 1/2] Represent function pointers in mir-constants as a Value instead of Item --- src/librustc/mir/mod.rs | 14 ++++----- src/librustc_mir/build/scope.rs | 6 ++-- src/librustc_mir/hair/cx/expr.rs | 33 +++++++++++--------- src/librustc_mir/hair/cx/mod.rs | 5 ++- src/librustc_mir/shim.rs | 5 ++- src/librustc_mir/transform/qualify_consts.rs | 5 --- src/librustc_mir/transform/type_check.rs | 5 ++- src/librustc_mir/util/elaborate_drops.rs | 6 ++-- src/librustc_trans/mir/analyze.rs | 7 +++-- src/librustc_trans/mir/constant.rs | 15 +++++---- 10 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9fdb8665776..01dc7f51e29 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -983,16 +983,16 @@ impl<'tcx> Debug for Operand<'tcx> { } 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) }, }) } diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 1de5b921856..dd4190a412d 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -89,6 +89,7 @@ should go to. 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())], diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index da58a1ed1f4..44858a98e36 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -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, - }, } } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index c555ce1ab9c..3eef5d83b8b 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -132,9 +132,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { 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), }); } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 26d5b7fd38a..63d20be88fe 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -12,6 +12,7 @@ use rustc::hir; 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] ) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index e998665e035..ba42804c926 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -568,11 +568,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { }); } 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() { diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index f98bb73c504..3d604affbfe 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -15,6 +15,7 @@ use rustc::infer::{self, InferCtxt, InferOk}; 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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() } diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index d0f142ad7d7..ccbc6700d89 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -525,8 +525,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> }], 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 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> 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 diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 2c3b479c7dd..a3968650043 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -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 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { 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() => { diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 107b0982af9..5d7f71848f8 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -101,9 +101,12 @@ impl<'tcx> Const<'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,8 +479,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { 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)); @@ -924,8 +927,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { 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); From 9c918464e186c7b19550004a771104589c0952d2 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 17 Mar 2017 17:47:09 +0100 Subject: [PATCH 2/2] Remove zst hacks --- src/librustc_trans/mir/constant.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 5d7f71848f8..dbd928194c0 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -479,13 +479,6 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let ty = self.monomorphize(&constant.ty); match constant.literal.clone() { mir::Literal::Item { def_id, substs } => { - // 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 substs = self.monomorphize(&substs); MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new()) } @@ -927,13 +920,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let ty = self.monomorphize(&constant.ty); let result = match constant.literal.clone() { mir::Literal::Item { def_id, substs } => { - // 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); - } - let substs = self.monomorphize(&substs); MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new()) }