about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-03-07 16:09:01 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-03-24 16:19:31 +0100
commitb0d9afbc04483a8c19f15e13e3a61ce11892536d (patch)
tree90bb4825d2d92b0141fe1d57fe98d4595932177f /src
parent366386c46dbe660947de21dfd04eace5486e2f00 (diff)
downloadrust-b0d9afbc04483a8c19f15e13e3a61ce11892536d.tar.gz
rust-b0d9afbc04483a8c19f15e13e3a61ce11892536d.zip
Represent function pointers in mir-constants as a Value instead of Item
Diffstat (limited to 'src')
-rw-r--r--src/librustc/mir/mod.rs14
-rw-r--r--src/librustc_mir/build/scope.rs6
-rw-r--r--src/librustc_mir/hair/cx/expr.rs33
-rw-r--r--src/librustc_mir/hair/cx/mod.rs5
-rw-r--r--src/librustc_mir/shim.rs5
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs5
-rw-r--r--src/librustc_mir/transform/type_check.rs5
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs6
-rw-r--r--src/librustc_trans/mir/analyze.rs7
-rw-r--r--src/librustc_trans/mir/constant.rs15
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);