Skip to content

Commit 3fd397b

Browse files
committed
rustc: make {Closure,Generator}Substs::split as cheap as possible.
1 parent 10f08ab commit 3fd397b

File tree

1 file changed

+31
-67
lines changed

1 file changed

+31
-67
lines changed

src/librustc/ty/sty.rs

Lines changed: 31 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::mir::interpret::ConstValue;
1111
use crate::mir::interpret::Scalar;
1212
use crate::mir::Promoted;
1313
use crate::ty::layout::VariantIdx;
14-
use crate::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef};
14+
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
1515
use crate::ty::{
1616
self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
1717
};
@@ -364,23 +364,21 @@ pub struct ClosureSubsts<'tcx> {
364364
/// Struct returned by `split()`. Note that these are subslices of the
365365
/// parent slice and not canonical substs themselves.
366366
struct SplitClosureSubsts<'tcx> {
367-
// FIXME(eddyb) maybe replace these with `GenericArg` to avoid having
368-
// `GenericArg::expect_ty` called on all of them when only one is used.
369-
closure_kind_ty: Ty<'tcx>,
370-
closure_sig_as_fn_ptr_ty: Ty<'tcx>,
371-
tupled_upvars_ty: Ty<'tcx>,
367+
closure_kind_ty: GenericArg<'tcx>,
368+
closure_sig_as_fn_ptr_ty: GenericArg<'tcx>,
369+
tupled_upvars_ty: GenericArg<'tcx>,
372370
}
373371

374372
impl<'tcx> ClosureSubsts<'tcx> {
375373
/// Divides the closure substs into their respective
376374
/// components. Single source of truth with respect to the
377375
/// ordering.
378376
fn split(self) -> SplitClosureSubsts<'tcx> {
379-
let parent_len = self.substs.len() - 3;
380-
SplitClosureSubsts {
381-
closure_kind_ty: self.substs.type_at(parent_len),
382-
closure_sig_as_fn_ptr_ty: self.substs.type_at(parent_len + 1),
383-
tupled_upvars_ty: self.substs.type_at(parent_len + 2),
377+
match self.substs[..] {
378+
[.., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
379+
SplitClosureSubsts { closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty }
380+
}
381+
_ => bug!("closure substs missing synthetics"),
384382
}
385383
}
386384

@@ -390,29 +388,19 @@ impl<'tcx> ClosureSubsts<'tcx> {
390388
/// Used primarily by `ty::print::pretty` to be able to handle closure
391389
/// types that haven't had their synthetic types substituted in.
392390
pub fn is_valid(self) -> bool {
393-
self.substs.len() >= 3 && matches!(self.split().tupled_upvars_ty.kind, Tuple(_))
391+
self.substs.len() >= 3 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_))
394392
}
395393

396394
#[inline]
397395
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
398-
let upvars = match self.split().tupled_upvars_ty.kind {
399-
Tuple(upvars) => upvars,
400-
_ => bug!("upvars should be tupled"),
401-
};
402-
upvars.iter().map(|t| {
403-
if let GenericArgKind::Type(ty) = t.unpack() {
404-
ty
405-
} else {
406-
bug!("upvar should be type")
407-
}
408-
})
396+
self.split().tupled_upvars_ty.expect_ty().tuple_fields()
409397
}
410398

411399
/// Returns the closure kind for this closure; may return a type
412400
/// variable during inference. To get the closure kind during
413401
/// inference, use `infcx.closure_kind(substs)`.
414402
pub fn kind_ty(self) -> Ty<'tcx> {
415-
self.split().closure_kind_ty
403+
self.split().closure_kind_ty.expect_ty()
416404
}
417405

418406
/// Returns the `fn` pointer type representing the closure signature for this
@@ -421,7 +409,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
421409
// type is known at the time of the creation of `ClosureSubsts`,
422410
// see `rustc_typeck::check::closure`.
423411
pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> {
424-
self.split().closure_sig_as_fn_ptr_ty
412+
self.split().closure_sig_as_fn_ptr_ty.expect_ty()
425413
}
426414

427415
/// Returns the closure kind for this closure; only usable outside
@@ -430,7 +418,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
430418
///
431419
/// If you have an inference context, use `infcx.closure_kind()`.
432420
pub fn kind(self) -> ty::ClosureKind {
433-
self.split().closure_kind_ty.to_opt_closure_kind().unwrap()
421+
self.kind_ty().to_opt_closure_kind().unwrap()
434422
}
435423

436424
/// Extracts the signature from the closure.
@@ -450,24 +438,20 @@ pub struct GeneratorSubsts<'tcx> {
450438
}
451439

452440
struct SplitGeneratorSubsts<'tcx> {
453-
// FIXME(eddyb) maybe replace these with `GenericArg` to avoid having
454-
// `GenericArg::expect_ty` called on all of them when only one is used.
455-
resume_ty: Ty<'tcx>,
456-
yield_ty: Ty<'tcx>,
457-
return_ty: Ty<'tcx>,
458-
witness: Ty<'tcx>,
459-
tupled_upvars_ty: Ty<'tcx>,
441+
resume_ty: GenericArg<'tcx>,
442+
yield_ty: GenericArg<'tcx>,
443+
return_ty: GenericArg<'tcx>,
444+
witness: GenericArg<'tcx>,
445+
tupled_upvars_ty: GenericArg<'tcx>,
460446
}
461447

462448
impl<'tcx> GeneratorSubsts<'tcx> {
463449
fn split(self) -> SplitGeneratorSubsts<'tcx> {
464-
let parent_len = self.substs.len() - 5;
465-
SplitGeneratorSubsts {
466-
resume_ty: self.substs.type_at(parent_len),
467-
yield_ty: self.substs.type_at(parent_len + 1),
468-
return_ty: self.substs.type_at(parent_len + 2),
469-
witness: self.substs.type_at(parent_len + 3),
470-
tupled_upvars_ty: self.substs.type_at(parent_len + 4),
450+
match self.substs[..] {
451+
[.., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
452+
SplitGeneratorSubsts { resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty }
453+
}
454+
_ => bug!("generator substs missing synthetics"),
471455
}
472456
}
473457

@@ -477,7 +461,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
477461
/// Used primarily by `ty::print::pretty` to be able to handle generator
478462
/// types that haven't had their synthetic types substituted in.
479463
pub fn is_valid(self) -> bool {
480-
self.substs.len() >= 5 && matches!(self.split().tupled_upvars_ty.kind, Tuple(_))
464+
self.substs.len() >= 5 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_))
481465
}
482466

483467
/// This describes the types that can be contained in a generator.
@@ -486,37 +470,27 @@ impl<'tcx> GeneratorSubsts<'tcx> {
486470
/// The state transformation MIR pass may only produce layouts which mention types
487471
/// in this tuple. Upvars are not counted here.
488472
pub fn witness(self) -> Ty<'tcx> {
489-
self.split().witness
473+
self.split().witness.expect_ty()
490474
}
491475

492476
#[inline]
493477
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
494-
let upvars = match self.split().tupled_upvars_ty.kind {
495-
Tuple(upvars) => upvars,
496-
_ => bug!("upvars should be tupled"),
497-
};
498-
upvars.iter().map(|t| {
499-
if let GenericArgKind::Type(ty) = t.unpack() {
500-
ty
501-
} else {
502-
bug!("upvar should be type")
503-
}
504-
})
478+
self.split().tupled_upvars_ty.expect_ty().tuple_fields()
505479
}
506480

507481
/// Returns the type representing the resume type of the generator.
508482
pub fn resume_ty(self) -> Ty<'tcx> {
509-
self.split().resume_ty
483+
self.split().resume_ty.expect_ty()
510484
}
511485

512486
/// Returns the type representing the yield type of the generator.
513487
pub fn yield_ty(self) -> Ty<'tcx> {
514-
self.split().yield_ty
488+
self.split().yield_ty.expect_ty()
515489
}
516490

517491
/// Returns the type representing the return type of the generator.
518492
pub fn return_ty(self) -> Ty<'tcx> {
519-
self.split().return_ty
493+
self.split().return_ty.expect_ty()
520494
}
521495

522496
/// Returns the "generator signature", which consists of its yield
@@ -645,17 +619,7 @@ impl<'tcx> UpvarSubsts<'tcx> {
645619
UpvarSubsts::Closure(substs) => substs.as_closure().split().tupled_upvars_ty,
646620
UpvarSubsts::Generator(substs) => substs.as_generator().split().tupled_upvars_ty,
647621
};
648-
let upvars = match tupled_upvars_ty.kind {
649-
Tuple(upvars) => upvars,
650-
_ => bug!("upvars should be tupled"),
651-
};
652-
upvars.iter().map(|t| {
653-
if let GenericArgKind::Type(ty) = t.unpack() {
654-
ty
655-
} else {
656-
bug!("upvar should be type")
657-
}
658-
})
622+
tupled_upvars_ty.expect_ty().tuple_fields()
659623
}
660624
}
661625

0 commit comments

Comments
 (0)