|
11 | 11 | use llvm::{self, ValueRef, BasicBlockRef}; |
12 | 12 | use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err}; |
13 | 13 | use rustc::middle::lang_items; |
14 | | -use rustc::ty::{self, layout}; |
| 14 | +use rustc::ty::{self, layout, TypeFoldable}; |
15 | 15 | use rustc::mir; |
16 | 16 | use abi::{Abi, FnType, ArgType}; |
17 | 17 | use adt; |
@@ -435,10 +435,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { |
435 | 435 |
|
436 | 436 | if intrinsic == Some("transmute") { |
437 | 437 | let &(ref dest, target) = destination.as_ref().unwrap(); |
438 | | - self.with_lvalue_ref(&bcx, dest, |this, dest| { |
439 | | - this.trans_transmute(&bcx, &args[0], dest); |
440 | | - }); |
441 | | - |
| 438 | + self.trans_transmute(&bcx, &args[0], dest); |
442 | 439 | funclet_br(self, bcx, target); |
443 | 440 | return; |
444 | 441 | } |
@@ -877,7 +874,34 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { |
877 | 874 | } |
878 | 875 |
|
879 | 876 | fn trans_transmute(&mut self, bcx: &Builder<'a, 'tcx>, |
880 | | - src: &mir::Operand<'tcx>, dst: LvalueRef<'tcx>) { |
| 877 | + src: &mir::Operand<'tcx>, |
| 878 | + dst: &mir::Lvalue<'tcx>) { |
| 879 | + if let mir::Lvalue::Local(index) = *dst { |
| 880 | + match self.locals[index] { |
| 881 | + LocalRef::Lvalue(lvalue) => self.trans_transmute_into(bcx, src, &lvalue), |
| 882 | + LocalRef::Operand(None) => { |
| 883 | + let lvalue_ty = self.monomorphized_lvalue_ty(dst); |
| 884 | + assert!(!lvalue_ty.has_erasable_regions()); |
| 885 | + let lvalue = LvalueRef::alloca(bcx, lvalue_ty, "transmute_temp"); |
| 886 | + self.trans_transmute_into(bcx, src, &lvalue); |
| 887 | + let op = self.trans_load(bcx, lvalue.llval, lvalue.alignment, lvalue_ty); |
| 888 | + self.locals[index] = LocalRef::Operand(Some(op)); |
| 889 | + } |
| 890 | + LocalRef::Operand(Some(_)) => { |
| 891 | + let ty = self.monomorphized_lvalue_ty(dst); |
| 892 | + assert!(common::type_is_zero_size(bcx.ccx, ty), |
| 893 | + "assigning to initialized SSAtemp"); |
| 894 | + } |
| 895 | + } |
| 896 | + } else { |
| 897 | + let dst = self.trans_lvalue(bcx, dst); |
| 898 | + self.trans_transmute_into(bcx, src, &dst); |
| 899 | + } |
| 900 | + } |
| 901 | + |
| 902 | + fn trans_transmute_into(&mut self, bcx: &Builder<'a, 'tcx>, |
| 903 | + src: &mir::Operand<'tcx>, |
| 904 | + dst: &LvalueRef<'tcx>) { |
881 | 905 | let mut val = self.trans_operand(bcx, src); |
882 | 906 | if let ty::TyFnDef(def_id, substs, _) = val.ty.sty { |
883 | 907 | let llouttype = type_of::type_of(bcx.ccx, dst.ty.to_ty(bcx.tcx())); |
|
0 commit comments