@@ -11,7 +11,7 @@ use crate::mir::interpret::ConstValue;
11
11
use crate :: mir:: interpret:: Scalar ;
12
12
use crate :: mir:: Promoted ;
13
13
use crate :: ty:: layout:: VariantIdx ;
14
- use crate :: ty:: subst:: { GenericArgKind , InternalSubsts , Subst , SubstsRef } ;
14
+ use crate :: ty:: subst:: { GenericArg , GenericArgKind , InternalSubsts , Subst , SubstsRef } ;
15
15
use crate :: ty:: {
16
16
self , AdtDef , DefIdTree , Discr , Ty , TyCtxt , TypeFlags , TypeFoldable , WithConstness ,
17
17
} ;
@@ -276,6 +276,7 @@ static_assert_size!(TyKind<'_>, 24);
276
276
/// - U is a type parameter representing the types of its upvars, tupled up
277
277
/// (borrowed, if appropriate; that is, if an U field represents a by-ref upvar,
278
278
/// 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.
279
280
///
280
281
/// So, for example, given this function:
281
282
///
@@ -364,21 +365,26 @@ pub struct ClosureSubsts<'tcx> {
364
365
/// Struct returned by `split()`. Note that these are subslices of the
365
366
/// parent slice and not canonical substs themselves.
366
367
struct 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.
367
370
closure_kind_ty : Ty < ' tcx > ,
368
371
closure_sig_ty : Ty < ' tcx > ,
369
- tupled_upvars_ty : Ty < ' tcx > ,
372
+ upvars : & ' tcx [ GenericArg < ' tcx > ] ,
370
373
}
371
374
372
375
impl < ' tcx > ClosureSubsts < ' tcx > {
373
376
/// Divides the closure substs into their respective
374
377
/// components. Single source of truth with respect to the
375
378
/// ordering.
376
379
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
+ } ;
378
384
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 .. ] ,
382
388
}
383
389
}
384
390
@@ -388,22 +394,15 @@ impl<'tcx> ClosureSubsts<'tcx> {
388
394
/// Used primarily by `ty::print::pretty` to be able to handle closure
389
395
/// types that haven't had their synthetic types substituted in.
390
396
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
+ }
392
401
}
393
402
394
403
#[ inline]
395
404
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 ( ) )
407
406
}
408
407
409
408
/// Returns the closure kind for this closure; may return a type
@@ -454,22 +453,27 @@ pub struct GeneratorSubsts<'tcx> {
454
453
}
455
454
456
455
struct 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.
457
458
resume_ty : Ty < ' tcx > ,
458
459
yield_ty : Ty < ' tcx > ,
459
460
return_ty : Ty < ' tcx > ,
460
461
witness : Ty < ' tcx > ,
461
- tupled_upvars_ty : Ty < ' tcx > ,
462
+ upvars : & ' tcx [ GenericArg < ' tcx > ] ,
462
463
}
463
464
464
465
impl < ' tcx > GeneratorSubsts < ' tcx > {
465
466
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
+ } ;
467
471
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 .. ] ,
473
477
}
474
478
}
475
479
@@ -479,7 +483,10 @@ impl<'tcx> GeneratorSubsts<'tcx> {
479
483
/// Used primarily by `ty::print::pretty` to be able to handle generator
480
484
/// types that haven't had their synthetic types substituted in.
481
485
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
+ }
483
490
}
484
491
485
492
/// This describes the types that can be contained in a generator.
@@ -493,17 +500,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
493
500
494
501
#[ inline]
495
502
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 ( ) )
507
504
}
508
505
509
506
/// Returns the type representing the resume type of the generator.
@@ -643,13 +640,9 @@ pub enum UpvarSubsts<'tcx> {
643
640
impl < ' tcx > UpvarSubsts < ' tcx > {
644
641
#[ inline]
645
642
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 ,
653
646
} ;
654
647
upvars. iter ( ) . map ( |t| {
655
648
if let GenericArgKind :: Type ( ty) = t. unpack ( ) {
0 commit comments