Skip to content

Commit cb1bec9

Browse files
committed
Fix some type-related bugs
Some types weren't being properly monomorphised, and didn't have their regions properly erased. This is now fixed. Also fixes an issue where a temp was initialized in two separate branches, but wasn't given an alloca.
1 parent 73790f0 commit cb1bec9

File tree

4 files changed

+36
-18
lines changed

4 files changed

+36
-18
lines changed

src/librustc_trans/mir/analyze.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ impl<'tcx> Visitor<'tcx> for TempAnalyzer {
105105
match *lvalue {
106106
mir::Lvalue::Temp(index) => {
107107
match context {
108-
LvalueContext::Call |
108+
LvalueContext::Call => {
109+
self.mark_assigned(index as usize);
110+
}
109111
LvalueContext::Consume => {
110112
}
111113
LvalueContext::Store |

src/librustc_trans/mir/block.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use adt;
1616
use base;
1717
use build;
1818
use callee::{Callee, CalleeData, Fn, Intrinsic, NamedTupleConstructor, Virtual};
19-
use common::{self, Block, BlockAndBuilder, C_undef};
19+
use common::{self, type_is_fat_ptr, Block, BlockAndBuilder, C_undef};
2020
use debuginfo::DebugLoc;
2121
use Disr;
2222
use machine::{llalign_of_min, llbitsize_of_real};
@@ -169,6 +169,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
169169
_ => bug!("{} is not callable", callee.ty)
170170
};
171171

172+
let sig = bcx.tcx().erase_late_bound_regions(sig);
173+
172174
// Handle intrinsics old trans wants Expr's for, ourselves.
173175
let intrinsic = match (&callee.ty.sty, &callee.data) {
174176
(&ty::TyFnDef(def_id, _, _), &Intrinsic) => {
@@ -200,7 +202,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
200202
return;
201203
}
202204

203-
let extra_args = &args[sig.0.inputs.len()..];
205+
let extra_args = &args[sig.inputs.len()..];
204206
let extra_args = extra_args.iter().map(|op_arg| {
205207
self.mir.operand_ty(bcx.tcx(), op_arg)
206208
}).collect::<Vec<_>>();
@@ -263,30 +265,30 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
263265
};
264266

265267
bcx.with_block(|bcx| {
266-
let res = trans_intrinsic_call(bcx, callee.ty, &fn_ty,
268+
trans_intrinsic_call(bcx, callee.ty, &fn_ty,
267269
ArgVals(llargs), dest,
268270
DebugLoc::None);
269-
let bcx = res.bcx.build();
270-
if let Some((_, target)) = *destination {
271-
for op in args {
272-
self.set_operand_dropped(&bcx, op);
273-
}
274-
funclet_br(bcx, self.llblock(target));
275-
} else {
276-
// trans_intrinsic_call already used Unreachable.
277-
// bcx.unreachable();
278-
}
279271
});
280272

281273
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
282274
// Make a fake operand for store_return
283275
let op = OperandRef {
284276
val: OperandValue::Ref(dst),
285-
ty: sig.0.output.unwrap()
277+
ty: sig.output.unwrap()
286278
};
287279
self.store_return(&bcx, ret_dest, fn_ty.ret, op);
288280
}
289281

282+
if let Some((_, target)) = *destination {
283+
for op in args {
284+
self.set_operand_dropped(&bcx, op);
285+
}
286+
funclet_br(bcx, self.llblock(target));
287+
} else {
288+
// trans_intrinsic_call already used Unreachable.
289+
// bcx.unreachable();
290+
}
291+
290292
return;
291293
}
292294
Fn(f) => f,
@@ -318,7 +320,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
318320
ret_bcx.at_start(|ret_bcx| {
319321
let op = OperandRef {
320322
val: OperandValue::Immediate(invokeret),
321-
ty: sig.0.output.unwrap()
323+
ty: sig.output.unwrap()
322324
};
323325
self.store_return(&ret_bcx, ret_dest, fn_ty.ret, op);
324326
for op in args {
@@ -332,7 +334,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
332334
if let Some((_, target)) = *destination {
333335
let op = OperandRef {
334336
val: OperandValue::Immediate(llret),
335-
ty: sig.0.output.unwrap()
337+
ty: sig.output.unwrap()
336338
};
337339
self.store_return(&bcx, ret_dest, fn_ty.ret, op);
338340
for op in args {
@@ -554,6 +556,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
554556
let dest = match *dest {
555557
mir::Lvalue::Temp(idx) => {
556558
let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), dest);
559+
let lvalue_ty = bcx.monomorphize(&lvalue_ty);
557560
let ret_ty = lvalue_ty.to_ty(bcx.tcx());
558561
match self.temps[idx as usize] {
559562
TempRef::Lvalue(dest) => dest,
@@ -633,6 +636,18 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
633636
self.temps[idx as usize] = TempRef::Operand(Some(op));
634637
}
635638
DirectOperand(idx) => {
639+
let op = if type_is_fat_ptr(bcx.tcx(), op.ty) {
640+
let llval = op.immediate();
641+
let ptr = bcx.extract_value(llval, 0);
642+
let meta = bcx.extract_value(llval, 1);
643+
644+
OperandRef {
645+
val: OperandValue::FatPtr(ptr, meta),
646+
ty: op.ty
647+
}
648+
} else {
649+
op
650+
};
636651
self.temps[idx as usize] = TempRef::Operand(Some(op));
637652
}
638653
}

src/librustc_trans/mir/lvalue.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
220220
TempRef::Lvalue(lvalue) => f(self, lvalue),
221221
TempRef::Operand(None) => {
222222
let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), lvalue);
223+
let lvalue_ty = bcx.monomorphize(&lvalue_ty);
223224
let lvalue = LvalueRef::alloca(bcx,
224225
lvalue_ty.to_ty(bcx.tcx()),
225226
"lvalue_temp");

src/librustc_trans/type_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
182182

183183
debug!("type_of {:?}", t);
184184

185-
assert!(!t.has_escaping_regions());
185+
assert!(!t.has_escaping_regions(), "{:?} has escaping regions", t);
186186

187187
// Replace any typedef'd types with their equivalent non-typedef
188188
// type. This ensures that all LLVM nominal types that contain

0 commit comments

Comments
 (0)