diff options
| author | David Wood <david@davidtw.co> | 2020-06-22 13:07:05 +0100 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2020-07-20 11:23:25 +0100 |
| commit | c6ed442f401d90211ae36a9808ccaf0a3dc025f6 (patch) | |
| tree | 226bb49097be3131683c13cdc06e4f7b7c905eb8 | |
| parent | 576deef691830084184be0618e86fd4a798802ed (diff) | |
| download | rust-c6ed442f401d90211ae36a9808ccaf0a3dc025f6.tar.gz rust-c6ed442f401d90211ae36a9808ccaf0a3dc025f6.zip | |
ty: `STILL_FURTHER_SPECIALIZABLE` w/out prnt subst
This commit modifies the `STILL_FURTHER_SPECIALIZABLE` flag so that the flag isn't set by the parent substs of closures or generators. Signed-off-by: David Wood <david@davidtw.co>
| -rw-r--r-- | src/librustc_middle/ty/flags.rs | 26 | ||||
| -rw-r--r-- | src/librustc_middle/ty/sty.rs | 48 |
2 files changed, 66 insertions, 8 deletions
diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs index 0e86fcf53b2..11a8bedb660 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/src/librustc_middle/ty/flags.rs @@ -85,7 +85,19 @@ impl FlagComputation { } &ty::Generator(_, ref substs, _) => { - self.add_substs(substs); + let substs = substs.as_generator(); + let should_remove_further_specializable = + !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); + self.add_substs(substs.parent_substs()); + if should_remove_further_specializable { + self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; + } + + self.add_ty(substs.resume_ty()); + self.add_ty(substs.return_ty()); + self.add_ty(substs.witness()); + self.add_ty(substs.yield_ty()); + self.add_ty(substs.tupled_upvars_ty()); } &ty::GeneratorWitness(ts) => { @@ -95,7 +107,17 @@ impl FlagComputation { } &ty::Closure(_, substs) => { - self.add_substs(substs); + let substs = substs.as_closure(); + let should_remove_further_specializable = + !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); + self.add_substs(substs.parent_substs()); + if should_remove_further_specializable { + self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; + } + + self.add_ty(substs.sig_as_fn_ptr_ty()); + self.add_ty(substs.kind_ty()); + self.add_ty(substs.tupled_upvars_ty()); } &ty::Bound(debruijn, _) => { diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 2f17db62233..03bf51c95c5 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -318,6 +318,7 @@ 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> { + parent: &'tcx [GenericArg<'tcx>], closure_kind_ty: GenericArg<'tcx>, closure_sig_as_fn_ptr_ty: GenericArg<'tcx>, tupled_upvars_ty: GenericArg<'tcx>, @@ -329,8 +330,13 @@ impl<'tcx> ClosureSubsts<'tcx> { /// ordering. 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 } + [ref parent @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => { + SplitClosureSubsts { + parent, + closure_kind_ty, + closure_sig_as_fn_ptr_ty, + tupled_upvars_ty, + } } _ => bug!("closure substs missing synthetics"), } @@ -345,9 +351,20 @@ impl<'tcx> ClosureSubsts<'tcx> { self.substs.len() >= 3 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_)) } + /// Returns the substitutions of the closure's parent. + pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] { + self.split().parent + } + #[inline] pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - self.split().tupled_upvars_ty.expect_ty().tuple_fields() + self.tupled_upvars_ty().tuple_fields() + } + + /// Returns the tuple type representing the upvars for this closure. + #[inline] + pub fn tupled_upvars_ty(self) -> Ty<'tcx> { + self.split().tupled_upvars_ty.expect_ty() } /// Returns the closure kind for this closure; may return a type @@ -392,6 +409,7 @@ pub struct GeneratorSubsts<'tcx> { } struct SplitGeneratorSubsts<'tcx> { + parent: &'tcx [GenericArg<'tcx>], resume_ty: GenericArg<'tcx>, yield_ty: GenericArg<'tcx>, return_ty: GenericArg<'tcx>, @@ -402,8 +420,15 @@ struct SplitGeneratorSubsts<'tcx> { impl<'tcx> GeneratorSubsts<'tcx> { 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 } + [ref parent @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => { + SplitGeneratorSubsts { + parent, + resume_ty, + yield_ty, + return_ty, + witness, + tupled_upvars_ty, + } } _ => bug!("generator substs missing synthetics"), } @@ -418,6 +443,11 @@ impl<'tcx> GeneratorSubsts<'tcx> { self.substs.len() >= 5 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_)) } + /// Returns the substitutions of the generator's parent. + pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] { + self.split().parent + } + /// 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. @@ -429,7 +459,13 @@ impl<'tcx> GeneratorSubsts<'tcx> { #[inline] pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - self.split().tupled_upvars_ty.expect_ty().tuple_fields() + self.tupled_upvars_ty().tuple_fields() + } + + /// Returns the tuple type representing the upvars for this generator. + #[inline] + pub fn tupled_upvars_ty(self) -> Ty<'tcx> { + self.split().tupled_upvars_ty.expect_ty() } /// Returns the type representing the resume type of the generator. |
