Skip to content

Commit 296ec5f

Browse files
Refactor FnSig to contain a Slice for its inputs and outputs.
1 parent 1eab19d commit 296ec5f

File tree

21 files changed

+121
-114
lines changed

21 files changed

+121
-114
lines changed

src/librustc/ty/context.rs

+11
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/relate.rs

+19-8
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

@@ -180,21 +182,30 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
180182
-> RelateResult<'tcx, ty::FnSig<'tcx>>
181183
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
182184
{
183-
if a.variadic() != b.variadic() {
185+
if a.variadic != b.variadic {
184186
return Err(TypeError::VariadicMismatch(
185-
expected_found(relation, &a.variadic(), &b.variadic())));
187+
expected_found(relation, &a.variadic, &b.variadic)));
186188
}
187189

188190
if a.inputs().len() != b.inputs().len() {
189191
return Err(TypeError::ArgCount);
190192
}
191193

192-
let inputs = a.inputs().iter().zip(b.inputs()).map(|(&a, &b)| {
193-
relation.relate_with_variance(ty::Contravariant, &a, &b)
194-
}).collect::<Result<Vec<_>, _>>()?;
195-
let output = relation.relate(&a.output(), &b.output())?;
196-
197-
Ok(ty::FnSig::new(inputs, output, 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+
})
198209
}
199210
}
200211

src/librustc/ty/structural_impls.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -232,10 +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::new(inputs, output, self.variadic())
238-
})
235+
tcx.lift(&self.inputs_and_output).map(|x| {
236+
ty::FnSig {
237+
inputs_and_output: x,
238+
variadic: self.variadic
239+
}
239240
})
240241
}
241242
}
@@ -585,17 +586,20 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
585586

586587
impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
587588
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
588-
ty::FnSig::new(self.inputs().to_owned().fold_with(folder),
589-
self.output().fold_with(folder),
590-
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+
}
591594
}
592595

593596
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
594597
folder.fold_fn_sig(self)
595598
}
596599

597600
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
598-
self.inputs().to_owned().visit_with(visitor) || self.output().visit_with(visitor)
601+
self.inputs().iter().any(|i| i.visit_with(visitor)) ||
602+
self.output().visit_with(visitor)
599603
}
600604
}
601605

src/librustc/ty/sty.rs

+10-19
Original file line numberDiff line numberDiff line change
@@ -563,40 +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-
inputs: Vec<Ty<'tcx>>,
567-
output: Ty<'tcx>,
568-
variadic: bool
566+
pub inputs_and_output: &'tcx Slice<Ty<'tcx>>,
567+
pub variadic: bool
569568
}
570569

571570
impl<'tcx> FnSig<'tcx> {
572-
pub fn new(inputs: Vec<Ty<'tcx>>, output: Ty<'tcx>, variadic: bool) -> Self {
573-
FnSig { inputs: inputs, output: output, variadic: variadic }
574-
}
575-
576571
pub fn inputs(&self) -> &[Ty<'tcx>] {
577-
&self.inputs
572+
&self.inputs_and_output[..self.inputs_and_output.len() - 1]
578573
}
579574

580575
pub fn output(&self) -> Ty<'tcx> {
581-
self.output
582-
}
583-
584-
pub fn variadic(&self) -> bool {
585-
self.variadic
576+
self.inputs_and_output[self.inputs_and_output.len() - 1]
586577
}
587578
}
588579

589580
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
590581

591582
impl<'tcx> PolyFnSig<'tcx> {
592-
pub fn inputs<'a>(&'a self) -> Binder<&[Ty<'tcx>]> {
593-
Binder(self.0.inputs())
583+
pub fn inputs(&self) -> Binder<&[Ty<'tcx>]> {
584+
Binder(self.skip_binder().inputs())
594585
}
595586
pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
596-
self.map_bound_ref(|fn_sig| fn_sig.inputs[index])
587+
self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
597588
}
598589
pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
599-
self.map_bound_ref(|fn_sig| fn_sig.output.clone())
590+
self.map_bound_ref(|fn_sig| fn_sig.output().clone())
600591
}
601592
pub fn variadic(&self) -> bool {
602593
self.skip_binder().variadic
@@ -1261,8 +1252,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
12611252
}
12621253

12631254
// Type accessors for substructures of types
1264-
pub fn fn_args(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
1265-
ty::Binder(self.fn_sig().inputs().skip_binder().iter().cloned().collect::<Vec<_>>())
1255+
pub fn fn_args(&self) -> ty::Binder<&[Ty<'tcx>]> {
1256+
self.fn_sig().inputs()
12661257
}
12671258

12681259
pub fn fn_ret(&self) -> Binder<Ty<'tcx>> {

src/librustc/util/ppaux.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
595595
impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
596596
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
597597
write!(f, "fn")?;
598-
fn_sig(f, self.inputs(), self.variadic(), self.output())
598+
fn_sig(f, self.inputs(), self.variadic, self.output())
599599
}
600600
}
601601

@@ -625,7 +625,7 @@ impl fmt::Debug for ty::RegionVid {
625625

626626
impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
627627
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
628-
write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic(), self.output())
628+
write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic, self.output())
629629
}
630630
}
631631

src/librustc_driver/test.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -265,15 +265,10 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
265265
}
266266

267267
pub fn t_fn(&self, input_tys: &[Ty<'tcx>], output_ty: Ty<'tcx>) -> Ty<'tcx> {
268-
let input_args = input_tys.iter().cloned().collect();
269268
self.infcx.tcx.mk_fn_ptr(self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
270269
unsafety: hir::Unsafety::Normal,
271270
abi: Abi::Rust,
272-
sig: ty::Binder(ty::FnSig {
273-
inputs: input_args,
274-
output: output_ty,
275-
variadic: false,
276-
}),
271+
sig: ty::Binder(self.infcx.tcx.mk_fn_sig(input_tys.iter().cloned(), output_ty, false)),
277272
}))
278273
}
279274

src/librustc_mir/transform/type_check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
529529
{
530530
debug!("check_call_inputs({:?}, {:?})", sig, args);
531531
if args.len() < sig.inputs().len() ||
532-
(args.len() > sig.inputs().len() && !sig.variadic()) {
532+
(args.len() > sig.inputs().len() && !sig.variadic) {
533533
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
534534
}
535535
for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() {

src/librustc_trans/abi.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ impl FnType {
369369

370370
let mut inputs = sig.inputs();
371371
let extra_args = if abi == RustCall {
372-
assert!(!sig.variadic() && extra_args.is_empty());
372+
assert!(!sig.variadic && extra_args.is_empty());
373373

374374
match sig.inputs().last().unwrap().sty {
375375
ty::TyTuple(ref tupled_arguments) => {
@@ -382,7 +382,7 @@ impl FnType {
382382
}
383383
}
384384
} else {
385-
assert!(sig.variadic() || extra_args.is_empty());
385+
assert!(sig.variadic || extra_args.is_empty());
386386
extra_args
387387
};
388388

@@ -525,7 +525,7 @@ impl FnType {
525525
FnType {
526526
args: args,
527527
ret: ret,
528-
variadic: sig.variadic(),
528+
variadic: sig.variadic,
529529
cconv: cconv
530530
}
531531
}

src/librustc_trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
10771077
let dest_val = adt::MaybeSizedValue::sized(dest); // Can return unsized value
10781078
let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize;
10791079
let mut arg_idx = 0;
1080-
for (i, arg_ty) in sig.inputs().into_iter().enumerate() {
1080+
for (i, arg_ty) in sig.inputs().iter().enumerate() {
10811081
let lldestptr = adt::trans_field_ptr(bcx, sig.output(), dest_val, Disr::from(disr), i);
10821082
let arg = &fcx.fn_ty.args[arg_idx];
10831083
arg_idx += 1;

src/librustc_trans/callee.rs

+9-15
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use type_of;
3838
use Disr;
3939
use rustc::ty::{self, Ty, TypeFoldable};
4040
use rustc::hir;
41+
use std::iter;
4142

4243
use syntax_pos::DUMMY_SP;
4344

@@ -329,13 +330,10 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
329330

330331
// Make a version with the type of by-ref closure.
331332
let ty::ClosureTy { unsafety, abi, mut sig } = tcx.closure_type(def_id, substs);
332-
sig.0 = ty::FnSig::new({
333-
let mut inputs = sig.0.inputs().to_owned();
334-
inputs.insert(0, ref_closure_ty); // sig has no self type as of yet
335-
inputs
336-
},
333+
sig.0 = tcx.mk_fn_sig(
334+
iter::once(ref_closure_ty).chain(sig.0.inputs().iter().cloned()),
337335
sig.0.output(),
338-
sig.0.variadic()
336+
sig.0.variadic
339337
);
340338
let llref_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
341339
unsafety: unsafety,
@@ -349,14 +347,10 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
349347
// Make a version of the closure type with the same arguments, but
350348
// with argument #0 being by value.
351349
assert_eq!(abi, Abi::RustCall);
352-
sig.0 = ty::FnSig::new(
353-
{
354-
let mut inputs = sig.0.inputs().to_owned();
355-
inputs[0] = closure_ty;
356-
inputs
357-
},
350+
sig.0 = tcx.mk_fn_sig(
351+
iter::once(closure_ty).chain(sig.0.inputs().iter().skip(1).cloned()),
358352
sig.0.output(),
359-
sig.0.variadic()
353+
sig.0.variadic
360354
);
361355

362356
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
@@ -507,8 +501,8 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
507501
};
508502
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
509503
let tuple_input_ty = tcx.intern_tup(sig.inputs());
510-
let sig = ty::FnSig::new(
511-
vec![bare_fn_ty_maybe_ref, tuple_input_ty],
504+
let sig = tcx.mk_fn_sig(
505+
[bare_fn_ty_maybe_ref, tuple_input_ty].iter().cloned(),
512506
sig.output(),
513507
false
514508
);

src/librustc_trans/common.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,8 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
418418
let ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
419419
unsafety: hir::Unsafety::Unsafe,
420420
abi: Abi::C,
421-
sig: ty::Binder(ty::FnSig::new(
422-
vec![tcx.mk_mut_ptr(tcx.types.u8)],
421+
sig: ty::Binder(tcx.mk_fn_sig(
422+
iter::once(tcx.mk_mut_ptr(tcx.types.u8)),
423423
tcx.types.never,
424424
false
425425
)),
@@ -1091,10 +1091,10 @@ pub fn ty_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
10911091
ty::ClosureKind::FnOnce => ty,
10921092
};
10931093

1094-
let sig = sig.map_bound(|sig| ty::FnSig::new(
1095-
iter::once(env_ty).chain(sig.inputs().into_iter().cloned()).collect(),
1094+
let sig = sig.map_bound(|sig| tcx.mk_fn_sig(
1095+
iter::once(env_ty).chain(sig.inputs().iter().cloned()),
10961096
sig.output(),
1097-
sig.variadic()
1097+
sig.variadic
10981098
));
10991099
Cow::Owned(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: sig })
11001100
}

src/librustc_trans/debuginfo/type_names.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
125125
output.pop();
126126
}
127127

128-
if sig.variadic() {
128+
if sig.variadic {
129129
if !sig.inputs().is_empty() {
130130
output.push_str(", ...");
131131
} else {

src/librustc_trans/intrinsic.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use rustc::session::Session;
3636
use syntax_pos::{Span, DUMMY_SP};
3737

3838
use std::cmp::Ordering;
39+
use std::iter;
3940

4041
fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option<ValueRef> {
4142
let llvm_name = match name {
@@ -1012,7 +1013,7 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
10121013
trans: &mut for<'b> FnMut(Block<'b, 'tcx>))
10131014
-> ValueRef {
10141015
let ccx = fcx.ccx;
1015-
let sig = ty::FnSig::new(inputs, output, false);
1016+
let sig = ccx.tcx().mk_fn_sig(inputs.into_iter(), output, false);
10161017
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
10171018

10181019
let rust_fn_ty = ccx.tcx().mk_fn_ptr(ccx.tcx().mk_bare_fn(ty::BareFnTy {
@@ -1047,7 +1048,7 @@ fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
10471048
let fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
10481049
unsafety: hir::Unsafety::Unsafe,
10491050
abi: Abi::Rust,
1050-
sig: ty::Binder(ty::FnSig::new(vec![i8p], tcx.mk_nil(), false)),
1051+
sig: ty::Binder(tcx.mk_fn_sig(iter::once(i8p), tcx.mk_nil(), false)),
10511052
}));
10521053
let output = tcx.types.i32;
10531054
let rust_try = gen_fn(fcx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans);

src/librustc_trans/trans_item.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
187187
assert_eq!(dg.ty(), glue::get_drop_glue_type(tcx, dg.ty()));
188188
let t = dg.ty();
189189

190-
let sig = ty::FnSig::new(vec![tcx.mk_mut_ptr(tcx.types.i8)], tcx.mk_nil(), false);
190+
let sig = tcx.mk_fn_sig(iter::once(tcx.mk_mut_ptr(tcx.types.i8)), tcx.mk_nil(), false);
191191

192192
// Create a FnType for fn(*mut i8) and substitute the real type in
193193
// later - that prevents FnType from splitting fat pointers up.
@@ -487,7 +487,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
487487
output.pop();
488488
}
489489

490-
if sig.variadic() {
490+
if sig.variadic {
491491
if !sig.inputs().is_empty() {
492492
output.push_str(", ...");
493493
} else {

0 commit comments

Comments
 (0)