diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-23 10:29:11 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-23 10:29:11 +0100 |
| commit | bee074f032970fd1b59650c04a70e75eeee9c63b (patch) | |
| tree | fae855037a249c1191dfca9c29ee8e9261790b85 /src/librustc | |
| parent | 906b39958322c54b76de4f301976e7753777be4e (diff) | |
| parent | d9a15ccd976bc8a4a79c99fbf68892c2bbdfffec (diff) | |
Rollup merge of #69968 - eddyb:tupled-closure-captures, r=nikomatsakis
rustc: keep upvars tupled in {Closure,Generator}Substs.
Previously, each closure/generator capture's (aka "upvar") type was tracked as one "synthetic" type parameter in the closure/generator substs, and figuring out where the parent `fn`'s generics end and the synthetics start involved slicing at `tcx.generics_of(def_id).parent_count`.
Needing to query `generics_of` limited @davidtwco (who wants to compute some `TypeFlags` differently for parent generics vs upvars, and `TyCtxt` is not available there), which is how I got started on this, but it's also possible that the `generics_of` queries are slowing down `{Closure,Generator}Substs` methods.
To give an example, for a `foo::<T, U>::{closure#0}` with captures `x: X` and `y: Y`, substs are:
* before this PR: `[T, U, /*kind*/, /*signature*/, X, Y]`
* after this PR: `[T, U, /*kind*/, /*signature*/, (X, Y)]`
You can see that, with this PR, no matter how many captures, the last 3 entries in the substs (or 5 for a generator) are always the "synthetic" ones, with the last one being the tuple of capture types.
r? @nikomatsakis cc @Zoxc
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/traits/query.rs | 4 | ||||
| -rw-r--r-- | src/librustc/ty/instance.rs | 4 | ||||
| -rw-r--r-- | src/librustc/ty/layout.rs | 20 | ||||
| -rw-r--r-- | src/librustc/ty/outlives.rs | 8 | ||||
| -rw-r--r-- | src/librustc/ty/print/pretty.rs | 87 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 191 | ||||
| -rw-r--r-- | src/librustc/ty/util.rs | 2 |
7 files changed, 160 insertions, 156 deletions
diff --git a/src/librustc/traits/query.rs b/src/librustc/traits/query.rs index c9055182620..67f4b15f919 100644 --- a/src/librustc/traits/query.rs +++ b/src/librustc/traits/query.rs @@ -229,8 +229,8 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { // (T1..Tn) and closures have same properties as T1..Tn -- // check if *any* of those are trivial. ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())), - ty::Closure(def_id, ref substs) => { - substs.as_closure().upvar_tys(def_id, tcx).all(|t| trivial_dropck_outlives(tcx, t)) + ty::Closure(_, ref substs) => { + substs.as_closure().upvar_tys().all(|t| trivial_dropck_outlives(tcx, t)) } ty::Adt(def, _) => { diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 46372701a92..ac49feaf8c2 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -341,7 +341,7 @@ impl<'tcx> Instance<'tcx> { substs: ty::SubstsRef<'tcx>, requested_kind: ty::ClosureKind, ) -> Instance<'tcx> { - let actual_kind = substs.as_closure().kind(def_id, tcx); + let actual_kind = substs.as_closure().kind(); match needs_fn_once_adapter_shim(actual_kind, requested_kind) { Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs), @@ -372,7 +372,7 @@ impl<'tcx> Instance<'tcx> { let self_ty = tcx.mk_closure(closure_did, substs); - let sig = substs.as_closure().sig(closure_did, tcx); + let sig = substs.as_closure().sig(); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); assert_eq!(sig.inputs().len(), 1); let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index d66fcd3a20d..c54360e0393 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -628,8 +628,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, substs)?, - ty::Closure(def_id, ref substs) => { - let tys = substs.as_closure().upvar_tys(def_id, tcx); + ty::Closure(_, ref substs) => { + let tys = substs.as_closure().upvar_tys(); univariant( &tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?, &ReprOptions::default(), @@ -1402,7 +1402,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Build a prefix layout, including "promoting" all ineligible // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. - let discr_index = substs.as_generator().prefix_tys(def_id, tcx).count(); + let discr_index = substs.as_generator().prefix_tys().count(); // `info.variant_fields` already accounts for the reserved variants, so no need to add them. let max_discr = (info.variant_fields.len() - 1) as u128; @@ -1419,7 +1419,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { .map(|ty| self.layout_of(ty)); let prefix_layouts = substs .as_generator() - .prefix_tys(def_id, tcx) + .prefix_tys() .map(|ty| self.layout_of(ty)) .chain(iter::once(Ok(discr_layout))) .chain(promoted_layouts) @@ -2095,9 +2095,7 @@ where ty::Str => tcx.types.u8, // Tuples, generators and closures. - ty::Closure(def_id, ref substs) => { - substs.as_closure().upvar_tys(def_id, tcx).nth(i).unwrap() - } + ty::Closure(_, ref substs) => substs.as_closure().upvar_tys().nth(i).unwrap(), ty::Generator(def_id, ref substs, _) => match this.variants { Variants::Single { index } => substs @@ -2111,7 +2109,7 @@ where if i == discr_index { return discr_layout(discr); } - substs.as_generator().prefix_tys(def_id, tcx).nth(i).unwrap() + substs.as_generator().prefix_tys().nth(i).unwrap() } }, @@ -2298,7 +2296,7 @@ impl<'tcx> ty::Instance<'tcx> { sig } ty::Closure(def_id, substs) => { - let sig = substs.as_closure().sig(def_id, tcx); + let sig = substs.as_closure().sig(); let env_ty = tcx.closure_env_ty(def_id, substs).unwrap(); sig.map_bound(|sig| tcx.mk_fn_sig( @@ -2309,8 +2307,8 @@ impl<'tcx> ty::Instance<'tcx> { sig.abi )) } - ty::Generator(def_id, substs, _) => { - let sig = substs.as_generator().poly_sig(def_id, tcx); + ty::Generator(_, substs, _) => { + let sig = substs.as_generator().poly_sig(); let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index b397a2c80d5..9dd96f2f2b5 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -61,15 +61,15 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo // in the `subtys` iterator (e.g., when encountering a // projection). match ty.kind { - ty::Closure(def_id, ref substs) => { - for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) { + ty::Closure(_, ref substs) => { + for upvar_ty in substs.as_closure().upvar_tys() { compute_components(tcx, upvar_ty, out); } } - ty::Generator(def_id, ref substs, _) => { + ty::Generator(_, ref substs, _) => { // Same as the closure case - for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) { + for upvar_ty in substs.as_generator().upvar_tys() { compute_components(tcx, upvar_ty, out); } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 8fbb9f0891a..3a95c573ca3 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -617,8 +617,6 @@ pub trait PrettyPrinter<'tcx>: } ty::Str => p!(write("str")), ty::Generator(did, substs, movability) => { - let upvar_tys = substs.as_generator().upvar_tys(did, self.tcx()); - let witness = substs.as_generator().witness(did, self.tcx()); match movability { hir::Movability::Movable => p!(write("[generator")), hir::Movability::Static => p!(write("[static generator")), @@ -627,31 +625,47 @@ pub trait PrettyPrinter<'tcx>: // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { p!(write("@{:?}", self.tcx().hir().span(hir_id))); - let mut sep = " "; - for (&var_id, upvar_ty) in - self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys) - { - p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); - sep = ", "; + + if substs.as_generator().is_valid() { + let upvar_tys = substs.as_generator().upvar_tys(); + let mut sep = " "; + for (&var_id, upvar_ty) in self + .tcx() + .upvars(did) + .as_ref() + .iter() + .flat_map(|v| v.keys()) + .zip(upvar_tys) + { + p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); + sep = ", "; + } } } else { // Cross-crate closure types should only be // visible in codegen bug reports, I imagine. p!(write("@{:?}", did)); - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - p!(write("{}{}:", sep, index), print(upvar_ty)); - sep = ", "; + + if substs.as_generator().is_valid() { + let upvar_tys = substs.as_generator().upvar_tys(); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!(write("{}{}:", sep, index), print(upvar_ty)); + sep = ", "; + } } } - p!(write(" "), print(witness), write("]")) + if substs.as_generator().is_valid() { + p!(write(" "), print(substs.as_generator().witness())); + } + + p!(write("]")) } ty::GeneratorWitness(types) => { p!(in_binder(&types)); } ty::Closure(did, substs) => { - let upvar_tys = substs.as_closure().upvar_tys(did, self.tcx()); p!(write("[closure")); // FIXME(eddyb) should use `def_span`. @@ -661,30 +675,43 @@ pub trait PrettyPrinter<'tcx>: } else { p!(write("@{:?}", self.tcx().hir().span(hir_id))); } - let mut sep = " "; - for (&var_id, upvar_ty) in - self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys) - { - p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); - sep = ", "; + + if substs.as_closure().is_valid() { + let upvar_tys = substs.as_closure().upvar_tys(); + let mut sep = " "; + for (&var_id, upvar_ty) in self + .tcx() + .upvars(did) + .as_ref() + .iter() + .flat_map(|v| v.keys()) + .zip(upvar_tys) + { + p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); + sep = ", "; + } } } else { // Cross-crate closure types should only be // visible in codegen bug reports, I imagine. p!(write("@{:?}", did)); - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - p!(write("{}{}:", sep, index), print(upvar_ty)); - sep = ", "; + + if substs.as_closure().is_valid() { + let upvar_tys = substs.as_closure().upvar_tys(); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!(write("{}{}:", sep, index), print(upvar_ty)); + sep = ", "; + } } } - if self.tcx().sess.verbose() { - p!(write( - " closure_kind_ty={:?} closure_sig_as_fn_ptr_ty={:?}", - substs.as_closure().kind_ty(did, self.tcx()), - substs.as_closure().sig_as_fn_ptr_ty(did, self.tcx()) - )); + if self.tcx().sess.verbose() && substs.as_closure().is_valid() { + p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty())); + p!( + write(" closure_sig_as_fn_ptr_ty="), + print(substs.as_closure().sig_as_fn_ptr_ty()) + ); } p!(write("]")) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 00310ef9b31..096f63fdf2e 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -11,7 +11,7 @@ use crate::mir::interpret::ConstValue; use crate::mir::interpret::Scalar; use crate::mir::Promoted; use crate::ty::layout::VariantIdx; -use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; +use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::{ self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness, }; @@ -260,15 +260,11 @@ static_assert_size!(TyKind<'_>, 24); /// A closure can be modeled as a struct that looks like: /// -/// struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> { -/// upvar0: U0, -/// ... -/// upvark: Uk -/// } +/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U); /// /// where: /// -/// - 'l0...'li and T0...Tj are the lifetime and type parameters +/// - 'l0...'li and T0...Tj are the generic parameters /// in scope on the function that defined the closure, /// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This /// is rather hackily encoded via a scalar type. See @@ -277,9 +273,9 @@ static_assert_size!(TyKind<'_>, 24); /// type. For example, `fn(u32, u32) -> u32` would mean that the closure /// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait /// specified above. -/// - U0...Uk are type parameters representing the types of its upvars -/// (borrowed, if appropriate; that is, if Ui represents a by-ref upvar, -/// and the up-var has the type `Foo`, then `Ui = &Foo`). +/// - U is a type parameter representing the types of its upvars, tupled up +/// (borrowed, if appropriate; that is, if an U field represents a by-ref upvar, +/// and the up-var has the type `Foo`, then that field of U will be `&Foo`). /// /// So, for example, given this function: /// @@ -289,9 +285,7 @@ static_assert_size!(TyKind<'_>, 24); /// /// the type of the closure would be something like: /// -/// struct Closure<'a, T, U0> { -/// data: U0 -/// } +/// struct Closure<'a, T, U>(...U); /// /// Note that the type of the upvar is not specified in the struct. /// You may wonder how the impl would then be able to use the upvar, @@ -299,7 +293,7 @@ static_assert_size!(TyKind<'_>, 24); /// (conceptually) not fully generic over Closure but rather tied to /// instances with the expected upvar types: /// -/// impl<'b, 'a, T> FnMut() for Closure<'a, T, &'b mut &'a mut T> { +/// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> { /// ... /// } /// @@ -308,7 +302,7 @@ static_assert_size!(TyKind<'_>, 24); /// (Here, I am assuming that `data` is mut-borrowed.) /// /// Now, the last question you may ask is: Why include the upvar types -/// as extra type parameters? The reason for this design is that the +/// in an extra type parameter? The reason for this design is that the /// upvar types can reference lifetimes that are internal to the /// creating function. In my example above, for example, the lifetime /// `'b` represents the scope of the closure itself; this is some @@ -360,7 +354,7 @@ static_assert_size!(TyKind<'_>, 24); #[derive(Copy, Clone, Debug, TypeFoldable)] pub struct ClosureSubsts<'tcx> { /// Lifetime and type parameters from the enclosing function, - /// concatenated with the types of the upvars. + /// concatenated with a tuple containing the types of the upvars. /// /// These are separated out because codegen wants to pass them around /// when monomorphizing. @@ -370,52 +364,52 @@ pub struct ClosureSubsts<'tcx> { /// Struct returned by `split()`. Note that these are subslices of the /// parent slice and not canonical substs themselves. struct SplitClosureSubsts<'tcx> { - closure_kind_ty: Ty<'tcx>, - closure_sig_as_fn_ptr_ty: Ty<'tcx>, - upvar_kinds: &'tcx [GenericArg<'tcx>], + closure_kind_ty: GenericArg<'tcx>, + closure_sig_as_fn_ptr_ty: GenericArg<'tcx>, + tupled_upvars_ty: GenericArg<'tcx>, } impl<'tcx> ClosureSubsts<'tcx> { /// Divides the closure substs into their respective /// components. Single source of truth with respect to the /// ordering. - fn split(self, def_id: DefId, tcx: TyCtxt<'_>) -> SplitClosureSubsts<'tcx> { - let generics = tcx.generics_of(def_id); - let parent_len = generics.parent_count; - SplitClosureSubsts { - closure_kind_ty: self.substs.type_at(parent_len), - closure_sig_as_fn_ptr_ty: self.substs.type_at(parent_len + 1), - upvar_kinds: &self.substs[parent_len + 2..], + fn split(self) -> SplitClosureSubsts<'tcx> { + match self.substs[..] { + [.., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => { + SplitClosureSubsts { closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty } + } + _ => bug!("closure substs missing synthetics"), } } + /// Returns `true` only if enough of the synthetic types are known to + /// allow using all of the methods on `ClosureSubsts` without panicking. + /// + /// Used primarily by `ty::print::pretty` to be able to handle closure + /// types that haven't had their synthetic types substituted in. + pub fn is_valid(self) -> bool { + self.substs.len() >= 3 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_)) + } + #[inline] - pub fn upvar_tys( - self, - def_id: DefId, - tcx: TyCtxt<'_>, - ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx); - upvar_kinds.iter().map(|t| { - if let GenericArgKind::Type(ty) = t.unpack() { - ty - } else { - bug!("upvar should be type") - } - }) + pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { + self.split().tupled_upvars_ty.expect_ty().tuple_fields() } /// Returns the closure kind for this closure; may return a type /// variable during inference. To get the closure kind during - /// inference, use `infcx.closure_kind(def_id, substs)`. - pub fn kind_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { - self.split(def_id, tcx).closure_kind_ty + /// inference, use `infcx.closure_kind(substs)`. + pub fn kind_ty(self) -> Ty<'tcx> { + self.split().closure_kind_ty.expect_ty() } /// Returns the `fn` pointer type representing the closure signature for this /// closure. - pub fn sig_as_fn_ptr_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { - self.split(def_id, tcx).closure_sig_as_fn_ptr_ty + // FIXME(eddyb) this should be unnecessary, as the shallowly resolved + // type is known at the time of the creation of `ClosureSubsts`, + // see `rustc_typeck::check::closure`. + pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> { + self.split().closure_sig_as_fn_ptr_ty.expect_ty() } /// Returns the closure kind for this closure; only usable outside @@ -423,13 +417,13 @@ impl<'tcx> ClosureSubsts<'tcx> { /// there are no type variables. /// /// If you have an inference context, use `infcx.closure_kind()`. - pub fn kind(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::ClosureKind { - self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap() + pub fn kind(self) -> ty::ClosureKind { + self.kind_ty().to_opt_closure_kind().unwrap() } /// Extracts the signature from the closure. - pub fn sig(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { - let ty = self.sig_as_fn_ptr_ty(def_id, tcx); + pub fn sig(self) -> ty::PolyFnSig<'tcx> { + let ty = self.sig_as_fn_ptr_ty(); match ty.kind { ty::FnPtr(sig) => sig, _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind), @@ -444,64 +438,59 @@ pub struct GeneratorSubsts<'tcx> { } struct SplitGeneratorSubsts<'tcx> { - resume_ty: Ty<'tcx>, - yield_ty: Ty<'tcx>, - return_ty: Ty<'tcx>, - witness: Ty<'tcx>, - upvar_kinds: &'tcx [GenericArg<'tcx>], + resume_ty: GenericArg<'tcx>, + yield_ty: GenericArg<'tcx>, + return_ty: GenericArg<'tcx>, + witness: GenericArg<'tcx>, + tupled_upvars_ty: GenericArg<'tcx>, } impl<'tcx> GeneratorSubsts<'tcx> { - fn split(self, def_id: DefId, tcx: TyCtxt<'_>) -> SplitGeneratorSubsts<'tcx> { - let generics = tcx.generics_of(def_id); - let parent_len = generics.parent_count; - SplitGeneratorSubsts { - resume_ty: self.substs.type_at(parent_len), - yield_ty: self.substs.type_at(parent_len + 1), - return_ty: self.substs.type_at(parent_len + 2), - witness: self.substs.type_at(parent_len + 3), - upvar_kinds: &self.substs[parent_len + 4..], + fn split(self) -> SplitGeneratorSubsts<'tcx> { + match self.substs[..] { + [.., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => { + SplitGeneratorSubsts { resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty } + } + _ => bug!("generator substs missing synthetics"), } } + /// Returns `true` only if enough of the synthetic types are known to + /// allow using all of the methods on `GeneratorSubsts` without panicking. + /// + /// Used primarily by `ty::print::pretty` to be able to handle generator + /// types that haven't had their synthetic types substituted in. + pub fn is_valid(self) -> bool { + self.substs.len() >= 5 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_)) + } + /// This describes the types that can be contained in a generator. /// It will be a type variable initially and unified in the last stages of typeck of a body. /// It contains a tuple of all the types that could end up on a generator frame. /// The state transformation MIR pass may only produce layouts which mention types /// in this tuple. Upvars are not counted here. - pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { - self.split(def_id, tcx).witness + pub fn witness(self) -> Ty<'tcx> { + self.split().witness.expect_ty() } #[inline] - pub fn upvar_tys( - self, - def_id: DefId, - tcx: TyCtxt<'_>, - ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx); - upvar_kinds.iter().map(|t| { - if let GenericArgKind::Type(ty) = t.unpack() { - ty - } else { - bug!("upvar should be type") - } - }) + pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { + self.split().tupled_upvars_ty.expect_ty().tuple_fields() } /// Returns the type representing the resume type of the generator. - pub fn resume_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { - self.split(def_id, tcx).resume_ty + pub fn resume_ty(self) -> Ty<'tcx> { + self.split().resume_ty.expect_ty() } /// Returns the type representing the yield type of the generator. - pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { - self.split(def_id, tcx).yield_ty + pub fn yield_ty(self) -> Ty<'tcx> { + self.split().yield_ty.expect_ty() } /// Returns the type representing the return type of the generator. - pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { - self.split(def_id, tcx).return_ty + pub fn return_ty(self) -> Ty<'tcx> { + self.split().return_ty.expect_ty() } /// Returns the "generator signature", which consists of its yield @@ -510,17 +499,17 @@ impl<'tcx> GeneratorSubsts<'tcx> { /// N.B., some bits of the code prefers to see this wrapped in a /// binder, but it never contains bound regions. Probably this /// function should be removed. - pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> PolyGenSig<'tcx> { - ty::Binder::dummy(self.sig(def_id, tcx)) + pub fn poly_sig(self) -> PolyGenSig<'tcx> { + ty::Binder::dummy(self.sig()) } /// Returns the "generator signature", which consists of its resume, yield /// and return types. - pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> GenSig<'tcx> { + pub fn sig(self) -> GenSig<'tcx> { ty::GenSig { - resume_ty: self.resume_ty(def_id, tcx), - yield_ty: self.yield_ty(def_id, tcx), - return_ty: self.return_ty(def_id, tcx), + resume_ty: self.resume_ty(), + yield_ty: self.yield_ty(), + return_ty: self.return_ty(), } } } @@ -612,8 +601,8 @@ impl<'tcx> GeneratorSubsts<'tcx> { /// This is the types of the fields of a generator which are not stored in a /// variant. #[inline] - pub fn prefix_tys(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> impl Iterator<Item = Ty<'tcx>> { - self.upvar_tys(def_id, tcx) + pub fn prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>> { + self.upvar_tys() } } @@ -625,22 +614,12 @@ pub enum UpvarSubsts<'tcx> { impl<'tcx> UpvarSubsts<'tcx> { #[inline] - pub fn upvar_tys( - self, - def_id: DefId, - tcx: TyCtxt<'tcx>, - ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - let upvar_kinds = match self { - UpvarSubsts::Closure(substs) => substs.as_closure().split(def_id, tcx).upvar_kinds, - UpvarSubsts::Generator(substs) => substs.as_generator().split(def_id, tcx).upvar_kinds, + pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { + let tupled_upvars_ty = match self { + UpvarSubsts::Closure(substs) => substs.as_closure().split().tupled_upvars_ty, + UpvarSubsts::Generator(substs) => substs.as_generator().split().tupled_upvars_ty, }; - upvar_kinds.iter().map(|t| { - if let GenericArgKind::Type(ty) = t.unpack() { - ty - } else { - bug!("upvar should be type") - } - }) + tupled_upvars_ty.expect_ty().tuple_fields() } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 69daa2da1fd..1f512f1dde7 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -502,7 +502,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> Option<ty::Binder<Ty<'tcx>>> { let closure_ty = self.mk_closure(closure_def_id, closure_substs); let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); - let closure_kind_ty = closure_substs.as_closure().kind_ty(closure_def_id, self); + let closure_kind_ty = closure_substs.as_closure().kind_ty(); let closure_kind = closure_kind_ty.to_opt_closure_kind()?; let env_ty = match closure_kind { ty::ClosureKind::Fn => self.mk_imm_ref(self.mk_region(env_region), closure_ty), |
