@@ -11,7 +11,7 @@ use crate::mir::interpret::ConstValue;
1111use crate :: mir:: interpret:: Scalar ;
1212use crate :: mir:: Promoted ;
1313use crate :: ty:: layout:: VariantIdx ;
14- use crate :: ty:: subst:: { GenericArgKind , InternalSubsts , Subst , SubstsRef } ;
14+ use crate :: ty:: subst:: { GenericArg , GenericArgKind , InternalSubsts , Subst , SubstsRef } ;
1515use crate :: ty:: {
1616 self , AdtDef , DefIdTree , Discr , Ty , TyCtxt , TypeFlags , TypeFoldable , WithConstness ,
1717} ;
@@ -276,6 +276,7 @@ static_assert_size!(TyKind<'_>, 24);
276276/// - U is a type parameter representing the types of its upvars, tupled up
277277/// (borrowed, if appropriate; that is, if an U field represents a by-ref upvar,
278278/// and the up-var has the type `Foo`, then that field of U will be `&Foo`).
279+ /// FIXME(eddyb) update this with the new setup which tuples all synthetics.
279280///
280281/// So, for example, given this function:
281282///
@@ -364,21 +365,26 @@ pub struct ClosureSubsts<'tcx> {
364365/// Struct returned by `split()`. Note that these are subslices of the
365366/// parent slice and not canonical substs themselves.
366367struct SplitClosureSubsts < ' tcx > {
368+ // FIXME(eddyb) maybe replace these with `GenericArg` to avoid having
369+ // `GenericArg::expect_ty` called on all of them when only one is used.
367370 closure_kind_ty : Ty < ' tcx > ,
368371 closure_sig_ty : Ty < ' tcx > ,
369- tupled_upvars_ty : Ty < ' tcx > ,
372+ upvars : & ' tcx [ GenericArg < ' tcx > ] ,
370373}
371374
372375impl < ' tcx > ClosureSubsts < ' tcx > {
373376 /// Divides the closure substs into their respective
374377 /// components. Single source of truth with respect to the
375378 /// ordering.
376379 fn split ( self ) -> SplitClosureSubsts < ' tcx > {
377- let parent_len = self . substs . len ( ) - 3 ;
380+ let synthetics = match self . substs [ self . substs . len ( ) - 1 ] . expect_ty ( ) . kind {
381+ Tuple ( synthetics) => synthetics,
382+ _ => bug ! ( "synthetics should be tupled" ) ,
383+ } ;
378384 SplitClosureSubsts {
379- closure_kind_ty : self . substs . type_at ( parent_len ) ,
380- closure_sig_ty : self . substs . type_at ( parent_len + 1 ) ,
381- tupled_upvars_ty : self . substs . type_at ( parent_len + 2 ) ,
385+ closure_kind_ty : synthetics . type_at ( 0 ) ,
386+ closure_sig_ty : synthetics . type_at ( 1 ) ,
387+ upvars : & synthetics [ 2 .. ] ,
382388 }
383389 }
384390
@@ -388,22 +394,15 @@ impl<'tcx> ClosureSubsts<'tcx> {
388394 /// Used primarily by `ty::print::pretty` to be able to handle closure
389395 /// types that haven't had their synthetic types substituted in.
390396 pub fn is_valid ( self ) -> bool {
391- self . substs . len ( ) >= 3 && matches ! ( self . split( ) . tupled_upvars_ty. kind, Tuple ( _) )
397+ match self . substs [ self . substs . len ( ) - 1 ] . expect_ty ( ) . kind {
398+ Tuple ( synthetics) => synthetics. len ( ) >= 2 ,
399+ _ => false ,
400+ }
392401 }
393402
394403 #[ inline]
395404 pub fn upvar_tys ( self ) -> impl Iterator < Item = Ty < ' tcx > > + ' tcx {
396- let upvars = match self . split ( ) . tupled_upvars_ty . kind {
397- Tuple ( upvars) => upvars,
398- _ => bug ! ( "upvars should be tupled" ) ,
399- } ;
400- upvars. iter ( ) . map ( |t| {
401- if let GenericArgKind :: Type ( ty) = t. unpack ( ) {
402- ty
403- } else {
404- bug ! ( "upvar should be type" )
405- }
406- } )
405+ self . split ( ) . upvars . iter ( ) . map ( |t| t. expect_ty ( ) )
407406 }
408407
409408 /// Returns the closure kind for this closure; may return a type
@@ -454,22 +453,27 @@ pub struct GeneratorSubsts<'tcx> {
454453}
455454
456455struct SplitGeneratorSubsts < ' tcx > {
456+ // FIXME(eddyb) maybe replace these with `GenericArg` to avoid having
457+ // `GenericArg::expect_ty` called on all of them when only one is used.
457458 resume_ty : Ty < ' tcx > ,
458459 yield_ty : Ty < ' tcx > ,
459460 return_ty : Ty < ' tcx > ,
460461 witness : Ty < ' tcx > ,
461- tupled_upvars_ty : Ty < ' tcx > ,
462+ upvars : & ' tcx [ GenericArg < ' tcx > ] ,
462463}
463464
464465impl < ' tcx > GeneratorSubsts < ' tcx > {
465466 fn split ( self ) -> SplitGeneratorSubsts < ' tcx > {
466- let parent_len = self . substs . len ( ) - 5 ;
467+ let synthetics = match self . substs [ self . substs . len ( ) - 1 ] . expect_ty ( ) . kind {
468+ Tuple ( synthetics) => synthetics,
469+ _ => bug ! ( "synthetics should be tupled" ) ,
470+ } ;
467471 SplitGeneratorSubsts {
468- resume_ty : self . substs . type_at ( parent_len ) ,
469- yield_ty : self . substs . type_at ( parent_len + 1 ) ,
470- return_ty : self . substs . type_at ( parent_len + 2 ) ,
471- witness : self . substs . type_at ( parent_len + 3 ) ,
472- tupled_upvars_ty : self . substs . type_at ( parent_len + 4 ) ,
472+ resume_ty : synthetics . type_at ( 0 ) ,
473+ yield_ty : synthetics . type_at ( 1 ) ,
474+ return_ty : synthetics . type_at ( 2 ) ,
475+ witness : synthetics . type_at ( 3 ) ,
476+ upvars : & synthetics [ 4 .. ] ,
473477 }
474478 }
475479
@@ -479,7 +483,10 @@ impl<'tcx> GeneratorSubsts<'tcx> {
479483 /// Used primarily by `ty::print::pretty` to be able to handle generator
480484 /// types that haven't had their synthetic types substituted in.
481485 pub fn is_valid ( self ) -> bool {
482- self . substs . len ( ) >= 5 && matches ! ( self . split( ) . tupled_upvars_ty. kind, Tuple ( _) )
486+ match self . substs [ self . substs . len ( ) - 1 ] . expect_ty ( ) . kind {
487+ Tuple ( synthetics) => synthetics. len ( ) >= 4 ,
488+ _ => false ,
489+ }
483490 }
484491
485492 /// This describes the types that can be contained in a generator.
@@ -493,17 +500,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
493500
494501 #[ inline]
495502 pub fn upvar_tys ( self ) -> impl Iterator < Item = Ty < ' tcx > > + ' tcx {
496- let upvars = match self . split ( ) . tupled_upvars_ty . kind {
497- Tuple ( upvars) => upvars,
498- _ => bug ! ( "upvars should be tupled" ) ,
499- } ;
500- upvars. iter ( ) . map ( |t| {
501- if let GenericArgKind :: Type ( ty) = t. unpack ( ) {
502- ty
503- } else {
504- bug ! ( "upvar should be type" )
505- }
506- } )
503+ self . split ( ) . upvars . iter ( ) . map ( |t| t. expect_ty ( ) )
507504 }
508505
509506 /// Returns the type representing the resume type of the generator.
@@ -643,13 +640,9 @@ pub enum UpvarSubsts<'tcx> {
643640impl < ' tcx > UpvarSubsts < ' tcx > {
644641 #[ inline]
645642 pub fn upvar_tys ( self ) -> impl Iterator < Item = Ty < ' tcx > > + ' tcx {
646- let tupled_upvars_ty = match self {
647- UpvarSubsts :: Closure ( substs) => substs. as_closure ( ) . split ( ) . tupled_upvars_ty ,
648- UpvarSubsts :: Generator ( substs) => substs. as_generator ( ) . split ( ) . tupled_upvars_ty ,
649- } ;
650- let upvars = match tupled_upvars_ty. kind {
651- Tuple ( upvars) => upvars,
652- _ => bug ! ( "upvars should be tupled" ) ,
643+ let upvars = match self {
644+ UpvarSubsts :: Closure ( substs) => substs. as_closure ( ) . split ( ) . upvars ,
645+ UpvarSubsts :: Generator ( substs) => substs. as_generator ( ) . split ( ) . upvars ,
653646 } ;
654647 upvars. iter ( ) . map ( |t| {
655648 if let GenericArgKind :: Type ( ty) = t. unpack ( ) {
0 commit comments