});
if let Some(scope) = scope {
// schedule a shallow free of that memory, lest we unwind:
- this.schedule_drop(expr_span, scope, &Place::Local(result), value.ty);
+ this.schedule_drop_storage_and_value(
+ expr_span, scope, &Place::Local(result), value.ty,
+ );
}
// malloc some memory of suitable type (thus far, uninitialized):
}
ExprKind::Closure { closure_id, substs, upvars, movability } => {
// see (*) above
- let mut operands: Vec<_> =
- upvars.into_iter()
- .map(|upvar| unpack!(block = this.as_operand(block, scope, upvar)))
- .collect();
+ let mut operands: Vec<_> = upvars
+ .into_iter()
+ .map(|upvar| {
+ let upvar = this.hir.mirror(upvar);
+ match Category::of(&upvar.kind) {
+ // Use as_place to avoid creating a temporary when
+ // moving a variable into a closure, so that
+ // borrowck knows which variables to mark as being
+ // used as mut. This is OK here because the upvar
+ // expressions have no side effects and act on
+ // disjoint places.
+ // This occurs when capturing by copy/move, while
+ // by reference captures use as_operand
+ Some(Category::Place) => {
+ let place = unpack!(block = this.as_place(block, upvar));
+ this.consume_by_copy_or_move(place)
+ }
+ _ => {
+ unpack!(block = this.as_operand(block, scope, upvar))
+ }
+ }
+ })
+ .collect();
let result = match substs {
UpvarSubsts::Generator(substs) => {
let movability = movability.unwrap();
value: ty::Const::from_bits(
this.hir.tcx(),
0,
- this.hir.tcx().types.u32),
+ ty::ParamEnv::empty().and(this.hir.tcx().types.u32)),
},
}));
box AggregateKind::Generator(closure_id, substs, movability)
// Helper to get a `-1` value of the appropriate type
fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
- let bits = self.hir.integer_bit_width(ty);
+ let param_ty = ty::ParamEnv::empty().and(self.hir.tcx().lift_to_global(&ty).unwrap());
+ let bits = self.hir.tcx().layout_of(param_ty).unwrap().size.bits();
let n = (!0u128) >> (128 - bits);
let literal = Literal::Value {
- value: ty::Const::from_bits(self.hir.tcx(), n, ty)
+ value: ty::Const::from_bits(self.hir.tcx(), n, param_ty)
};
self.literal_operand(span, ty, literal)
// Helper to get the minimum value of the appropriate type
fn minval_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
assert!(ty.is_signed());
- let bits = self.hir.integer_bit_width(ty);
+ let param_ty = ty::ParamEnv::empty().and(self.hir.tcx().lift_to_global(&ty).unwrap());
+ let bits = self.hir.tcx().layout_of(param_ty).unwrap().size.bits();
let n = 1 << (bits - 1);
let literal = Literal::Value {
- value: ty::Const::from_bits(self.hir.tcx(), n, ty)
+ value: ty::Const::from_bits(self.hir.tcx(), n, param_ty)
};
self.literal_operand(span, ty, literal)