Skip to content

Commit ff261d3

Browse files
committed
Auto merge of #38097 - Mark-Simulacrum:fn-sig-slice, r=eddyb
Refactor ty::FnSig to contain a &'tcx Slice<Ty<'tcx>> We refactor this in order to achieve the following wins: - Decrease the size of `FnSig` (`Vec` + `bool`: 32, `&Slice` + `bool`: 24). - Potentially decrease total allocated memory due to arena-allocating `FnSig` inputs/output; since they are allocated in the type list arena, other users of type lists can reuse the same allocation for an equivalent type list. - Remove the last part of the type system which needs drop glue (#37965 removed the other remaining part). This makes arenas containing `FnSig` faster to drop (since we don't need to drop a Vec for each one), and makes reusing them without clearing/dropping potentially possible. r? @eddyb
2 parents f7c93c0 + 296ec5f commit ff261d3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+264
-291
lines changed

src/librustc/middle/intrinsicck.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> {
178178
let typ = self.infcx.tcx.tables().node_id_to_type(expr.id);
179179
match typ.sty {
180180
ty::TyFnDef(.., ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
181-
let from = bare_fn_ty.sig.0.inputs[0];
182-
let to = bare_fn_ty.sig.0.output;
181+
let from = bare_fn_ty.sig.skip_binder().inputs()[0];
182+
let to = bare_fn_ty.sig.skip_binder().output();
183183
self.check_transmute(expr.span, from, to, expr.id);
184184
}
185185
_ => {

src/librustc/traits/object_safety.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
241241
// The `Self` type is erased, so it should not appear in list of
242242
// arguments or return type apart from the receiver.
243243
let ref sig = self.item_type(method.def_id).fn_sig();
244-
for &input_ty in &sig.0.inputs[1..] {
244+
for input_ty in &sig.skip_binder().inputs()[1..] {
245245
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
246246
return Some(MethodViolationCode::ReferencesSelf);
247247
}
248248
}
249-
if self.contains_illegal_self_type_reference(trait_def_id, sig.0.output) {
249+
if self.contains_illegal_self_type_reference(trait_def_id, sig.output().skip_binder()) {
250250
return Some(MethodViolationCode::ReferencesSelf);
251251
}
252252

src/librustc/traits/select.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,21 +1368,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
13681368
ty::TyFnDef(.., &ty::BareFnTy {
13691369
unsafety: hir::Unsafety::Normal,
13701370
abi: Abi::Rust,
1371-
sig: ty::Binder(ty::FnSig {
1372-
inputs: _,
1373-
output: _,
1374-
variadic: false
1375-
})
1371+
ref sig,
13761372
}) |
13771373
ty::TyFnPtr(&ty::BareFnTy {
13781374
unsafety: hir::Unsafety::Normal,
13791375
abi: Abi::Rust,
1380-
sig: ty::Binder(ty::FnSig {
1381-
inputs: _,
1382-
output: _,
1383-
variadic: false
1384-
})
1385-
}) => {
1376+
ref sig
1377+
}) if !sig.variadic() => {
13861378
candidates.vec.push(FnPointerCandidate);
13871379
}
13881380

src/librustc/traits/util.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,14 +487,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
487487
-> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)>
488488
{
489489
let arguments_tuple = match tuple_arguments {
490-
TupleArgumentsFlag::No => sig.0.inputs[0],
491-
TupleArgumentsFlag::Yes => self.intern_tup(&sig.0.inputs[..]),
490+
TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
491+
TupleArgumentsFlag::Yes =>
492+
self.intern_tup(sig.skip_binder().inputs()),
492493
};
493494
let trait_ref = ty::TraitRef {
494495
def_id: fn_trait_def_id,
495496
substs: self.mk_substs_trait(self_ty, &[arguments_tuple]),
496497
};
497-
ty::Binder((trait_ref, sig.0.output))
498+
ty::Binder((trait_ref, sig.skip_binder().output()))
498499
}
499500
}
500501

src/librustc/ty/context.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,6 +1542,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
15421542
}
15431543
}
15441544

1545+
pub fn mk_fn_sig<I>(self, inputs: I, output: I::Item, variadic: bool)
1546+
-> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
1547+
where I: Iterator,
1548+
I::Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>
1549+
{
1550+
inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
1551+
inputs_and_output: self.intern_type_list(xs),
1552+
variadic: variadic
1553+
})
1554+
}
1555+
15451556
pub fn mk_existential_predicates<I: InternAs<[ExistentialPredicate<'tcx>],
15461557
&'tcx Slice<ExistentialPredicate<'tcx>>>>(self, iter: I)
15471558
-> I::Output {

src/librustc/ty/fast_reject.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
8181
Some(TupleSimplifiedType(tys.len()))
8282
}
8383
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => {
84-
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
84+
Some(FunctionSimplifiedType(f.sig.skip_binder().inputs().len()))
8585
}
8686
ty::TyProjection(_) | ty::TyParam(_) => {
8787
if can_simplify_params {

src/librustc/ty/flags.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ impl FlagComputation {
180180
fn add_fn_sig(&mut self, fn_sig: &ty::PolyFnSig) {
181181
let mut computation = FlagComputation::new();
182182

183-
computation.add_tys(&fn_sig.0.inputs);
184-
computation.add_ty(fn_sig.0.output);
183+
computation.add_tys(fn_sig.skip_binder().inputs());
184+
computation.add_ty(fn_sig.skip_binder().output());
185185

186186
self.add_bound_computation(&computation);
187187
}

src/librustc/ty/relate.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ use ty::subst::{Kind, Substs};
1818
use ty::{self, Ty, TyCtxt, TypeFoldable};
1919
use ty::error::{ExpectedFound, TypeError};
2020
use std::rc::Rc;
21+
use std::iter;
2122
use syntax::abi;
2223
use hir as ast;
24+
use rustc_data_structures::accumulate_vec::AccumulateVec;
2325

2426
pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
2527

@@ -185,32 +187,28 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
185187
expected_found(relation, &a.variadic, &b.variadic)));
186188
}
187189

188-
let inputs = relate_arg_vecs(relation,
189-
&a.inputs,
190-
&b.inputs)?;
191-
let output = relation.relate(&a.output, &b.output)?;
190+
if a.inputs().len() != b.inputs().len() {
191+
return Err(TypeError::ArgCount);
192+
}
192193

193-
Ok(ty::FnSig {inputs: inputs,
194-
output: output,
195-
variadic: a.variadic})
194+
let inputs_and_output = a.inputs().iter().cloned()
195+
.zip(b.inputs().iter().cloned())
196+
.map(|x| (x, false))
197+
.chain(iter::once(((a.output(), b.output()), true)))
198+
.map(|((a, b), is_output)| {
199+
if is_output {
200+
relation.relate(&a, &b)
201+
} else {
202+
relation.relate_with_variance(ty::Contravariant, &a, &b)
203+
}
204+
}).collect::<Result<AccumulateVec<[_; 8]>, _>>()?;
205+
Ok(ty::FnSig {
206+
inputs_and_output: relation.tcx().intern_type_list(&inputs_and_output),
207+
variadic: a.variadic
208+
})
196209
}
197210
}
198211

199-
fn relate_arg_vecs<'a, 'gcx, 'tcx, R>(relation: &mut R,
200-
a_args: &[Ty<'tcx>],
201-
b_args: &[Ty<'tcx>])
202-
-> RelateResult<'tcx, Vec<Ty<'tcx>>>
203-
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
204-
{
205-
if a_args.len() != b_args.len() {
206-
return Err(TypeError::ArgCount);
207-
}
208-
209-
a_args.iter().zip(b_args)
210-
.map(|(a, b)| relation.relate_with_variance(ty::Contravariant, a, b))
211-
.collect()
212-
}
213-
214212
impl<'tcx> Relate<'tcx> for ast::Unsafety {
215213
fn relate<'a, 'gcx, R>(relation: &mut R,
216214
a: &ast::Unsafety,

src/librustc/ty/structural_impls.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
232232
impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
233233
type Lifted = ty::FnSig<'tcx>;
234234
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
235-
tcx.lift(&self.inputs[..]).and_then(|inputs| {
236-
tcx.lift(&self.output).map(|output| {
237-
ty::FnSig {
238-
inputs: inputs,
239-
output: output,
240-
variadic: self.variadic
241-
}
242-
})
235+
tcx.lift(&self.inputs_and_output).map(|x| {
236+
ty::FnSig {
237+
inputs_and_output: x,
238+
variadic: self.variadic
239+
}
243240
})
244241
}
245242
}
@@ -589,17 +586,20 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
589586

590587
impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
591588
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
592-
ty::FnSig { inputs: self.inputs.fold_with(folder),
593-
output: self.output.fold_with(folder),
594-
variadic: self.variadic }
589+
let inputs_and_output = self.inputs_and_output.fold_with(folder);
590+
ty::FnSig {
591+
inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
592+
variadic: self.variadic,
593+
}
595594
}
596595

597596
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
598597
folder.fold_fn_sig(self)
599598
}
600599

601600
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
602-
self.inputs.visit_with(visitor) || self.output.visit_with(visitor)
601+
self.inputs().iter().any(|i| i.visit_with(visitor)) ||
602+
self.output().visit_with(visitor)
603603
}
604604
}
605605

src/librustc/ty/sty.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -563,22 +563,31 @@ pub struct ClosureTy<'tcx> {
563563
/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
564564
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
565565
pub struct FnSig<'tcx> {
566-
pub inputs: Vec<Ty<'tcx>>,
567-
pub output: Ty<'tcx>,
566+
pub inputs_and_output: &'tcx Slice<Ty<'tcx>>,
568567
pub variadic: bool
569568
}
570569

570+
impl<'tcx> FnSig<'tcx> {
571+
pub fn inputs(&self) -> &[Ty<'tcx>] {
572+
&self.inputs_and_output[..self.inputs_and_output.len() - 1]
573+
}
574+
575+
pub fn output(&self) -> Ty<'tcx> {
576+
self.inputs_and_output[self.inputs_and_output.len() - 1]
577+
}
578+
}
579+
571580
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
572581

573582
impl<'tcx> PolyFnSig<'tcx> {
574-
pub fn inputs(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
575-
self.map_bound_ref(|fn_sig| fn_sig.inputs.clone())
583+
pub fn inputs(&self) -> Binder<&[Ty<'tcx>]> {
584+
Binder(self.skip_binder().inputs())
576585
}
577586
pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
578-
self.map_bound_ref(|fn_sig| fn_sig.inputs[index])
587+
self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
579588
}
580589
pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
581-
self.map_bound_ref(|fn_sig| fn_sig.output.clone())
590+
self.map_bound_ref(|fn_sig| fn_sig.output().clone())
582591
}
583592
pub fn variadic(&self) -> bool {
584593
self.skip_binder().variadic
@@ -1243,7 +1252,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
12431252
}
12441253

12451254
// Type accessors for substructures of types
1246-
pub fn fn_args(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
1255+
pub fn fn_args(&self) -> ty::Binder<&[Ty<'tcx>]> {
12471256
self.fn_sig().inputs()
12481257
}
12491258

0 commit comments

Comments
 (0)