|
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