From b6d9f8387aaa9ccd9ba0b379b60c402561fad970 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 7 Jun 2016 00:24:21 +0300 Subject: [PATCH 1/3] trans: use Pair for ignored nil pairs instead of Immediate. --- src/librustc_trans/mir/mod.rs | 7 ++++++- src/test/run-pass/mir_trans_calls.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index d1206550b13d6..408b30c72582c 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -124,7 +124,12 @@ impl<'tcx> TempRef<'tcx> { // Zero-size temporaries aren't always initialized, which // doesn't matter because they don't contain data, but // we need something in the operand. - let val = OperandValue::Immediate(common::C_nil(ccx)); + let nil = common::C_nil(ccx); + let val = if common::type_is_imm_pair(ccx, ty) { + OperandValue::Pair(nil, nil) + } else { + OperandValue::Immediate(nil) + }; let op = OperandRef { val: val, ty: ty diff --git a/src/test/run-pass/mir_trans_calls.rs b/src/test/run-pass/mir_trans_calls.rs index 31e2c8925711c..0527f38a9c36d 100644 --- a/src/test/run-pass/mir_trans_calls.rs +++ b/src/test/run-pass/mir_trans_calls.rs @@ -147,6 +147,16 @@ fn test_fn_transmute_zst(x: ()) -> [(); 1] { }) } +#[rustc_mir] +fn test_fn_ignored_pair() -> ((), ()) { + ((), ()) +} + +#[rustc_mir] +fn test_fn_ignored_pair_0() { + test_fn_ignored_pair().0 +} + fn main() { assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..])); assert_eq!(test2(98), 98); @@ -169,4 +179,6 @@ fn main() { assert_eq!(test_fn_nil_call(&(|| 42)), 42); assert_eq!(test_fn_transmute_zst(()), [()]); + + assert_eq!(test_fn_ignored_pair_0(), ()); } From 11e31091a9e7e3604d79d9e820067120945c538d Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 7 Jun 2016 02:21:58 +0300 Subject: [PATCH 2/3] trans: don't forget to cast Pair constants of the wrong type. --- src/librustc_trans/mir/constant.rs | 4 ++-- src/test/run-pass/mir_constval_adts.rs | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index d352a8241acd4..5347188707344 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -122,10 +122,10 @@ impl<'tcx> Const<'tcx> { let llty = type_of::immediate_type_of(ccx, self.ty); let llvalty = val_ty(self.llval); - let val = if common::type_is_imm_pair(ccx, self.ty) { + let val = if llty == llvalty && common::type_is_imm_pair(ccx, self.ty) { let (a, b) = self.get_pair(); OperandValue::Pair(a, b) - } else if common::type_is_immediate(ccx, self.ty) && llty == llvalty { + } else if llty == llvalty && common::type_is_immediate(ccx, self.ty) { // If the types match, we can use the value directly. OperandValue::Immediate(self.llval) } else { diff --git a/src/test/run-pass/mir_constval_adts.rs b/src/test/run-pass/mir_constval_adts.rs index 4e9c0bce646e6..0ce9e88ef3dbe 100644 --- a/src/test/run-pass/mir_constval_adts.rs +++ b/src/test/run-pass/mir_constval_adts.rs @@ -15,21 +15,23 @@ struct Point { _y: i32, } +#[derive(PartialEq, Eq, Debug)] +struct Newtype(T); + const STRUCT: Point = Point { _x: 42, _y: 42 }; const TUPLE1: (i32, i32) = (42, 42); const TUPLE2: (&'static str, &'static str) = ("hello","world"); +const PAIR_NEWTYPE: (Newtype, Newtype) = (Newtype(42), Newtype(42)); #[rustc_mir] -fn mir() -> (Point, (i32, i32), (&'static str, &'static str)){ +fn mir() -> (Point, (i32, i32), (&'static str, &'static str), (Newtype, Newtype)) { let struct1 = STRUCT; let tuple1 = TUPLE1; let tuple2 = TUPLE2; - (struct1, tuple1, tuple2) + let pair_newtype = PAIR_NEWTYPE; + (struct1, tuple1, tuple2, pair_newtype) } -#[derive(PartialEq, Eq, Debug)] -struct Newtype(T); - const NEWTYPE: Newtype<&'static str> = Newtype("foobar"); #[rustc_mir] @@ -39,7 +41,7 @@ fn test_promoted_newtype_str_ref() { } fn main(){ - assert_eq!(mir(), (STRUCT, TUPLE1, TUPLE2)); + assert_eq!(mir(), (STRUCT, TUPLE1, TUPLE2, PAIR_NEWTYPE)); test_promoted_newtype_str_ref(); } From 02cbc0ef8ce62ca2c903052fdf13e33af152a38d Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 7 Jun 2016 10:04:31 +0300 Subject: [PATCH 3/3] trans: don't create allocas anywhere other than the entry block. --- src/librustc_trans/mir/block.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index b7aca4c8d7fed..56bf803fcd818 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -894,8 +894,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { // bitcasting to the struct type yields invalid cast errors. // We instead thus allocate some scratch space... - let llscratch = bcx.alloca(llcast_ty, "fn_ret_cast"); - bcx.with_block(|bcx| base::call_lifetime_start(bcx, llscratch)); + let llscratch = bcx.with_block(|bcx| { + let alloca = base::alloca(bcx, llcast_ty, "fn_ret_cast"); + base::call_lifetime_start(bcx, alloca); + alloca + }); // ...where we first store the value... bcx.store(op.immediate(), llscratch);