Skip to content

Commit eb9cb4d

Browse files
committed
trans: derefs don't need the pointer in an alloca.
1 parent 93c32b5 commit eb9cb4d

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/librustc_trans/mir/analyze.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ impl<'mir, 'bcx, 'tcx> Visitor<'tcx> for TempAnalyzer<'mir, 'bcx, 'tcx> {
151151
}
152152
}
153153

154+
// A deref projection only reads the pointer, never needs the lvalue.
155+
if let mir::Lvalue::Projection(ref proj) = *lvalue {
156+
if let mir::ProjectionElem::Deref = proj.elem {
157+
return self.visit_lvalue(&proj.base, LvalueContext::Consume);
158+
}
159+
}
160+
154161
self.super_lvalue(lvalue, context);
155162
}
156163
}

src/librustc_trans/mir/lvalue.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use Disr;
2727
use std::ptr;
2828

2929
use super::{MirContext, TempRef};
30+
use super::operand::OperandValue;
3031

3132
#[derive(Copy, Clone, Debug)]
3233
pub struct LvalueRef<'tcx> {
@@ -121,6 +122,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
121122
let return_ty = fn_return_ty.unwrap();
122123
LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty))
123124
},
125+
mir::Lvalue::Projection(box mir::Projection {
126+
ref base,
127+
elem: mir::ProjectionElem::Deref
128+
}) => {
129+
// Load the pointer from its location.
130+
let ptr = self.trans_consume(bcx, base);
131+
let projected_ty = LvalueTy::from_ty(ptr.ty)
132+
.projection_ty(tcx, &mir::ProjectionElem::Deref);
133+
let projected_ty = bcx.monomorphize(&projected_ty);
134+
let (llptr, llextra) = match ptr.val {
135+
OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()),
136+
OperandValue::Pair(llptr, llextra) => (llptr, llextra),
137+
OperandValue::Ref(_) => bug!("Deref of by-Ref type {:?}", ptr.ty)
138+
};
139+
LvalueRef {
140+
llval: llptr,
141+
llextra: llextra,
142+
ty: projected_ty,
143+
}
144+
}
124145
mir::Lvalue::Projection(ref projection) => {
125146
let tr_base = self.trans_lvalue(bcx, &projection.base);
126147
let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);
@@ -138,15 +159,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
138159
};
139160

140161
let (llprojected, llextra) = match projection.elem {
141-
mir::ProjectionElem::Deref => {
142-
let base_ty = tr_base.ty.to_ty(tcx);
143-
if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) {
144-
(base::load_ty_builder(bcx, tr_base.llval, base_ty),
145-
ptr::null_mut())
146-
} else {
147-
load_fat_ptr(bcx, tr_base.llval)
148-
}
149-
}
162+
mir::ProjectionElem::Deref => bug!(),
150163
mir::ProjectionElem::Field(ref field, _) => {
151164
let base_ty = tr_base.ty.to_ty(tcx);
152165
let base_repr = adt::represent_type(ccx, base_ty);

0 commit comments

Comments
 (0)