Record whether a Call in MIR corresponds to a call in HIR

This commit is contained in:
Matthew Jasper 2018-09-29 10:34:12 +01:00
parent 6ddab3e078
commit cc09cb5e5a
17 changed files with 58 additions and 17 deletions

View File

@ -194,11 +194,13 @@ for mir::TerminatorKind<'gcx> {
mir::TerminatorKind::Call { ref func, mir::TerminatorKind::Call { ref func,
ref args, ref args,
ref destination, ref destination,
cleanup } => { cleanup,
from_hir_call, } => {
func.hash_stable(hcx, hasher); func.hash_stable(hcx, hasher);
args.hash_stable(hcx, hasher); args.hash_stable(hcx, hasher);
destination.hash_stable(hcx, hasher); destination.hash_stable(hcx, hasher);
cleanup.hash_stable(hcx, hasher); cleanup.hash_stable(hcx, hasher);
from_hir_call.hash_stable(hcx, hasher);
} }
mir::TerminatorKind::Assert { ref cond, mir::TerminatorKind::Assert { ref cond,
expected, expected,

View File

@ -1049,6 +1049,9 @@ pub enum TerminatorKind<'tcx> {
destination: Option<(Place<'tcx>, BasicBlock)>, destination: Option<(Place<'tcx>, BasicBlock)>,
/// Cleanups to be done if the call unwinds. /// Cleanups to be done if the call unwinds.
cleanup: Option<BasicBlock>, cleanup: Option<BasicBlock>,
/// Whether this is from a call in HIR, rather than from an overloaded
/// operator. True for overloaded function call.
from_hir_call: bool,
}, },
/// Jump to the target if the condition has the expected value, /// Jump to the target if the condition has the expected value,
@ -2810,6 +2813,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
ref args, ref args,
ref destination, ref destination,
cleanup, cleanup,
from_hir_call,
} => { } => {
let dest = destination let dest = destination
.as_ref() .as_ref()
@ -2820,6 +2824,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
args: args.fold_with(folder), args: args.fold_with(folder),
destination: dest, destination: dest,
cleanup, cleanup,
from_hir_call,
} }
} }
Assert { Assert {

View File

@ -468,7 +468,8 @@ macro_rules! make_mir_visitor {
TerminatorKind::Call { ref $($mutability)* func, TerminatorKind::Call { ref $($mutability)* func,
ref $($mutability)* args, ref $($mutability)* args,
ref $($mutability)* destination, ref $($mutability)* destination,
cleanup } => { cleanup,
from_hir_call: _, } => {
self.visit_operand(func, source_location); self.visit_operand(func, source_location);
for arg in args { for arg in args {
self.visit_operand(arg, source_location); self.visit_operand(arg, source_location);

View File

@ -412,7 +412,13 @@ impl FunctionCx<'a, 'll, 'tcx> {
bug!("undesugared DropAndReplace in codegen: {:?}", terminator); bug!("undesugared DropAndReplace in codegen: {:?}", terminator);
} }
mir::TerminatorKind::Call { ref func, ref args, ref destination, cleanup } => { mir::TerminatorKind::Call {
ref func,
ref args,
ref destination,
cleanup,
from_hir_call: _
} => {
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar. // Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
let callee = self.codegen_operand(&bx, func); let callee = self.codegen_operand(&bx, func);

View File

@ -667,6 +667,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
ref args, ref args,
ref destination, ref destination,
cleanup: _, cleanup: _,
from_hir_call: _,
} => { } => {
self.consume_operand(ContextKind::CallOperator.new(loc), (func, span), flow_state); self.consume_operand(ContextKind::CallOperator.new(loc), (func, span), flow_state);
for arg in args { for arg in args {

View File

@ -203,6 +203,7 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
ref args, ref args,
ref destination, ref destination,
cleanup: _, cleanup: _,
from_hir_call: _,
} => { } => {
self.consume_operand(ContextKind::CallOperator.new(location), func); self.consume_operand(ContextKind::CallOperator.new(location), func);
for arg in args { for arg in args {

View File

@ -264,7 +264,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
); );
exit_block.unit() exit_block.unit()
} }
ExprKind::Call { ty, fun, args } => { ExprKind::Call { ty, fun, args, from_hir_call } => {
// FIXME(canndrew): This is_never should probably be an is_uninhabited // FIXME(canndrew): This is_never should probably be an is_uninhabited
let diverges = expr.ty.is_never(); let diverges = expr.ty.is_never();
let intrinsic = match ty.sty { let intrinsic = match ty.sty {
@ -326,6 +326,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} else { } else {
Some((destination.clone(), success)) Some((destination.clone(), success))
}, },
from_hir_call,
}, },
); );
success.unit() success.unit()

View File

@ -361,6 +361,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
args: vec![val, expect], args: vec![val, expect],
destination: Some((eq_result.clone(), eq_block)), destination: Some((eq_result.clone(), eq_block)),
cleanup: Some(cleanup), cleanup: Some(cleanup),
from_hir_call: false,
}); });
// check the result // check the result

View File

@ -795,7 +795,7 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list); self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list);
} }
} }
mir::TerminatorKind::Call { cleanup, ref destination, func: _, args: _ } => { mir::TerminatorKind::Call { cleanup, ref destination, .. } => {
if let Some(unwind) = cleanup { if let Some(unwind) = cleanup {
if !self.dead_unwinds.contains(bb) { if !self.dead_unwinds.contains(bb) {
self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list); self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);

View File

@ -380,7 +380,13 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
self.gather_operand(value); self.gather_operand(value);
self.gather_init(location, InitKind::Deep); self.gather_init(location, InitKind::Deep);
} }
TerminatorKind::Call { ref func, ref args, ref destination, cleanup: _ } => { TerminatorKind::Call {
ref func,
ref args,
ref destination,
cleanup: _,
from_hir_call: _,
} => {
self.gather_operand(func); self.gather_operand(func);
for arg in args { for arg in args {
self.gather_operand(arg); self.gather_operand(arg);

View File

@ -21,6 +21,7 @@ use rustc::ty::cast::CastKind as TyCastKind;
use rustc::hir; use rustc::hir;
use rustc::hir::def_id::LocalDefId; use rustc::hir::def_id::LocalDefId;
use rustc::mir::{BorrowKind}; use rustc::mir::{BorrowKind};
use syntax_pos::Span;
impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
type Output = Expr<'tcx>; type Output = Expr<'tcx>;
@ -232,9 +233,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let kind = match expr.node { let kind = match expr.node {
// Here comes the interesting stuff: // Here comes the interesting stuff:
hir::ExprKind::MethodCall(.., ref args) => { hir::ExprKind::MethodCall(_, method_span, ref args) => {
// Rewrite a.b(c) into UFCS form like Trait::b(a, c) // Rewrite a.b(c) into UFCS form like Trait::b(a, c)
let expr = method_callee(cx, expr, None); let expr = method_callee(cx, expr, method_span,None);
let args = args.iter() let args = args.iter()
.map(|e| e.to_ref()) .map(|e| e.to_ref())
.collect(); .collect();
@ -242,6 +243,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
ty: expr.ty, ty: expr.ty,
fun: expr.to_ref(), fun: expr.to_ref(),
args, args,
from_hir_call: true,
} }
} }
@ -254,7 +256,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// rewrite f(u, v) into FnOnce::call_once(f, (u, v)) // rewrite f(u, v) into FnOnce::call_once(f, (u, v))
let method = method_callee(cx, expr, None); let method = method_callee(cx, expr, fun.span,None);
let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e)); let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e));
let tupled_args = Expr { let tupled_args = Expr {
@ -268,6 +270,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
ty: method.ty, ty: method.ty,
fun: method.to_ref(), fun: method.to_ref(),
args: vec![fun.to_ref(), tupled_args.to_ref()], args: vec![fun.to_ref(), tupled_args.to_ref()],
from_hir_call: true,
} }
} else { } else {
let adt_data = if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = let adt_data = if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) =
@ -321,6 +324,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
ty: cx.tables().node_id_to_type(fun.hir_id), ty: cx.tables().node_id_to_type(fun.hir_id),
fun: fun.to_ref(), fun: fun.to_ref(),
args: args.to_ref(), args: args.to_ref(),
from_hir_call: true,
} }
} }
} }
@ -812,6 +816,7 @@ fn user_annotated_ty_for_adt(
fn method_callee<'a, 'gcx, 'tcx>( fn method_callee<'a, 'gcx, 'tcx>(
cx: &mut Cx<'a, 'gcx, 'tcx>, cx: &mut Cx<'a, 'gcx, 'tcx>,
expr: &hir::Expr, expr: &hir::Expr,
span: Span,
overloaded_callee: Option<(DefId, &'tcx Substs<'tcx>)>, overloaded_callee: Option<(DefId, &'tcx Substs<'tcx>)>,
) -> Expr<'tcx> { ) -> Expr<'tcx> {
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
@ -832,7 +837,7 @@ fn method_callee<'a, 'gcx, 'tcx>(
Expr { Expr {
temp_lifetime, temp_lifetime,
ty, ty,
span: expr.span, span,
kind: ExprKind::Literal { kind: ExprKind::Literal {
literal: ty::Const::zero_sized(cx.tcx(), ty), literal: ty::Const::zero_sized(cx.tcx(), ty),
user_ty, user_ty,
@ -1093,11 +1098,12 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
expr: &'tcx hir::Expr, expr: &'tcx hir::Expr,
args: Vec<ExprRef<'tcx>>) args: Vec<ExprRef<'tcx>>)
-> ExprKind<'tcx> { -> ExprKind<'tcx> {
let fun = method_callee(cx, expr, None); let fun = method_callee(cx, expr, expr.span, None);
ExprKind::Call { ExprKind::Call {
ty: fun.ty, ty: fun.ty,
fun: fun.to_ref(), fun: fun.to_ref(),
args, args,
from_hir_call: false,
} }
} }
@ -1132,7 +1138,7 @@ fn overloaded_place<'a, 'gcx, 'tcx>(
// construct the complete expression `foo()` for the overloaded call, // construct the complete expression `foo()` for the overloaded call,
// which will yield the &T type // which will yield the &T type
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let fun = method_callee(cx, expr, overloaded_callee); let fun = method_callee(cx, expr, expr.span, overloaded_callee);
let ref_expr = Expr { let ref_expr = Expr {
temp_lifetime, temp_lifetime,
ty: ref_ty, ty: ref_ty,
@ -1141,6 +1147,7 @@ fn overloaded_place<'a, 'gcx, 'tcx>(
ty: fun.ty, ty: fun.ty,
fun: fun.to_ref(), fun: fun.to_ref(),
args, args,
from_hir_call: false,
}, },
}; };

View File

@ -150,6 +150,9 @@ pub enum ExprKind<'tcx> {
ty: Ty<'tcx>, ty: Ty<'tcx>,
fun: ExprRef<'tcx>, fun: ExprRef<'tcx>,
args: Vec<ExprRef<'tcx>>, args: Vec<ExprRef<'tcx>>,
// Whether this is from a call in HIR, rather than from an overloaded
// operator. True for overloaded function call.
from_hir_call: bool,
}, },
Deref { Deref {
arg: ExprRef<'tcx>, arg: ExprRef<'tcx>,

View File

@ -468,6 +468,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
args: vec![Operand::Move(ref_loc)], args: vec![Operand::Move(ref_loc)],
destination: Some((dest, next)), destination: Some((dest, next)),
cleanup: Some(cleanup), cleanup: Some(cleanup),
from_hir_call: true,
}, false); }, false);
} }
@ -766,7 +767,8 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Some(BasicBlock::new(3)) Some(BasicBlock::new(3))
} else { } else {
None None
} },
from_hir_call: true,
}, false); }, false);
if let Adjustment::RefMut = rcvr_adjustment { if let Adjustment::RefMut = rcvr_adjustment {

View File

@ -121,6 +121,7 @@ impl Lower128Bit {
args: vec![lhs, rhs], args: vec![lhs, rhs],
destination: Some((place, bb)), destination: Some((place, bb)),
cleanup: None, cleanup: None,
from_hir_call: false,
}, },
}); });
} }

View File

@ -258,7 +258,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
}; };
match terminator.kind { match terminator.kind {
TerminatorKind::Call { mut func, mut args, .. } => { TerminatorKind::Call { mut func, mut args, from_hir_call, .. } => {
self.visit_operand(&mut func, loc); self.visit_operand(&mut func, loc);
for arg in &mut args { for arg in &mut args {
self.visit_operand(arg, loc); self.visit_operand(arg, loc);
@ -272,7 +272,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
func, func,
args, args,
cleanup: None, cleanup: None,
destination: Some((Place::Local(new_temp), new_target)) destination: Some((Place::Local(new_temp), new_target)),
from_hir_call,
}, },
..terminator ..terminator
}; };

View File

@ -318,6 +318,7 @@ fn check_terminator(
TerminatorKind::Call { TerminatorKind::Call {
func, func,
args, args,
from_hir_call: _,
destination: _, destination: _,
cleanup: _, cleanup: _,
} => { } => {

View File

@ -545,8 +545,9 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
args: vec![Operand::Move(Place::Local(ref_place))], args: vec![Operand::Move(Place::Local(ref_place))],
destination: Some((unit_temp, succ)), destination: Some((unit_temp, succ)),
cleanup: unwind.into_option(), cleanup: unwind.into_option(),
from_hir_call: true,
}, },
source_info: self.source_info source_info: self.source_info,
}), }),
is_cleanup: unwind.is_cleanup(), is_cleanup: unwind.is_cleanup(),
}; };
@ -903,7 +904,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
args: args, args: args,
destination: Some((unit_temp, target)), destination: Some((unit_temp, target)),
cleanup: None cleanup: None,
from_hir_call: false,
}; // FIXME(#43234) }; // FIXME(#43234)
let free_block = self.new_block(unwind, call); let free_block = self.new_block(unwind, call);