diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 6896c69d7db92..2357549c82e08 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -178,8 +178,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> { let typ = self.infcx.tcx.tables().node_id_to_type(expr.id); match typ.sty { ty::TyFnDef(.., ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => { - let from = bare_fn_ty.sig.0.inputs[0]; - let to = bare_fn_ty.sig.0.output; + let from = bare_fn_ty.sig.skip_binder().inputs()[0]; + let to = bare_fn_ty.sig.skip_binder().output(); self.check_transmute(expr.span, from, to, expr.id); } _ => { diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ceee6c236e4e3..0d5c9b98941dc 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -241,12 +241,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // The `Self` type is erased, so it should not appear in list of // arguments or return type apart from the receiver. let ref sig = self.item_type(method.def_id).fn_sig(); - for &input_ty in &sig.0.inputs[1..] { + for input_ty in &sig.skip_binder().inputs()[1..] { if self.contains_illegal_self_type_reference(trait_def_id, input_ty) { return Some(MethodViolationCode::ReferencesSelf); } } - if self.contains_illegal_self_type_reference(trait_def_id, sig.0.output) { + if self.contains_illegal_self_type_reference(trait_def_id, sig.output().skip_binder()) { return Some(MethodViolationCode::ReferencesSelf); } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index c54c0bf74ef7a..23cfc2517590c 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1368,21 +1368,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyFnDef(.., &ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: Abi::Rust, - sig: ty::Binder(ty::FnSig { - inputs: _, - output: _, - variadic: false - }) + ref sig, }) | ty::TyFnPtr(&ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: Abi::Rust, - sig: ty::Binder(ty::FnSig { - inputs: _, - output: _, - variadic: false - }) - }) => { + ref sig + }) if !sig.variadic() => { candidates.vec.push(FnPointerCandidate); } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 321936fe54be1..cebd8bf87d736 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -487,14 +487,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)> { let arguments_tuple = match tuple_arguments { - TupleArgumentsFlag::No => sig.0.inputs[0], - TupleArgumentsFlag::Yes => self.intern_tup(&sig.0.inputs[..]), + TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], + TupleArgumentsFlag::Yes => + self.intern_tup(sig.skip_binder().inputs()), }; let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, substs: self.mk_substs_trait(self_ty, &[arguments_tuple]), }; - ty::Binder((trait_ref, sig.0.output)) + ty::Binder((trait_ref, sig.skip_binder().output())) } } 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/fast_reject.rs b/src/librustc/ty/fast_reject.rs index ade6cad6866df..7b4d76ad4973e 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -81,7 +81,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, Some(TupleSimplifiedType(tys.len())) } ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => { - Some(FunctionSimplifiedType(f.sig.0.inputs.len())) + Some(FunctionSimplifiedType(f.sig.skip_binder().inputs().len())) } ty::TyProjection(_) | ty::TyParam(_) => { if can_simplify_params { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 2bcbccb7d0505..a06d3ed6cf4fb 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -180,8 +180,8 @@ impl FlagComputation { fn add_fn_sig(&mut self, fn_sig: &ty::PolyFnSig) { let mut computation = FlagComputation::new(); - computation.add_tys(&fn_sig.0.inputs); - computation.add_ty(fn_sig.0.output); + computation.add_tys(fn_sig.skip_binder().inputs()); + computation.add_ty(fn_sig.skip_binder().output()); self.add_bound_computation(&computation); } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 8cb1483107ff1..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>; @@ -185,32 +187,28 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { expected_found(relation, &a.variadic, &b.variadic))); } - let inputs = relate_arg_vecs(relation, - &a.inputs, - &b.inputs)?; - let output = relation.relate(&a.output, &b.output)?; + if a.inputs().len() != b.inputs().len() { + return Err(TypeError::ArgCount); + } - Ok(ty::FnSig {inputs: inputs, - output: output, - variadic: 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 + }) } } -fn relate_arg_vecs<'a, 'gcx, 'tcx, R>(relation: &mut R, - a_args: &[Ty<'tcx>], - b_args: &[Ty<'tcx>]) - -> RelateResult<'tcx, Vec>> - where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a -{ - if a_args.len() != b_args.len() { - return Err(TypeError::ArgCount); - } - - a_args.iter().zip(b_args) - .map(|(a, b)| relation.relate_with_variance(ty::Contravariant, a, b)) - .collect() -} - impl<'tcx> Relate<'tcx> for ast::Unsafety { fn relate<'a, 'gcx, R>(relation: &mut R, a: &ast::Unsafety, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 88de3575274cc..0f0478bc8cdb0 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -232,14 +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 { - inputs: inputs, - output: output, - variadic: self.variadic - } - }) + tcx.lift(&self.inputs_and_output).map(|x| { + ty::FnSig { + inputs_and_output: x, + variadic: self.variadic + } }) } } @@ -589,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 { inputs: self.inputs.fold_with(folder), - output: self.output.fold_with(folder), - variadic: 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 { @@ -599,7 +598,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { } fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.inputs.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 59f774b954cf9..3b7c46ef7fe17 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -563,22 +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> { - pub inputs: Vec>, - pub output: Ty<'tcx>, + pub inputs_and_output: &'tcx Slice>, pub variadic: bool } +impl<'tcx> FnSig<'tcx> { + pub fn inputs(&self) -> &[Ty<'tcx>] { + &self.inputs_and_output[..self.inputs_and_output.len() - 1] + } + + pub fn output(&self) -> Ty<'tcx> { + self.inputs_and_output[self.inputs_and_output.len() - 1] + } +} + pub type PolyFnSig<'tcx> = Binder>; impl<'tcx> PolyFnSig<'tcx> { - pub fn inputs(&self) -> ty::Binder>> { - self.map_bound_ref(|fn_sig| fn_sig.inputs.clone()) + 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 @@ -1243,7 +1252,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } // Type accessors for substructures of types - pub fn fn_args(&self) -> ty::Binder>> { + pub fn fn_args(&self) -> ty::Binder<&[Ty<'tcx>]> { self.fn_sig().inputs() } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 6bb9d67db6f65..e6db35cc3f544 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -530,7 +530,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc self.hash(f.unsafety); self.hash(f.abi); self.hash(f.sig.variadic()); - self.hash(f.sig.inputs().skip_binder().len()); + self.hash(f.sig.skip_binder().inputs().len()); } TyDynamic(ref data, ..) => { if let Some(p) = data.principal() { diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 0848dcd2c8d21..3fa7a803141d1 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -126,6 +126,6 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { } fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: &ty::PolyFnSig<'tcx>) { - stack.push(sig.0.output); - stack.extend(sig.0.inputs.iter().cloned().rev()); + stack.push(sig.skip_binder().output()); + stack.extend(sig.skip_binder().inputs().iter().cloned().rev()); } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index b4c87e0ce426e..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_lint/builtin.rs b/src/librustc_lint/builtin.rs index f14fa7d4fdc23..ee6af643154fa 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1084,8 +1084,8 @@ impl LateLintPass for MutableTransmutes { let typ = cx.tcx.tables().node_id_to_type(expr.id); match typ.sty { ty::TyFnDef(.., ref bare_fn) if bare_fn.abi == RustIntrinsic => { - let from = bare_fn.sig.0.inputs[0]; - let to = bare_fn.sig.0.output; + let from = bare_fn.sig.skip_binder().inputs()[0]; + let to = bare_fn.sig.skip_binder().output(); return Some((&from.sty, &to.sty)); } _ => (), diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index bba31c8237d18..6475166192a25 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -603,8 +603,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } let sig = cx.erase_late_bound_regions(&bare_fn.sig); - if !sig.output.is_nil() { - let r = self.check_type_for_ffi(cache, sig.output); + if !sig.output().is_nil() { + let r = self.check_type_for_ffi(cache, sig.output()); match r { FfiSafe => {} _ => { @@ -612,7 +612,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } } } - for arg in sig.inputs { + for arg in sig.inputs() { let r = self.check_type_for_ffi(cache, arg); match r { FfiSafe => {} @@ -678,12 +678,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let sig = self.cx.tcx.item_type(def_id).fn_sig(); let sig = self.cx.tcx.erase_late_bound_regions(&sig); - for (&input_ty, input_hir) in sig.inputs.iter().zip(&decl.inputs) { - self.check_type_for_ffi_and_report_errors(input_hir.ty.span, &input_ty); + for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) { + self.check_type_for_ffi_and_report_errors(input_hir.ty.span, input_ty); } if let hir::Return(ref ret_hir) = decl.output { - let ret_ty = sig.output; + let ret_ty = sig.output(); if !ret_ty.is_nil() { self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty); } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 5a77de0807028..ffd9525933b4e 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -208,7 +208,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let diverges = match ty.sty { ty::TyFnDef(_, _, ref f) | ty::TyFnPtr(ref f) => { // FIXME(canndrew): This is_never should probably be an is_uninhabited - f.sig.0.output.is_never() + f.sig.skip_binder().output().is_never() } _ => false }; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index e850f6c4b045c..bd4724159b4cb 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -247,10 +247,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, span_bug!(expr.span, "method call has late-bound regions") }); - assert_eq!(sig.inputs.len(), 2); + assert_eq!(sig.inputs().len(), 2); let tupled_args = Expr { - ty: sig.inputs[1], + ty: sig.inputs()[1], temp_lifetime: temp_lifetime, span: expr.span, kind: ExprKind::Tuple { diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 88d02d7d004c9..e2a516edbc835 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -238,14 +238,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { .iter() .enumerate() .map(|(index, arg)| { - (fn_sig.inputs[index], Some(&*arg.pat)) + (fn_sig.inputs()[index], Some(&*arg.pat)) }); let body = self.tcx.map.expr(body_id); let arguments = implicit_argument.into_iter().chain(explicit_arguments); self.cx(MirSource::Fn(id)).build(|cx| { - build::construct_fn(cx, id, arguments, abi, fn_sig.output, body) + build::construct_fn(cx, id, arguments, abi, fn_sig.output(), body) }); intravisit::walk_fn(self, fk, decl, body_id, span, id); diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 0ceed274b6da6..4c86331a52576 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -506,15 +506,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { match *destination { Some((ref dest, _)) => { let dest_ty = dest.ty(mir, tcx).to_ty(tcx); - if let Err(terr) = self.sub_types(sig.output, dest_ty) { + if let Err(terr) = self.sub_types(sig.output(), dest_ty) { span_mirbug!(self, term, "call dest mismatch ({:?} <- {:?}): {:?}", - dest_ty, sig.output, terr); + dest_ty, sig.output(), terr); } }, None => { // FIXME(canndrew): This is_never should probably be an is_uninhabited - if !sig.output.is_never() { + if !sig.output().is_never() { span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); } }, @@ -528,11 +528,11 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { args: &[Operand<'tcx>]) { debug!("check_call_inputs({:?}, {:?})", sig, args); - if args.len() < sig.inputs.len() || - (args.len() > sig.inputs.len() && !sig.variadic) { + if args.len() < sig.inputs().len() || + (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() { + for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() { let op_arg_ty = op_arg.ty(mir, self.tcx()); if let Err(terr) = self.sub_types(op_arg_ty, fn_arg) { span_mirbug!(self, term, "bad arg #{:?} ({:?} <- {:?}): {:?}", @@ -562,12 +562,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // box_free takes a Box as a pointer. Allow for that. - if sig.inputs.len() != 1 { + if sig.inputs().len() != 1 { span_mirbug!(self, term, "box_free should take 1 argument"); return; } - let pointee_ty = match sig.inputs[0].sty { + let pointee_ty = match sig.inputs()[0].sty { ty::TyRawPtr(mt) => mt.ty, _ => { span_mirbug!(self, term, "box_free should take a raw ptr"); diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 07f53466b4975..0ac853e99eecd 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -367,13 +367,13 @@ impl FnType { Cdecl => llvm::CCallConv, }; - let mut inputs = &sig.inputs[..]; + let mut inputs = sig.inputs(); let extra_args = if abi == RustCall { assert!(!sig.variadic && extra_args.is_empty()); - match inputs[inputs.len() - 1].sty { + match sig.inputs().last().unwrap().sty { ty::TyTuple(ref tupled_arguments) => { - inputs = &inputs[..inputs.len() - 1]; + inputs = &sig.inputs()[0..sig.inputs().len() - 1]; &tupled_arguments[..] } _ => { @@ -428,7 +428,7 @@ impl FnType { } }; - let ret_ty = sig.output; + let ret_ty = sig.output(); let mut ret = arg_of(ret_ty, true); if !type_is_fat_ptr(ccx.tcx(), ret_ty) { @@ -569,7 +569,7 @@ impl FnType { }; // Fat pointers are returned by-value. if !self.ret.is_ignore() { - if !type_is_fat_ptr(ccx.tcx(), sig.output) { + if !type_is_fat_ptr(ccx.tcx(), sig.output()) { fixup(&mut self.ret); } } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index a31b61e42c440..867e4dce19aca 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1077,8 +1077,8 @@ 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() { - let lldestptr = adt::trans_field_ptr(bcx, sig.output, dest_val, Disr::from(disr), i); + 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; let b = &bcx.build(); @@ -1091,7 +1091,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg.store_fn_arg(b, &mut llarg_idx, lldestptr); } } - adt::trans_set_discr(bcx, sig.output, dest, disr); + adt::trans_set_discr(bcx, sig.output(), dest, disr); } fcx.finish(bcx, DebugLoc::None); diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index df56e27128c7e..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,7 +330,11 @@ 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.inputs.insert(0, ref_closure_ty); // sig has no self type as of yet + sig.0 = tcx.mk_fn_sig( + iter::once(ref_closure_ty).chain(sig.0.inputs().iter().cloned()), + sig.0.output(), + sig.0.variadic + ); let llref_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, @@ -342,7 +347,11 @@ 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.inputs[0] = closure_ty; + sig.0 = tcx.mk_fn_sig( + iter::once(closure_ty).chain(sig.0.inputs().iter().skip(1).cloned()), + sig.0.output(), + sig.0.variadic + ); let sig = tcx.erase_late_bound_regions_and_normalize(&sig); let fn_ty = FnType::new(ccx, abi, &sig, &[]); @@ -491,13 +500,12 @@ 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 { - inputs: vec![bare_fn_ty_maybe_ref, - tuple_input_ty], - output: sig.output, - variadic: false - }; + let tuple_input_ty = tcx.intern_tup(sig.inputs()); + let sig = tcx.mk_fn_sig( + [bare_fn_ty_maybe_ref, tuple_input_ty].iter().cloned(), + sig.output(), + false + ); let fn_ty = FnType::new(ccx, Abi::RustCall, &sig, &[]); let tuple_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 29925d964da25..b1d61cea39cec 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -418,11 +418,11 @@ 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 { - inputs: vec![tcx.mk_mut_ptr(tcx.types.u8)], - output: tcx.types.never, - variadic: false - }), + sig: ty::Binder(tcx.mk_fn_sig( + iter::once(tcx.mk_mut_ptr(tcx.types.u8)), + tcx.types.never, + false + )), })); let unwresume = ccx.eh_unwind_resume(); @@ -1091,10 +1091,11 @@ pub fn ty_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::ClosureKind::FnOnce => ty, }; - let sig = sig.map_bound(|sig| ty::FnSig { - inputs: iter::once(env_ty).chain(sig.inputs).collect(), - ..sig - }); + let sig = sig.map_bound(|sig| tcx.mk_fn_sig( + iter::once(env_ty).chain(sig.inputs().iter().cloned()), + sig.output(), + sig.variadic + )); Cow::Owned(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: sig }) } _ => bug!("unexpected type {:?} to ty_fn_sig", ty) diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index ca76211dc4c95..cda9fa46f1754 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -390,16 +390,16 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, { let signature = cx.tcx().erase_late_bound_regions(signature); - let mut signature_metadata: Vec = Vec::with_capacity(signature.inputs.len() + 1); + let mut signature_metadata: Vec = Vec::with_capacity(signature.inputs().len() + 1); // return type - signature_metadata.push(match signature.output.sty { + signature_metadata.push(match signature.output().sty { ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), - _ => type_metadata(cx, signature.output, span) + _ => type_metadata(cx, signature.output(), span) }); // regular arguments - for &argument_type in &signature.inputs { + for &argument_type in signature.inputs() { signature_metadata.push(type_metadata(cx, argument_type, span)); } diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index e023e654d51ad..aab70ab252a7f 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -308,18 +308,18 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return create_DIArray(DIB(cx), &[]); } - let mut signature = Vec::with_capacity(sig.inputs.len() + 1); + let mut signature = Vec::with_capacity(sig.inputs().len() + 1); // Return type -- llvm::DIBuilder wants this at index 0 - signature.push(match sig.output.sty { + signature.push(match sig.output().sty { ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), - _ => type_metadata(cx, sig.output, syntax_pos::DUMMY_SP) + _ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP) }); let inputs = if abi == Abi::RustCall { - &sig.inputs[..sig.inputs.len()-1] + &sig.inputs()[..sig.inputs().len() - 1] } else { - &sig.inputs[..] + sig.inputs() }; // Arguments types @@ -327,8 +327,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)); } - if abi == Abi::RustCall && !sig.inputs.is_empty() { - if let ty::TyTuple(args) = sig.inputs[sig.inputs.len() - 1].sty { + if abi == Abi::RustCall && !sig.inputs().is_empty() { + if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty { for &argument_type in args { signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)); } diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 80e6bd7aa2984..788ce32937d84 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -116,8 +116,8 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push_str("fn("); let sig = cx.tcx().erase_late_bound_regions_and_normalize(sig); - if !sig.inputs.is_empty() { - for ¶meter_type in &sig.inputs { + if !sig.inputs().is_empty() { + for ¶meter_type in sig.inputs() { push_debuginfo_type_name(cx, parameter_type, true, output); output.push_str(", "); } @@ -126,7 +126,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } if sig.variadic { - if !sig.inputs.is_empty() { + if !sig.inputs().is_empty() { output.push_str(", ..."); } else { output.push_str("..."); @@ -135,9 +135,9 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push(')'); - if !sig.output.is_nil() { + if !sig.output().is_nil() { output.push_str(" -> "); - push_debuginfo_type_name(cx, sig.output, true, output); + push_debuginfo_type_name(cx, sig.output(), true, output); } }, ty::TyClosure(..) => { diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index eef3b9b11474b..9bf023fc18936 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -124,7 +124,7 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx)); // FIXME(canndrew): This is_never should really be an is_uninhabited - if sig.output.is_never() { + if sig.output().is_never() { llvm::Attribute::NoReturn.apply_llfn(Function, llfn); } diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 016a76a72531b..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 { @@ -105,8 +106,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, }; let sig = tcx.erase_late_bound_regions_and_normalize(&fty.sig); - let arg_tys = sig.inputs; - let ret_ty = sig.output; + let arg_tys = sig.inputs(); + let ret_ty = sig.output(); let name = &*tcx.item_name(def_id).as_str(); let span = match call_debug_location { @@ -674,7 +675,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // again to find them and extract the arguments intr.inputs.iter() .zip(llargs) - .zip(&arg_tys) + .zip(arg_tys) .flat_map(|((t, llarg), ty)| modify_as_needed(bcx, t, ty, *llarg)) .collect() }; @@ -1012,11 +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 { - inputs: inputs, - output: output, - variadic: 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 { @@ -1051,11 +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 { - inputs: vec![i8p], - output: tcx.mk_nil(), - variadic: 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); @@ -1108,7 +1101,7 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a> let tcx = bcx.tcx(); let sig = tcx.erase_late_bound_regions_and_normalize(callee_ty.fn_sig()); - let arg_tys = sig.inputs; + let arg_tys = sig.inputs(); // every intrinsic takes a SIMD vector as its first argument require_simd!(arg_tys[0], "input"); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 29e6f6af416bc..76f5f32b5dcff 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -453,7 +453,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { return; } - let extra_args = &args[sig.inputs.len()..]; + let extra_args = &args[sig.inputs().len()..]; let extra_args = extra_args.iter().map(|op_arg| { let op_ty = op_arg.ty(&self.mir, bcx.tcx()); bcx.monomorphize(&op_ty) @@ -546,7 +546,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { // Make a fake operand for store_return let op = OperandRef { val: Ref(dst), - ty: sig.output, + ty: sig.output(), }; self.store_return(&bcx, ret_dest, fn_ty.ret, op); } @@ -584,7 +584,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { debug_loc.apply_to_bcx(ret_bcx); let op = OperandRef { val: Immediate(invokeret), - ty: sig.output, + ty: sig.output(), }; self.store_return(&ret_bcx, ret_dest, fn_ty.ret, op); }); @@ -595,7 +595,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { if let Some((_, target)) = *destination { let op = OperandRef { val: Immediate(llret), - ty: sig.output, + ty: sig.output(), }; self.store_return(&bcx, ret_dest, fn_ty.ret, op); funclet_br(self, bcx, target); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 322c5eb6e182a..214eaeb817f30 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -187,11 +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 { - inputs: vec![tcx.mk_mut_ptr(tcx.types.i8)], - output: tcx.mk_nil(), - variadic: 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. @@ -480,14 +476,10 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push_str("fn("); - let ty::FnSig { - inputs: sig_inputs, - output: sig_output, - variadic: sig_variadic - } = self.tcx.erase_late_bound_regions_and_normalize(sig); + let sig = self.tcx.erase_late_bound_regions_and_normalize(sig); - if !sig_inputs.is_empty() { - for ¶meter_type in &sig_inputs { + if !sig.inputs().is_empty() { + for ¶meter_type in sig.inputs() { self.push_type_name(parameter_type, output); output.push_str(", "); } @@ -495,8 +487,8 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.pop(); } - if sig_variadic { - if !sig_inputs.is_empty() { + if sig.variadic { + if !sig.inputs().is_empty() { output.push_str(", ..."); } else { output.push_str("..."); @@ -505,9 +497,9 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push(')'); - if !sig_output.is_nil() { + if !sig.output().is_nil() { output.push_str(" -> "); - self.push_type_name(sig_output, output); + self.push_type_name(sig.output(), output); } }, ty::TyClosure(def_id, ref closure_substs) => { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b5531b8bb9ec9..d458c7c009e2e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1595,7 +1595,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // checking for here would be considered early bound // anyway.) let inputs = bare_fn_ty.sig.inputs(); - let late_bound_in_args = tcx.collect_constrained_late_bound_regions(&inputs); + let late_bound_in_args = tcx.collect_constrained_late_bound_regions( + &inputs.map_bound(|i| i.to_owned())); let output = bare_fn_ty.sig.output(); let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output); for br in late_bound_in_ret.difference(&late_bound_in_args) { @@ -1795,19 +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 { - inputs: input_tys, - output: output_ty, - variadic: decl.variadic - }), + sig: ty::Binder(self.tcx().mk_fn_sig( + self_ty.into_iter().chain(arg_tys), + output_ty, + decl.variadic + )), }) } @@ -1849,20 +1847,20 @@ 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 - if i < e.inputs.len() { - Some(e.inputs[i]) + if i < e.inputs().len() { + Some(e.inputs()[i]) } else { None } }); 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, @@ -1879,15 +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 {inputs: input_tys, - output: output_ty, - variadic: 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 5b17b37e2795a..4fba29def226c 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -237,11 +237,11 @@ 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 { - inputs: self.err_args(arg_exprs.len()), - output: self.tcx.types.err, - variadic: false, - }); + error_fn_sig = ty::Binder(self.tcx.mk_fn_sig( + self.err_args(arg_exprs.len()).into_iter(), + self.tcx.types.err, + false, + )); (&error_fn_sig, None) } @@ -261,17 +261,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_arg_tys = self.expected_types_for_fn_args(call_expr.span, expected, - fn_sig.output, - &fn_sig.inputs); + fn_sig.output(), + fn_sig.inputs()); self.check_argument_types(call_expr.span, - &fn_sig.inputs, + fn_sig.inputs(), &expected_arg_tys[..], arg_exprs, fn_sig.variadic, TupleArgumentsFlag::DontTupleArguments, def_span); - fn_sig.output + fn_sig.output() } fn confirm_deferred_closure_call(&self, @@ -287,18 +287,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_arg_tys = self.expected_types_for_fn_args(call_expr.span, expected, - fn_sig.output.clone(), - &fn_sig.inputs); + fn_sig.output().clone(), + fn_sig.inputs()); self.check_argument_types(call_expr.span, - &fn_sig.inputs, + fn_sig.inputs(), &expected_arg_tys, arg_exprs, fn_sig.variadic, TupleArgumentsFlag::TupleArguments, None); - fn_sig.output + fn_sig.output() } fn confirm_overloaded_call(&self, @@ -365,12 +365,12 @@ 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[1..].iter().zip(&self.fn_sig.inputs) { - fcx.demand_eqtype(self.call_expr.span, self_arg_ty, method_arg_ty); + for (method_arg_ty, self_arg_ty) in + method_sig.inputs().iter().skip(1).zip(self.fn_sig.inputs()) { + fcx.demand_eqtype(self.call_expr.span, &self_arg_ty, &method_arg_ty); } - fcx.demand_eqtype(self.call_expr.span, method_sig.output, self.fn_sig.output); + fcx.demand_eqtype(self.call_expr.span, method_sig.output(), self.fn_sig.output()); fcx.write_overloaded_call_method_map(self.call_expr, method_callee); } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 486f8fc25bb32..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,11 @@ 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.inputs = vec![self.tcx.intern_tup(&fn_ty.sig.0.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() + ); debug!("closure for {:?} --> sig={:?} opt_kind={:?}", expr_def_id, @@ -212,23 +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 { - inputs: input_tys, - output: ret_param_ty, - variadic: 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/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 2602ff05badd4..e85dac1a44c44 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -495,8 +495,8 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a _ => bug!("{:?} is not a MethodTraitItem", trait_m), }; - let impl_iter = impl_sig.inputs.iter(); - let trait_iter = trait_sig.inputs.iter(); + let impl_iter = impl_sig.inputs().iter(); + let trait_iter = trait_sig.inputs().iter(); impl_iter.zip(trait_iter) .zip(impl_m_iter) .zip(trait_m_iter) @@ -508,7 +508,8 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a }) .next() .unwrap_or_else(|| { - if infcx.sub_types(false, &cause, impl_sig.output, trait_sig.output) + if infcx.sub_types(false, &cause, impl_sig.output(), + trait_sig.output()) .is_err() { (impl_m_output.span(), Some(trait_m_output.span())) } else { @@ -681,9 +682,9 @@ fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }; let impl_m_fty = m_fty(impl_m); let trait_m_fty = m_fty(trait_m); - if impl_m_fty.sig.0.inputs.len() != trait_m_fty.sig.0.inputs.len() { - let trait_number_args = trait_m_fty.sig.0.inputs.len(); - let impl_number_args = impl_m_fty.sig.0.inputs.len(); + let trait_number_args = trait_m_fty.sig.inputs().skip_binder().len(); + let impl_number_args = impl_m_fty.sig.inputs().skip_binder().len(); + if trait_number_args != impl_number_args { let trait_m_node_id = tcx.map.as_local_node_id(trait_m.def_id); let trait_span = if let Some(trait_id) = trait_m_node_id { match tcx.map.expect_trait_item(trait_id).node { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index a07573a7b9eab..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,11 +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 { - inputs: inputs, - output: output, - variadic: 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 { @@ -299,11 +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 { - inputs: vec![mut_u8], - output: tcx.mk_nil(), - variadic: 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) } @@ -377,21 +370,21 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt, let sig = tcx.item_type(def_id).fn_sig(); let sig = tcx.no_late_bound_regions(sig).unwrap(); - if intr.inputs.len() != sig.inputs.len() { + if intr.inputs.len() != sig.inputs().len() { span_err!(tcx.sess, it.span, E0444, "platform-specific intrinsic has invalid number of \ arguments: found {}, expected {}", - sig.inputs.len(), intr.inputs.len()); + sig.inputs().len(), intr.inputs.len()); return } - let input_pairs = intr.inputs.iter().zip(&sig.inputs); + let input_pairs = intr.inputs.iter().zip(sig.inputs()); for (i, (expected_arg, arg)) in input_pairs.enumerate() { match_intrinsic_type_to_type(ccx, &format!("argument {}", i + 1), it.span, &mut structural_to_nomimal, expected_arg, arg); } match_intrinsic_type_to_type(ccx, "return value", it.span, &mut structural_to_nomimal, - &intr.output, sig.output); + &intr.output, sig.output()); return } None => { diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 2e66f6290a022..b29eab780e035 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -246,7 +246,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { infer::FnCall, &fty.sig).0; let fn_sig = self.instantiate_type_scheme(span, trait_ref.substs, &fn_sig); - let transformed_self_ty = fn_sig.inputs[0]; + let transformed_self_ty = fn_sig.inputs()[0]; let method_ty = tcx.mk_fn_def(def_id, trait_ref.substs, tcx.mk_bare_fn(ty::BareFnTy { sig: ty::Binder(fn_sig), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1950adf832977..1b35081d5241c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -785,18 +785,18 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, // Create the function context. This is either derived from scratch or, // in the case of function expressions, based on the outer context. - let mut fcx = FnCtxt::new(inherited, fn_sig.output, body.id); + let mut fcx = FnCtxt::new(inherited, fn_sig.output(), body.id); *fcx.ps.borrow_mut() = UnsafetyState::function(unsafety, unsafety_id); 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.output = fcx.ret_ty; + fn_sig = fcx.tcx.mk_fn_sig(fn_sig.inputs().iter().cloned(), &fcx.ret_ty, fn_sig.variadic); { let mut visit = GatherLocalsVisitor { fcx: &fcx, }; // Add formal parameters. - for (arg_ty, input) in fn_sig.inputs.iter().zip(&decl.inputs) { + for (arg_ty, input) in fn_sig.inputs().iter().zip(&decl.inputs) { // The type of the argument must be well-formed. // // NB -- this is now checked in wfcheck, but that @@ -2473,14 +2473,16 @@ 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..]); - - self.check_argument_types(sp, &fty.sig.0.inputs[1..], &expected_arg_tys[..], + 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, self.tcx.map.span_if_local(def_id)); - fty.sig.0.output + fty.sig.0.output() } _ => { span_bug!(callee_expr.span, "method without bare fn type"); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index c0bf5773ed56a..eb08e70d4c3e4 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -296,10 +296,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // // FIXME(#27579) return types should not be implied bounds let fn_sig_tys: Vec<_> = - fn_sig.inputs.iter() - .cloned() - .chain(Some(fn_sig.output)) - .collect(); + fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect(); let old_body_id = self.set_body_id(body_id.node_id()); self.relate_free_regions(&fn_sig_tys[..], body_id.node_id(), span); @@ -940,7 +937,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let fn_sig = method.ty.fn_sig(); let fn_sig = // late-bound regions should have been instantiated self.tcx.no_late_bound_regions(fn_sig).unwrap(); - let self_ty = fn_sig.inputs[0]; + let self_ty = fn_sig.inputs()[0]; let (m, r) = match self_ty.sty { ty::TyRef(r, ref m) => (m.mutbl, r), _ => { @@ -967,8 +964,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.type_must_outlive(infer::CallRcvr(deref_expr.span), self_ty, r_deref_expr); self.type_must_outlive(infer::CallReturn(deref_expr.span), - fn_sig.output, r_deref_expr); - fn_sig.output + fn_sig.output(), r_deref_expr); + fn_sig.output() } None => derefd_ty }; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 7870b3677d0d0..7f35c8efeff41 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -449,15 +449,15 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { let fty = fcx.instantiate_type_scheme(span, free_substs, &fty); let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig); - for &input_ty in &sig.inputs { - fcx.register_wf_obligation(input_ty, span, self.code.clone()); + for input_ty in sig.inputs() { + fcx.register_wf_obligation(&input_ty, span, self.code.clone()); } - implied_bounds.extend(sig.inputs); + implied_bounds.extend(sig.inputs()); - fcx.register_wf_obligation(sig.output, span, self.code.clone()); + fcx.register_wf_obligation(sig.output(), span, self.code.clone()); // FIXME(#25759) return types should not be implied bounds - implied_bounds.push(sig.output); + implied_bounds.push(sig.output()); self.check_where_clauses(fcx, span, predicates); } @@ -487,7 +487,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { debug!("check_method_receiver: sig={:?}", sig); - let self_arg_ty = sig.inputs[0]; + let self_arg_ty = sig.inputs()[0]; let rcvr_ty = match ExplicitSelf::determine(self_ty, self_arg_ty) { ExplicitSelf::ByValue => self_ty, ExplicitSelf::ByReference(region, mutbl) => { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 3bb7d6a77ba5c..fba77d171797e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -920,21 +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 { - inputs: inputs, - output: ty, - variadic: false - }) + sig: ty::Binder(ccx.tcx.mk_fn_sig(inputs, ty, false)) })) } }; @@ -2085,9 +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 {inputs: input_tys, - output: output, - variadic: 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 dfa662590297f..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,11 +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 { - inputs: Vec::new(), - output: tcx.mk_nil(), - variadic: false - }) + sig: ty::Binder(tcx.mk_fn_sig(iter::empty(), tcx.mk_nil(), false)) })); require_same_types( @@ -274,14 +271,14 @@ 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 { - inputs: vec![ + sig: ty::Binder(tcx.mk_fn_sig( + [ tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8)) - ], - output: tcx.types.isize, - variadic: false, - }), + ].iter().cloned(), + tcx.types.isize, + false, + )), })); require_same_types( diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index ded9df25d5c66..39f996ee62b54 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -467,10 +467,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { sig: &ty::PolyFnSig<'tcx>, variance: VarianceTermPtr<'a>) { let contra = self.contravariant(variance); - for &input in &sig.0.inputs { + for &input in sig.0.inputs() { self.add_constraints_from_ty(generics, input, contra); } - self.add_constraints_from_ty(generics, sig.0.output, variance); + self.add_constraints_from_ty(generics, sig.0.output(), variance); } /// Adds constraints appropriate for a region appearing in a diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bc8472bb6b760..28ca92f5db6f6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1152,11 +1152,11 @@ impl<'a, 'tcx> Clean for (DefId, &'a ty::PolyFnSig<'tcx>) { cx.tcx.sess.cstore.fn_arg_names(did).into_iter() }.peekable(); FnDecl { - output: Return(sig.0.output.clean(cx)), + output: Return(sig.skip_binder().output().clean(cx)), attrs: Attributes::default(), - variadic: sig.0.variadic, + variadic: sig.skip_binder().variadic, inputs: Arguments { - values: sig.0.inputs.iter().map(|t| { + values: sig.skip_binder().inputs().iter().map(|t| { Argument { type_: t.clean(cx), id: ast::CRATE_NODE_ID,