From d81140a68f8635f33bc4d83bd27d1f18d434b495 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 11 Jan 2017 09:50:24 +0200 Subject: [PATCH] fix function arguments in constant promotion we can't create the target block until *after* we promote the arguments - otherwise the arguments will be promoted into the target block. oops. Fixes #38985. --- src/librustc_mir/transform/promote_consts.rs | 28 +++++++++++--------- src/test/run-pass/issue-37991.rs | 7 +++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 2a4b2b515cc68..b64ca58bb3ffa 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -238,7 +238,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.visit_rvalue(&mut rvalue, loc); self.assign(new_temp, rvalue, source_info.span); } else { - let mut terminator = if self.keep_original { + let terminator = if self.keep_original { self.source[loc.block].terminator().clone() } else { let terminator = self.source[loc.block].terminator_mut(); @@ -256,28 +256,30 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } }; - let last = self.promoted.basic_blocks().last().unwrap(); - let new_target = self.new_block(); - - terminator.kind = match terminator.kind { + match terminator.kind { TerminatorKind::Call { mut func, mut args, .. } => { self.visit_operand(&mut func, loc); for arg in &mut args { self.visit_operand(arg, loc); } - TerminatorKind::Call { - func: func, - args: args, - cleanup: None, - destination: Some((Lvalue::Local(new_temp), new_target)) - } + + let last = self.promoted.basic_blocks().last().unwrap(); + let new_target = self.new_block(); + + *self.promoted[last].terminator_mut() = Terminator { + kind: TerminatorKind::Call { + func: func, + args: args, + cleanup: None, + destination: Some((Lvalue::Local(new_temp), new_target)) + }, + ..terminator + }; } ref kind => { span_bug!(terminator.source_info.span, "{:?} not promotable", kind); } }; - - *self.promoted[last].terminator_mut() = terminator; }; self.keep_original = old_keep_original; diff --git a/src/test/run-pass/issue-37991.rs b/src/test/run-pass/issue-37991.rs index cacc653871ad5..9bdde02d0061c 100644 --- a/src/test/run-pass/issue-37991.rs +++ b/src/test/run-pass/issue-37991.rs @@ -14,7 +14,14 @@ const fn foo() -> i64 { 3 } +const fn bar(x: i64) -> i64 { + x*2 +} + fn main() { let val = &(foo() % 2); assert_eq!(*val, 1); + + let val2 = &(bar(1+1) % 3); + assert_eq!(*val2, 1); }