Skip to content

Commit d337f34

Browse files
authored
Auto merge of #37220 - Mark-Simulacrum:arena-alloc-slice, r=eddyb
alloc_slice in TypedArena Added `TypedArena::alloc_slice`, and moved from using `TypedArena<Vec<T>>` to `TypedArena<T>`. `TypedArena::alloc_slice` is implemented by copying the slices elements into the typed arena, requiring that `T: Copy` when using it. We allocate a new chunk when there's insufficient space remaining in the previous chunk, and we cannot resize the old chunk in place. This is non-optimal, since we may waste allocated space when allocating (especially longer) slices, but is considered good enough for the time being. This change also reduces heap fragmentation, since the arena now directly stores objects instead of storing the Vec's length and pointer to its contents. Performance: ``` futures-rs-test 5.048s vs 5.061s --> 0.997x faster (variance: 1.028x, 1.020x) helloworld 0.284s vs 0.295s --> 0.963x faster (variance: 1.207x, 1.189x) html5ever-2016- 8.396s vs 8.208s --> 1.023x faster (variance: 1.019x, 1.036x) hyper.0.5.0 5.768s vs 5.797s --> 0.995x faster (variance: 1.027x, 1.028x) inflate-0.1.0 5.213s vs 5.069s --> 1.028x faster (variance: 1.008x, 1.022x) issue-32062-equ 0.428s vs 0.467s --> 0.916x faster (variance: 1.188x, 1.015x) issue-32278-big 1.949s vs 2.010s --> 0.970x faster (variance: 1.112x, 1.049x) jld-day15-parse 1.795s vs 1.877s --> 0.956x faster (variance: 1.037x, 1.015x) piston-image-0. 13.554s vs 13.522s --> 1.002x faster (variance: 1.019x, 1.020x) rust-encoding-0 2.489s vs 2.465s --> 1.010x faster (variance: 1.047x, 1.086x) syntex-0.42.2 34.646s vs 34.593s --> 1.002x faster (variance: 1.007x, 1.005x) syntex-0.42.2-i 17.181s vs 17.163s --> 1.001x faster (variance: 1.004x, 1.004x) ``` r? @eddyb
2 parents cfc9b51 + 83b1982 commit d337f34

File tree

19 files changed

+93
-56
lines changed

19 files changed

+93
-56
lines changed

src/libarena/lib.rs

+39-6
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use std::intrinsics;
4646
use std::marker::{PhantomData, Send};
4747
use std::mem;
4848
use std::ptr;
49+
use std::slice;
4950

5051
use alloc::heap;
5152
use alloc::raw_vec::RawVec;
@@ -133,7 +134,7 @@ impl<T> TypedArena<T> {
133134
#[inline]
134135
pub fn alloc(&self, object: T) -> &mut T {
135136
if self.ptr == self.end {
136-
self.grow()
137+
self.grow(1)
137138
}
138139

139140
unsafe {
@@ -154,24 +155,56 @@ impl<T> TypedArena<T> {
154155
}
155156
}
156157

158+
/// Allocates a slice of objects that are copy into the `TypedArena`, returning a mutable
159+
/// reference to it. Will panic if passed a zero-sized types.
160+
#[inline]
161+
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
162+
where T: Copy {
163+
assert!(mem::size_of::<T>() != 0);
164+
if slice.len() == 0 {
165+
return unsafe { slice::from_raw_parts_mut(heap::EMPTY as *mut T, 0) };
166+
}
167+
168+
let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize;
169+
let at_least_bytes = slice.len() * mem::size_of::<T>();
170+
if available_capacity_bytes < at_least_bytes {
171+
self.grow(slice.len());
172+
}
173+
174+
unsafe {
175+
let start_ptr = self.ptr.get();
176+
let arena_slice = slice::from_raw_parts_mut(start_ptr, slice.len());
177+
self.ptr.set(start_ptr.offset(arena_slice.len() as isize));
178+
arena_slice.copy_from_slice(slice);
179+
arena_slice
180+
}
181+
}
182+
157183
/// Grows the arena.
158184
#[inline(never)]
159185
#[cold]
160-
fn grow(&self) {
186+
fn grow(&self, n: usize) {
161187
unsafe {
162188
let mut chunks = self.chunks.borrow_mut();
163-
let (chunk, new_capacity);
189+
let (chunk, mut new_capacity);
164190
if let Some(last_chunk) = chunks.last_mut() {
165-
if last_chunk.storage.double_in_place() {
191+
let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
192+
let currently_used_cap = used_bytes / mem::size_of::<T>();
193+
if last_chunk.storage.reserve_in_place(currently_used_cap, n) {
166194
self.end.set(last_chunk.end());
167195
return;
168196
} else {
169197
let prev_capacity = last_chunk.storage.cap();
170-
new_capacity = prev_capacity.checked_mul(2).unwrap();
198+
loop {
199+
new_capacity = prev_capacity.checked_mul(2).unwrap();
200+
if new_capacity >= currently_used_cap + n {
201+
break;
202+
}
203+
}
171204
}
172205
} else {
173206
let elem_size = cmp::max(1, mem::size_of::<T>());
174-
new_capacity = cmp::max(1, PAGE / elem_size);
207+
new_capacity = cmp::max(n, PAGE / elem_size);
175208
}
176209
chunk = TypedArenaChunk::<T>::new(new_capacity);
177210
self.ptr.set(chunk.start());

src/librustc/mir/tcx.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<'tcx> Rvalue<'tcx> {
163163
let lhs_ty = lhs.ty(mir, tcx);
164164
let rhs_ty = rhs.ty(mir, tcx);
165165
let ty = op.ty(tcx, lhs_ty, rhs_ty);
166-
let ty = tcx.mk_tup(vec![ty, tcx.types.bool]);
166+
let ty = tcx.mk_tup(&[ty, tcx.types.bool]);
167167
Some(ty)
168168
}
169169
&Rvalue::UnaryOp(_, ref operand) => {
@@ -184,7 +184,7 @@ impl<'tcx> Rvalue<'tcx> {
184184
}
185185
AggregateKind::Tuple => {
186186
Some(tcx.mk_tup(
187-
ops.iter().map(|op| op.ty(mir, tcx)).collect()
187+
&ops.iter().map(|op| op.ty(mir, tcx)).collect::<Vec<_>>()
188188
))
189189
}
190190
AggregateKind::Adt(def, _, substs, _) => {

src/librustc/traits/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
486486
{
487487
let arguments_tuple = match tuple_arguments {
488488
TupleArgumentsFlag::No => sig.0.inputs[0],
489-
TupleArgumentsFlag::Yes => self.mk_tup(sig.0.inputs.to_vec()),
489+
TupleArgumentsFlag::Yes => self.mk_tup(&sig.0.inputs),
490490
};
491491
let trait_ref = ty::TraitRef {
492492
def_id: fn_trait_def_id,

src/librustc/ty/context.rs

+21-17
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ use hir;
5454
pub struct CtxtArenas<'tcx> {
5555
// internings
5656
type_: TypedArena<TyS<'tcx>>,
57-
type_list: TypedArena<Vec<Ty<'tcx>>>,
58-
substs: TypedArena<Vec<Kind<'tcx>>>,
57+
type_list: TypedArena<Ty<'tcx>>,
58+
substs: TypedArena<Kind<'tcx>>,
5959
bare_fn: TypedArena<BareFnTy<'tcx>>,
6060
region: TypedArena<Region>,
6161
stability: TypedArena<attr::Stability>,
@@ -1117,6 +1117,7 @@ impl<'tcx> Borrow<Region> for Interned<'tcx, Region> {
11171117

11181118
macro_rules! intern_method {
11191119
($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
1120+
$alloc_method:ident,
11201121
$alloc_to_key:expr,
11211122
$alloc_to_ret:expr,
11221123
$needs_infer:expr) -> $ty:ty) => {
@@ -1142,7 +1143,8 @@ macro_rules! intern_method {
11421143
let v = unsafe {
11431144
mem::transmute(v)
11441145
};
1145-
let i = ($alloc_to_ret)(self.global_interners.arenas.$name.alloc(v));
1146+
let i = ($alloc_to_ret)(self.global_interners.arenas.$name
1147+
.$alloc_method(v));
11461148
self.global_interners.$name.borrow_mut().insert(Interned(i));
11471149
return i;
11481150
}
@@ -1156,7 +1158,7 @@ macro_rules! intern_method {
11561158
}
11571159
}
11581160

1159-
let i = ($alloc_to_ret)(self.interners.arenas.$name.alloc(v));
1161+
let i = ($alloc_to_ret)(self.interners.arenas.$name.$alloc_method(v));
11601162
self.interners.$name.borrow_mut().insert(Interned(i));
11611163
i
11621164
}
@@ -1180,7 +1182,7 @@ macro_rules! direct_interners {
11801182
}
11811183
}
11821184

1183-
intern_method!($lt_tcx, $name: $method($ty, |x| x, |x| x, $needs_infer) -> $ty);)+
1185+
intern_method!($lt_tcx, $name: $method($ty, alloc, |x| x, |x| x, $needs_infer) -> $ty);)+
11841186
}
11851187
}
11861188

@@ -1200,16 +1202,18 @@ direct_interners!('tcx,
12001202
}) -> Region
12011203
);
12021204

1203-
intern_method!('tcx,
1204-
type_list: mk_type_list(Vec<Ty<'tcx>>, Deref::deref, |xs: &[Ty]| -> &Slice<Ty> {
1205-
unsafe { mem::transmute(xs) }
1206-
}, keep_local) -> Slice<Ty<'tcx>>
1207-
);
1205+
macro_rules! slice_interners {
1206+
($($field:ident: $method:ident($ty:ident)),+) => (
1207+
$(intern_method!('tcx, $field: $method(&[$ty<'tcx>], alloc_slice, Deref::deref,
1208+
|xs: &[$ty]| -> &Slice<$ty> {
1209+
unsafe { mem::transmute(xs) }
1210+
}, |xs: &[$ty]| xs.iter().any(keep_local)) -> Slice<$ty<'tcx>>);)+
1211+
)
1212+
}
12081213

1209-
intern_method!('tcx,
1210-
substs: mk_substs(Vec<Kind<'tcx>>, Deref::deref, |xs: &[Kind]| -> &Slice<Kind> {
1211-
unsafe { mem::transmute(xs) }
1212-
}, keep_local) -> Slice<Kind<'tcx>>
1214+
slice_interners!(
1215+
type_list: mk_type_list(Ty),
1216+
substs: mk_substs(Kind)
12131217
);
12141218

12151219
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
@@ -1314,12 +1318,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13141318
self.mk_ty(TySlice(ty))
13151319
}
13161320

1317-
pub fn mk_tup(self, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
1321+
pub fn mk_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
13181322
self.mk_ty(TyTuple(self.mk_type_list(ts)))
13191323
}
13201324

13211325
pub fn mk_nil(self) -> Ty<'tcx> {
1322-
self.mk_tup(Vec::new())
1326+
self.mk_tup(&[])
13231327
}
13241328

13251329
pub fn mk_diverging_default(self) -> Ty<'tcx> {
@@ -1361,7 +1365,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13611365
pub fn mk_closure(self,
13621366
closure_id: DefId,
13631367
substs: &'tcx Substs<'tcx>,
1364-
tys: Vec<Ty<'tcx>>)
1368+
tys: &[Ty<'tcx>])
13651369
-> Ty<'tcx> {
13661370
self.mk_closure_from_closure_substs(closure_id, ClosureSubsts {
13671371
func_substs: substs,

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1797,7 +1797,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
17971797
_ if tys.references_error() => tcx.types.err,
17981798
0 => tcx.types.bool,
17991799
1 => tys[0],
1800-
_ => tcx.mk_tup(tys)
1800+
_ => tcx.mk_tup(&tys)
18011801
};
18021802

18031803
match self.sized_constraint.get(dep_node()) {

src/librustc/ty/relate.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
491491
if as_.len() == bs.len() {
492492
let ts = as_.iter().zip(bs)
493493
.map(|(a, b)| relation.relate(a, b))
494-
.collect::<Result<_, _>>()?;
495-
Ok(tcx.mk_tup(ts))
494+
.collect::<Result<Vec<_>, _>>()?;
495+
Ok(tcx.mk_tup(&ts))
496496
} else if !(as_.is_empty() || bs.is_empty()) {
497497
Err(TypeError::TupleSize(
498498
expected_found(relation, &as_.len(), &bs.len())))
@@ -547,7 +547,7 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
547547
let upvar_tys = relation.relate_zip(&a.upvar_tys, &b.upvar_tys)?;
548548
Ok(ty::ClosureSubsts {
549549
func_substs: substs,
550-
upvar_tys: relation.tcx().mk_type_list(upvar_tys)
550+
upvar_tys: relation.tcx().mk_type_list(&upvar_tys)
551551
})
552552
}
553553
}

src/librustc/ty/structural_impls.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
448448

449449
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<Ty<'tcx>> {
450450
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
451-
let tys = self.iter().map(|t| t.fold_with(folder)).collect();
452-
folder.tcx().mk_type_list(tys)
451+
let tys = self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>();
452+
folder.tcx().mk_type_list(&tys)
453453
}
454454

455455
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {

src/librustc/ty/subst.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
167167
pub fn new<I>(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I)
168168
-> &'tcx Substs<'tcx>
169169
where I: IntoIterator<Item=Kind<'tcx>> {
170-
tcx.mk_substs(params.into_iter().collect())
170+
tcx.mk_substs(&params.into_iter().collect::<Vec<_>>())
171171
}
172172

173173
pub fn maybe_new<I, E>(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I)
@@ -311,7 +311,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
311311
if params[..] == self[..] {
312312
self
313313
} else {
314-
folder.tcx().mk_substs(params)
314+
folder.tcx().mk_substs(&params)
315315
}
316316
}
317317

src/librustc_driver/test.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
275275
}
276276

277277
pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
278-
self.infcx.tcx.mk_tup(vec![ty1, ty2])
278+
self.infcx.tcx.mk_tup(&[ty1, ty2])
279279
}
280280

281281
pub fn t_param(&self, index: u32) -> Ty<'tcx> {
@@ -803,8 +803,8 @@ fn walk_ty() {
803803
let tcx = env.infcx.tcx;
804804
let int_ty = tcx.types.isize;
805805
let uint_ty = tcx.types.usize;
806-
let tup1_ty = tcx.mk_tup(vec![int_ty, uint_ty, int_ty, uint_ty]);
807-
let tup2_ty = tcx.mk_tup(vec![tup1_ty, tup1_ty, uint_ty]);
806+
let tup1_ty = tcx.mk_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
807+
let tup2_ty = tcx.mk_tup(&[tup1_ty, tup1_ty, uint_ty]);
808808
let uniq_ty = tcx.mk_box(tup2_ty);
809809
let walked: Vec<_> = uniq_ty.walk().collect();
810810
assert_eq!(walked,
@@ -819,8 +819,8 @@ fn walk_ty_skip_subtree() {
819819
let tcx = env.infcx.tcx;
820820
let int_ty = tcx.types.isize;
821821
let uint_ty = tcx.types.usize;
822-
let tup1_ty = tcx.mk_tup(vec![int_ty, uint_ty, int_ty, uint_ty]);
823-
let tup2_ty = tcx.mk_tup(vec![tup1_ty, tup1_ty, uint_ty]);
822+
let tup1_ty = tcx.mk_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
823+
let tup2_ty = tcx.mk_tup(&[tup1_ty, tup1_ty, uint_ty]);
824824
let uniq_ty = tcx.mk_box(tup2_ty);
825825

826826
// types we expect to see (in order), plus a boolean saying

src/librustc_metadata/decoder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ impl<'a, 'tcx> SpecializedDecoder<ty::GenericPredicates<'tcx>> for DecodeContext
374374

375375
impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx> {
376376
fn specialized_decode(&mut self) -> Result<&'tcx Substs<'tcx>, Self::Error> {
377-
Ok(self.tcx().mk_substs(Decodable::decode(self)?))
377+
Ok(self.tcx().mk_substs(&Vec::decode(self)?))
378378
}
379379
}
380380

@@ -386,7 +386,7 @@ impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Region> for DecodeContext<'a, 'tcx>
386386

387387
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> {
388388
fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> {
389-
Ok(self.tcx().mk_type_list(Decodable::decode(self)?))
389+
Ok(self.tcx().mk_type_list(&Vec::decode(self)?))
390390
}
391391
}
392392

src/librustc_mir/build/expr/as_rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
257257
let source_info = self.source_info(span);
258258
let bool_ty = self.hir.bool_ty();
259259
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
260-
let result_tup = self.hir.tcx().mk_tup(vec![ty, bool_ty]);
260+
let result_tup = self.hir.tcx().mk_tup(&[ty, bool_ty]);
261261
let result_value = self.temp(result_tup);
262262

263263
self.cfg.push_assign(block, source_info,

src/librustc_trans/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
327327
}
328328
};
329329
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
330-
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
330+
let tuple_input_ty = tcx.mk_tup(&sig.inputs);
331331
let sig = ty::FnSig {
332332
inputs: vec![bare_fn_ty_maybe_ref,
333333
tuple_input_ty],

src/librustc_trans/mir/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
773773
let rhs = self.const_operand(rhs, span)?;
774774
let ty = lhs.ty;
775775
let val_ty = op.ty(tcx, lhs.ty, rhs.ty);
776-
let binop_ty = tcx.mk_tup(vec![val_ty, tcx.types.bool]);
776+
let binop_ty = tcx.mk_tup(&[val_ty, tcx.types.bool]);
777777
let (lhs, rhs) = (lhs.llval, rhs.llval);
778778
assert!(!ty.is_fp());
779779

src/librustc_trans/mir/rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
430430
lhs.immediate(), rhs.immediate(),
431431
lhs.ty);
432432
let val_ty = op.ty(bcx.tcx(), lhs.ty, rhs.ty);
433-
let operand_ty = bcx.tcx().mk_tup(vec![val_ty, bcx.tcx().types.bool]);
433+
let operand_ty = bcx.tcx().mk_tup(&[val_ty, bcx.tcx().types.bool]);
434434
let operand = OperandRef {
435435
val: result,
436436
ty: operand_ty

src/librustc_typeck/astconv.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
660660
span: output_span
661661
};
662662

663-
(self.tcx().mk_tup(inputs), output_binding)
663+
(self.tcx().mk_tup(&inputs), output_binding)
664664
}
665665

666666
pub fn instantiate_poly_trait_ref(&self,
@@ -1663,8 +1663,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
16631663
hir::TyTup(ref fields) => {
16641664
let flds = fields.iter()
16651665
.map(|t| self.ast_ty_to_ty(rscope, &t))
1666-
.collect();
1667-
tcx.mk_tup(flds)
1666+
.collect::<Vec<_>>();
1667+
tcx.mk_tup(&flds)
16681668
}
16691669
hir::TyBareFn(ref bf) => {
16701670
require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);

src/librustc_typeck/check/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
169169
let max_len = cmp::max(expected_len, elements.len());
170170

171171
let element_tys: Vec<_> = (0 .. max_len).map(|_| self.next_ty_var()).collect();
172-
let pat_ty = tcx.mk_tup(element_tys.clone());
172+
let pat_ty = tcx.mk_tup(&element_tys);
173173
self.demand_eqtype(pat.span, expected, pat_ty);
174174
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
175175
self.check_pat(elem, &element_tys[i]);

src/librustc_typeck/check/closure.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
7171

7272
let closure_type = self.tcx.mk_closure(expr_def_id,
7373
self.parameter_environment.free_substs,
74-
upvar_tys);
74+
&upvar_tys);
7575

7676
let fn_sig = self.tcx
7777
.liberate_late_bound_regions(self.tcx.region_maps.call_site_extent(expr.id, body.id),
@@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
8888

8989
// Tuple up the arguments and insert the resulting function type into
9090
// the `closures` table.
91-
fn_ty.sig.0.inputs = vec![self.tcx.mk_tup(fn_ty.sig.0.inputs)];
91+
fn_ty.sig.0.inputs = vec![self.tcx.mk_tup(&fn_ty.sig.0.inputs)];
9292

9393
debug!("closure for {:?} --> sig={:?} opt_kind={:?}",
9494
expr_def_id,

0 commit comments

Comments
 (0)