diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 17c335fc9c72f..4854a14f733f5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1542,6 +1542,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + pub fn mk_fn_sig(self, inputs: I, output: I::Item, variadic: bool) + -> , ty::FnSig<'tcx>>>::Output + where I: Iterator, + I::Item: InternIteratorElement, ty::FnSig<'tcx>> + { + inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig { + inputs_and_output: self.intern_type_list(xs), + variadic: variadic + }) + } + pub fn mk_existential_predicates], &'tcx Slice>>>(self, iter: I) -> I::Output { diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 171519b0664d9..76c26d01ac8e2 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -18,8 +18,10 @@ use ty::subst::{Kind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; use std::rc::Rc; +use std::iter; use syntax::abi; use hir as ast; +use rustc_data_structures::accumulate_vec::AccumulateVec; pub type RelateResult<'tcx, T> = Result>; @@ -180,21 +182,30 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { -> RelateResult<'tcx, ty::FnSig<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { - if a.variadic() != b.variadic() { + if a.variadic != b.variadic { return Err(TypeError::VariadicMismatch( - expected_found(relation, &a.variadic(), &b.variadic()))); + expected_found(relation, &a.variadic, &b.variadic))); } if a.inputs().len() != b.inputs().len() { return Err(TypeError::ArgCount); } - let inputs = a.inputs().iter().zip(b.inputs()).map(|(&a, &b)| { - relation.relate_with_variance(ty::Contravariant, &a, &b) - }).collect::, _>>()?; - let output = relation.relate(&a.output(), &b.output())?; - - Ok(ty::FnSig::new(inputs, output, a.variadic())) + let inputs_and_output = a.inputs().iter().cloned() + .zip(b.inputs().iter().cloned()) + .map(|x| (x, false)) + .chain(iter::once(((a.output(), b.output()), true))) + .map(|((a, b), is_output)| { + if is_output { + relation.relate(&a, &b) + } else { + relation.relate_with_variance(ty::Contravariant, &a, &b) + } + }).collect::, _>>()?; + Ok(ty::FnSig { + inputs_and_output: relation.tcx().intern_type_list(&inputs_and_output), + variadic: a.variadic + }) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 9ca30850bcda9..0f0478bc8cdb0 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -232,10 +232,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> { type Lifted = ty::FnSig<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - tcx.lift(self.inputs()).and_then(|inputs| { - tcx.lift(&self.output()).map(|output| { - ty::FnSig::new(inputs, output, self.variadic()) - }) + tcx.lift(&self.inputs_and_output).map(|x| { + ty::FnSig { + inputs_and_output: x, + variadic: self.variadic + } }) } } @@ -585,9 +586,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::FnSig::new(self.inputs().to_owned().fold_with(folder), - self.output().fold_with(folder), - self.variadic()) + let inputs_and_output = self.inputs_and_output.fold_with(folder); + ty::FnSig { + inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output), + variadic: self.variadic, + } } fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { @@ -595,7 +598,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { } fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.inputs().to_owned().visit_with(visitor) || self.output().visit_with(visitor) + self.inputs().iter().any(|i| i.visit_with(visitor)) || + self.output().visit_with(visitor) } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 6c54d558ab789..3b7c46ef7fe17 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -563,40 +563,31 @@ pub struct ClosureTy<'tcx> { /// - `variadic` indicates whether this is a variadic function. (only true for foreign fns) #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub struct FnSig<'tcx> { - inputs: Vec>, - output: Ty<'tcx>, - variadic: bool + pub inputs_and_output: &'tcx Slice>, + pub variadic: bool } impl<'tcx> FnSig<'tcx> { - pub fn new(inputs: Vec>, output: Ty<'tcx>, variadic: bool) -> Self { - FnSig { inputs: inputs, output: output, variadic: variadic } - } - pub fn inputs(&self) -> &[Ty<'tcx>] { - &self.inputs + &self.inputs_and_output[..self.inputs_and_output.len() - 1] } pub fn output(&self) -> Ty<'tcx> { - self.output - } - - pub fn variadic(&self) -> bool { - self.variadic + self.inputs_and_output[self.inputs_and_output.len() - 1] } } pub type PolyFnSig<'tcx> = Binder>; impl<'tcx> PolyFnSig<'tcx> { - pub fn inputs<'a>(&'a self) -> Binder<&[Ty<'tcx>]> { - Binder(self.0.inputs()) + pub fn inputs(&self) -> Binder<&[Ty<'tcx>]> { + Binder(self.skip_binder().inputs()) } pub fn input(&self, index: usize) -> ty::Binder> { - self.map_bound_ref(|fn_sig| fn_sig.inputs[index]) + self.map_bound_ref(|fn_sig| fn_sig.inputs()[index]) } pub fn output(&self) -> ty::Binder> { - self.map_bound_ref(|fn_sig| fn_sig.output.clone()) + self.map_bound_ref(|fn_sig| fn_sig.output().clone()) } pub fn variadic(&self) -> bool { self.skip_binder().variadic @@ -1261,8 +1252,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } // Type accessors for substructures of types - pub fn fn_args(&self) -> ty::Binder>> { - ty::Binder(self.fn_sig().inputs().skip_binder().iter().cloned().collect::>()) + pub fn fn_args(&self) -> ty::Binder<&[Ty<'tcx>]> { + self.fn_sig().inputs() } pub fn fn_ret(&self) -> Binder> { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 3a973fe7bc53f..38b38e5b49764 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -595,7 +595,7 @@ impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> { impl<'tcx> fmt::Display for ty::FnSig<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "fn")?; - fn_sig(f, self.inputs(), self.variadic(), self.output()) + fn_sig(f, self.inputs(), self.variadic, self.output()) } } @@ -625,7 +625,7 @@ impl fmt::Debug for ty::RegionVid { impl<'tcx> fmt::Debug for ty::FnSig<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic(), self.output()) + write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic, self.output()) } } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 464e15faeaf75..b7cebe3107309 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -265,15 +265,10 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } pub fn t_fn(&self, input_tys: &[Ty<'tcx>], output_ty: Ty<'tcx>) -> Ty<'tcx> { - let input_args = input_tys.iter().cloned().collect(); self.infcx.tcx.mk_fn_ptr(self.infcx.tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: Abi::Rust, - sig: ty::Binder(ty::FnSig { - inputs: input_args, - output: output_ty, - variadic: false, - }), + sig: ty::Binder(self.infcx.tcx.mk_fn_sig(input_tys.iter().cloned(), output_ty, false)), })) } diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index f65b4e55d4766..4c86331a52576 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -529,7 +529,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { { debug!("check_call_inputs({:?}, {:?})", sig, args); if args.len() < sig.inputs().len() || - (args.len() > sig.inputs().len() && !sig.variadic()) { + (args.len() > sig.inputs().len() && !sig.variadic) { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() { diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index e780b8685e1ef..0ac853e99eecd 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -369,7 +369,7 @@ impl FnType { let mut inputs = sig.inputs(); let extra_args = if abi == RustCall { - assert!(!sig.variadic() && extra_args.is_empty()); + assert!(!sig.variadic && extra_args.is_empty()); match sig.inputs().last().unwrap().sty { ty::TyTuple(ref tupled_arguments) => { @@ -382,7 +382,7 @@ impl FnType { } } } else { - assert!(sig.variadic() || extra_args.is_empty()); + assert!(sig.variadic || extra_args.is_empty()); extra_args }; @@ -525,7 +525,7 @@ impl FnType { FnType { args: args, ret: ret, - variadic: sig.variadic(), + variadic: sig.variadic, cconv: cconv } } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 8cc47dc81684a..867e4dce19aca 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1077,7 +1077,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let dest_val = adt::MaybeSizedValue::sized(dest); // Can return unsized value let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize; let mut arg_idx = 0; - for (i, arg_ty) in sig.inputs().into_iter().enumerate() { + for (i, arg_ty) in sig.inputs().iter().enumerate() { let lldestptr = adt::trans_field_ptr(bcx, sig.output(), dest_val, Disr::from(disr), i); let arg = &fcx.fn_ty.args[arg_idx]; arg_idx += 1; diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 0d1fd4d69b178..7fb57dc19fcf9 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -38,6 +38,7 @@ use type_of; use Disr; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::hir; +use std::iter; use syntax_pos::DUMMY_SP; @@ -329,13 +330,10 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( // Make a version with the type of by-ref closure. let ty::ClosureTy { unsafety, abi, mut sig } = tcx.closure_type(def_id, substs); - sig.0 = ty::FnSig::new({ - let mut inputs = sig.0.inputs().to_owned(); - inputs.insert(0, ref_closure_ty); // sig has no self type as of yet - inputs - }, + sig.0 = tcx.mk_fn_sig( + iter::once(ref_closure_ty).chain(sig.0.inputs().iter().cloned()), sig.0.output(), - sig.0.variadic() + sig.0.variadic ); let llref_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety, @@ -349,14 +347,10 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( // Make a version of the closure type with the same arguments, but // with argument #0 being by value. assert_eq!(abi, Abi::RustCall); - sig.0 = ty::FnSig::new( - { - let mut inputs = sig.0.inputs().to_owned(); - inputs[0] = closure_ty; - inputs - }, + sig.0 = tcx.mk_fn_sig( + iter::once(closure_ty).chain(sig.0.inputs().iter().skip(1).cloned()), sig.0.output(), - sig.0.variadic() + sig.0.variadic ); let sig = tcx.erase_late_bound_regions_and_normalize(&sig); @@ -507,8 +501,8 @@ fn trans_fn_pointer_shim<'a, 'tcx>( }; let sig = tcx.erase_late_bound_regions_and_normalize(sig); let tuple_input_ty = tcx.intern_tup(sig.inputs()); - let sig = ty::FnSig::new( - vec![bare_fn_ty_maybe_ref, tuple_input_ty], + let sig = tcx.mk_fn_sig( + [bare_fn_ty_maybe_ref, tuple_input_ty].iter().cloned(), sig.output(), false ); diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 2682c37095a67..b1d61cea39cec 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -418,8 +418,8 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { let ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Unsafe, abi: Abi::C, - sig: ty::Binder(ty::FnSig::new( - vec![tcx.mk_mut_ptr(tcx.types.u8)], + sig: ty::Binder(tcx.mk_fn_sig( + iter::once(tcx.mk_mut_ptr(tcx.types.u8)), tcx.types.never, false )), @@ -1091,10 +1091,10 @@ pub fn ty_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::ClosureKind::FnOnce => ty, }; - let sig = sig.map_bound(|sig| ty::FnSig::new( - iter::once(env_ty).chain(sig.inputs().into_iter().cloned()).collect(), + let sig = sig.map_bound(|sig| tcx.mk_fn_sig( + iter::once(env_ty).chain(sig.inputs().iter().cloned()), sig.output(), - sig.variadic() + sig.variadic )); Cow::Owned(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: sig }) } diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 5eb632f63abcb..788ce32937d84 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -125,7 +125,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.pop(); } - if sig.variadic() { + if sig.variadic { if !sig.inputs().is_empty() { output.push_str(", ..."); } else { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index cf1dddf0f49c2..577ffbad1348b 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -36,6 +36,7 @@ use rustc::session::Session; use syntax_pos::{Span, DUMMY_SP}; use std::cmp::Ordering; +use std::iter; fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option { let llvm_name = match name { @@ -1012,7 +1013,7 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, trans: &mut for<'b> FnMut(Block<'b, 'tcx>)) -> ValueRef { let ccx = fcx.ccx; - let sig = ty::FnSig::new(inputs, output, false); + let sig = ccx.tcx().mk_fn_sig(inputs.into_iter(), output, false); let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]); 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>, let fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Unsafe, abi: Abi::Rust, - sig: ty::Binder(ty::FnSig::new(vec![i8p], tcx.mk_nil(), false)), + sig: ty::Binder(tcx.mk_fn_sig(iter::once(i8p), tcx.mk_nil(), false)), })); let output = tcx.types.i32; let rust_try = gen_fn(fcx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 3ae97d0cfcf3c..214eaeb817f30 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -187,7 +187,7 @@ impl<'a, 'tcx> TransItem<'tcx> { assert_eq!(dg.ty(), glue::get_drop_glue_type(tcx, dg.ty())); let t = dg.ty(); - let sig = ty::FnSig::new(vec![tcx.mk_mut_ptr(tcx.types.i8)], tcx.mk_nil(), false); + let sig = tcx.mk_fn_sig(iter::once(tcx.mk_mut_ptr(tcx.types.i8)), tcx.mk_nil(), false); // Create a FnType for fn(*mut i8) and substitute the real type in // later - that prevents FnType from splitting fat pointers up. @@ -487,7 +487,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.pop(); } - if sig.variadic() { + if sig.variadic { if !sig.inputs().is_empty() { output.push_str(", ..."); } else { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 1fd0b7944411c..d458c7c009e2e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1796,15 +1796,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::DefaultReturn(..) => self.tcx().mk_nil(), }; - let input_tys = self_ty.into_iter().chain(arg_tys).collect(); - - debug!("ty_of_method_or_bare_fn: input_tys={:?}", input_tys); debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty); self.tcx().mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, - sig: ty::Binder(ty::FnSig::new(input_tys, output_ty, decl.variadic)), + sig: ty::Binder(self.tcx().mk_fn_sig( + self_ty.into_iter().chain(arg_tys), + output_ty, + decl.variadic + )), }) } @@ -1846,7 +1847,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // that function type let rb = rscope::BindingRscope::new(); - let input_tys: Vec<_> = decl.inputs.iter().enumerate().map(|(i, a)| { + let input_tys = decl.inputs.iter().enumerate().map(|(i, a)| { let expected_arg_ty = expected_sig.as_ref().and_then(|e| { // no guarantee that the correct number of expected args // were supplied @@ -1857,9 +1858,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } }); self.ty_of_arg(&rb, a, expected_arg_ty) - }).collect(); + }); - let expected_ret_ty = expected_sig.map(|e| e.output()); + let expected_ret_ty = expected_sig.as_ref().map(|e| e.output()); let is_infer = match decl.output { hir::Return(ref output) if output.node == hir::TyInfer => true, @@ -1876,13 +1877,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::DefaultReturn(..) => bug!(), }; - debug!("ty_of_closure: input_tys={:?}", input_tys); debug!("ty_of_closure: output_ty={:?}", output_ty); ty::ClosureTy { unsafety: unsafety, abi: abi, - sig: ty::Binder(ty::FnSig::new(input_tys, output_ty, decl.variadic)), + sig: ty::Binder(self.tcx().mk_fn_sig(input_tys, output_ty, decl.variadic)), } } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index a49a15b2aa900..4fba29def226c 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -237,8 +237,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // This is the "default" function signature, used in case of error. // In that case, we check each argument against "error" in order to // set up all the node type bindings. - error_fn_sig = ty::Binder(ty::FnSig::new( - self.err_args(arg_exprs.len()), + error_fn_sig = ty::Binder(self.tcx.mk_fn_sig( + self.err_args(arg_exprs.len()).into_iter(), self.tcx.types.err, false, )); @@ -267,7 +267,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn_sig.inputs(), &expected_arg_tys[..], arg_exprs, - fn_sig.variadic(), + fn_sig.variadic, TupleArgumentsFlag::DontTupleArguments, def_span); @@ -294,7 +294,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn_sig.inputs(), &expected_arg_tys, arg_exprs, - fn_sig.variadic(), + fn_sig.variadic, TupleArgumentsFlag::TupleArguments, None); @@ -366,7 +366,7 @@ impl<'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> for CallResolution<'gcx, 'tc debug!("attempt_resolution: method_callee={:?}", method_callee); for (method_arg_ty, self_arg_ty) in - method_sig.inputs().into_iter().skip(1).zip(self.fn_sig.inputs()) { + method_sig.inputs().iter().skip(1).zip(self.fn_sig.inputs()) { fcx.demand_eqtype(self.call_expr.span, &self_arg_ty, &method_arg_ty); } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index d0bc3f691873a..142a8b971110d 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -15,6 +15,7 @@ use super::{check_fn, Expectation, FnCtxt}; use astconv::AstConv; use rustc::ty::{self, ToPolyTraitRef, Ty}; use std::cmp; +use std::iter; use syntax::abi::Abi; use rustc::hir; @@ -86,7 +87,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Tuple up the arguments and insert the resulting function type into // the `closures` table. - fn_ty.sig.0 = ty::FnSig::new(vec![self.tcx.intern_tup(fn_ty.sig.skip_binder().inputs())], + fn_ty.sig.0 = self.tcx.mk_fn_sig( + iter::once(self.tcx.intern_tup(fn_ty.sig.skip_binder().inputs())), fn_ty.sig.skip_binder().output(), fn_ty.sig.variadic() ); @@ -215,19 +217,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { arg_param_ty); let input_tys = match arg_param_ty.sty { - ty::TyTuple(tys) => tys.to_vec(), + ty::TyTuple(tys) => tys.into_iter(), _ => { return None; } }; - debug!("deduce_sig_from_projection: input_tys {:?}", input_tys); let ret_param_ty = projection.0.ty; let ret_param_ty = self.resolve_type_vars_if_possible(&ret_param_ty); - debug!("deduce_sig_from_projection: ret_param_ty {:?}", - ret_param_ty); + debug!("deduce_sig_from_projection: ret_param_ty {:?}", ret_param_ty); - let fn_sig = ty::FnSig::new(input_tys, ret_param_ty, false); + let fn_sig = self.tcx.mk_fn_sig(input_tys.cloned(), ret_param_ty, false); debug!("deduce_sig_from_projection: fn_sig {:?}", fn_sig); Some(fn_sig) diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 23915880167fe..183a2a48ff523 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -14,7 +14,6 @@ use intrinsics; use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::ty::subst::Substs; -use rustc::ty::FnSig; use rustc::ty::{self, Ty}; use rustc::util::nodemap::FxHashMap; use {CrateCtxt, require_same_types}; @@ -26,6 +25,8 @@ use syntax_pos::Span; use rustc::hir; +use std::iter; + fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::ForeignItem, n_tps: usize, @@ -42,7 +43,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let fty = tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Unsafe, abi: abi, - sig: ty::Binder(FnSig::new(inputs, output, false)), + sig: ty::Binder(tcx.mk_fn_sig(inputs.into_iter(), output, false)), })); let i_n_tps = tcx.item_generics(def_id).types.len(); if i_n_tps != n_tps { @@ -295,7 +296,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { let fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: Abi::Rust, - sig: ty::Binder(FnSig::new(vec![mut_u8], tcx.mk_nil(), false)), + sig: ty::Binder(tcx.mk_fn_sig(iter::once(mut_u8), tcx.mk_nil(), false)), }); (0, vec![tcx.mk_fn_ptr(fn_ty), mut_u8, mut_u8], tcx.types.i32) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 058bb9254d82b..1b35081d5241c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -790,7 +790,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, fcx.require_type_is_sized(fcx.ret_ty, decl.output.span(), traits::ReturnType); fcx.ret_ty = fcx.instantiate_anon_types(&fcx.ret_ty); - fn_sig = ty::FnSig::new(fn_sig.inputs().to_owned(), fcx.ret_ty, fn_sig.variadic()); + fn_sig = fcx.tcx.mk_fn_sig(fn_sig.inputs().iter().cloned(), &fcx.ret_ty, fn_sig.variadic); { let mut visit = GatherLocalsVisitor { fcx: &fcx, }; @@ -2473,11 +2473,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match method_fn_ty.sty { ty::TyFnDef(def_id, .., ref fty) => { // HACK(eddyb) ignore self in the definition (see above). - let expected_arg_tys = self.expected_types_for_fn_args(sp, expected, - fty.sig.0.output(), - &fty.sig.0.inputs()[1..]); + let expected_arg_tys = self.expected_types_for_fn_args( + sp, + expected, + fty.sig.0.output(), + &fty.sig.0.inputs()[1..] + ); self.check_argument_types(sp, &fty.sig.0.inputs()[1..], &expected_arg_tys[..], - args_no_rcvr, fty.sig.0.variadic(), tuple_arguments, + args_no_rcvr, fty.sig.0.variadic, tuple_arguments, self.tcx.map.span_if_local(def_id)); fty.sig.0.output() } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a965753a9c143..fba77d171797e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -920,17 +920,12 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let ctor_ty = match variant.ctor_kind { CtorKind::Fictive | CtorKind::Const => ty, CtorKind::Fn => { - let inputs: Vec<_> = - variant.fields - .iter() - .map(|field| tcx.item_type(field.did)) - .collect(); - let substs = mk_item_substs(&ccx.icx(&predicates), - ccx.tcx.map.span(ctor_id), def_id); + let inputs = variant.fields.iter().map(|field| tcx.item_type(field.did)); + let substs = mk_item_substs(&ccx.icx(&predicates), ccx.tcx.map.span(ctor_id), def_id); tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: abi::Abi::Rust, - sig: ty::Binder(ty::FnSig::new(inputs, ty, false)) + sig: ty::Binder(ccx.tcx.mk_fn_sig(inputs, ty, false)) })) } }; @@ -2081,7 +2076,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( ccx.tcx.mk_fn_def(def_id, substs, ccx.tcx.mk_bare_fn(ty::BareFnTy { abi: abi, unsafety: hir::Unsafety::Unsafe, - sig: ty::Binder(ty::FnSig::new(input_tys, output, decl.variadic)), + sig: ty::Binder(ccx.tcx.mk_fn_sig(input_tys.into_iter(), output, decl.variadic)), })) } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 0017676dae426..50d4c3cd0c994 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -116,6 +116,7 @@ use syntax::ast; use syntax::abi::Abi; use syntax_pos::Span; +use std::iter; use std::cell::RefCell; use util::nodemap::NodeMap; @@ -222,7 +223,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt, tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: Abi::Rust, - sig: ty::Binder(ty::FnSig::new(Vec::new(), tcx.mk_nil(), false)) + sig: ty::Binder(tcx.mk_fn_sig(iter::empty(), tcx.mk_nil(), false)) })); require_same_types( @@ -270,11 +271,11 @@ fn check_start_fn_ty(ccx: &CrateCtxt, tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: Abi::Rust, - sig: ty::Binder(ty::FnSig::new( - vec![ + sig: ty::Binder(tcx.mk_fn_sig( + [ tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8)) - ], + ].iter().cloned(), tcx.types.isize, false, )),