Skip to content

Commit

Permalink
Rollup merge of rust-lang#40602 - oli-obk:fn_const, r=eddyb
Browse files Browse the repository at this point in the history
Represent function pointers in mir-constants as a Value instead of Item

r? @eddyb
  • Loading branch information
Ariel Ben-Yehuda authored Mar 19, 2017
2 parents c1a864d + 187a922 commit 0d904ce
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 48 deletions.
5 changes: 2 additions & 3 deletions src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,9 +875,8 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
func: Operand::Constant(Constant {
span: c.source_info.span,
ty: fty,
literal: Literal::Item {
def_id: free_func,
substs: substs
literal: Literal::Value {
value: ConstVal::Function(free_func, substs),
}
}),
args: vec![Operand::Consume(c.lvalue.clone())],
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_mir/build/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -783,9 +784,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())],
Expand Down
33 changes: 18 additions & 15 deletions src/librustc_mir/hair/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,9 +711,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),
},
},
}
Expand All @@ -740,22 +739,32 @@ 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) => {
match cx.tables().node_id_to_type(expr.id).sty {
// 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,
Expand All @@ -767,17 +776,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,
},
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/librustc_mir/hair/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
});
}
}
Expand Down
5 changes: 0 additions & 5 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_mir/transform/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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()
}
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_trans/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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() => {
Expand Down
21 changes: 5 additions & 16 deletions src/librustc_trans/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
Expand Down Expand Up @@ -477,13 +480,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, 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);
let instance = Instance::new(def_id, substs);
MirConstContext::trans_def(self.ccx, instance, IndexVec::new())
Expand Down Expand Up @@ -927,13 +923,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, 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);
let instance = Instance::new(def_id, substs);
MirConstContext::trans_def(bcx.ccx, instance, IndexVec::new())
Expand Down

0 comments on commit 0d904ce

Please sign in to comment.