Skip to content

Commit 6429062

Browse files
committed
Auto merge of #69968 - eddyb:tupled-closure-captures, r=<try>
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
2 parents 54b7d21 + da30907 commit 6429062

File tree

65 files changed

+335
-324
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+335
-324
lines changed

src/librustc/traits/query.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
229229
// (T1..Tn) and closures have same properties as T1..Tn --
230230
// check if *any* of those are trivial.
231231
ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())),
232-
ty::Closure(def_id, ref substs) => {
233-
substs.as_closure().upvar_tys(def_id, tcx).all(|t| trivial_dropck_outlives(tcx, t))
232+
ty::Closure(_, ref substs) => {
233+
substs.as_closure().upvar_tys().all(|t| trivial_dropck_outlives(tcx, t))
234234
}
235235

236236
ty::Adt(def, _) => {

src/librustc/ty/instance.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl<'tcx> Instance<'tcx> {
329329
substs: ty::SubstsRef<'tcx>,
330330
requested_kind: ty::ClosureKind,
331331
) -> Instance<'tcx> {
332-
let actual_kind = substs.as_closure().kind(def_id, tcx);
332+
let actual_kind = substs.as_closure().kind();
333333

334334
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
335335
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
@@ -360,7 +360,7 @@ impl<'tcx> Instance<'tcx> {
360360

361361
let self_ty = tcx.mk_closure(closure_did, substs);
362362

363-
let sig = substs.as_closure().sig(closure_did, tcx);
363+
let sig = substs.as_closure().sig();
364364
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
365365
assert_eq!(sig.inputs().len(), 1);
366366
let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);

src/librustc/ty/layout.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
634634

635635
ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, substs)?,
636636

637-
ty::Closure(def_id, ref substs) => {
638-
let tys = substs.as_closure().upvar_tys(def_id, tcx);
637+
ty::Closure(_, ref substs) => {
638+
let tys = substs.as_closure().upvar_tys();
639639
univariant(
640640
&tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
641641
&ReprOptions::default(),
@@ -1408,7 +1408,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
14081408
// Build a prefix layout, including "promoting" all ineligible
14091409
// locals as part of the prefix. We compute the layout of all of
14101410
// these fields at once to get optimal packing.
1411-
let discr_index = substs.as_generator().prefix_tys(def_id, tcx).count();
1411+
let discr_index = substs.as_generator().prefix_tys().count();
14121412
// FIXME(eddyb) set the correct vaidity range for the discriminant.
14131413
let discr_layout = self.layout_of(substs.as_generator().discr_ty(tcx))?;
14141414
let discr = match &discr_layout.abi {
@@ -1422,7 +1422,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
14221422
.map(|ty| self.layout_of(ty));
14231423
let prefix_layouts = substs
14241424
.as_generator()
1425-
.prefix_tys(def_id, tcx)
1425+
.prefix_tys()
14261426
.map(|ty| self.layout_of(ty))
14271427
.chain(iter::once(Ok(discr_layout)))
14281428
.chain(promoted_layouts)
@@ -2094,9 +2094,7 @@ where
20942094
ty::Str => tcx.types.u8,
20952095

20962096
// Tuples, generators and closures.
2097-
ty::Closure(def_id, ref substs) => {
2098-
substs.as_closure().upvar_tys(def_id, tcx).nth(i).unwrap()
2099-
}
2097+
ty::Closure(_, ref substs) => substs.as_closure().upvar_tys().nth(i).unwrap(),
21002098

21012099
ty::Generator(def_id, ref substs, _) => match this.variants {
21022100
Variants::Single { index } => substs
@@ -2110,7 +2108,7 @@ where
21102108
if i == discr_index {
21112109
return discr_layout(discr);
21122110
}
2113-
substs.as_generator().prefix_tys(def_id, tcx).nth(i).unwrap()
2111+
substs.as_generator().prefix_tys().nth(i).unwrap()
21142112
}
21152113
},
21162114

@@ -2297,7 +2295,7 @@ impl<'tcx> ty::Instance<'tcx> {
22972295
sig
22982296
}
22992297
ty::Closure(def_id, substs) => {
2300-
let sig = substs.as_closure().sig(def_id, tcx);
2298+
let sig = substs.as_closure().sig();
23012299

23022300
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
23032301
sig.map_bound(|sig| tcx.mk_fn_sig(
@@ -2308,8 +2306,8 @@ impl<'tcx> ty::Instance<'tcx> {
23082306
sig.abi
23092307
))
23102308
}
2311-
ty::Generator(def_id, substs, _) => {
2312-
let sig = substs.as_generator().poly_sig(def_id, tcx);
2309+
ty::Generator(_, substs, _) => {
2310+
let sig = substs.as_generator().poly_sig();
23132311

23142312
let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
23152313
let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);

src/librustc/ty/outlives.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
6161
// in the `subtys` iterator (e.g., when encountering a
6262
// projection).
6363
match ty.kind {
64-
ty::Closure(def_id, ref substs) => {
65-
for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) {
64+
ty::Closure(_, ref substs) => {
65+
for upvar_ty in substs.as_closure().upvar_tys() {
6666
compute_components(tcx, upvar_ty, out);
6767
}
6868
}
6969

70-
ty::Generator(def_id, ref substs, _) => {
70+
ty::Generator(_, ref substs, _) => {
7171
// Same as the closure case
72-
for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) {
72+
for upvar_ty in substs.as_generator().upvar_tys() {
7373
compute_components(tcx, upvar_ty, out);
7474
}
7575

src/librustc/ty/print/pretty.rs

+60-28
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,8 @@ pub trait PrettyPrinter<'tcx>:
608608
}
609609
ty::Str => p!(write("str")),
610610
ty::Generator(did, substs, movability) => {
611-
let upvar_tys = substs.as_generator().upvar_tys(did, self.tcx());
612-
let witness = substs.as_generator().witness(did, self.tcx());
611+
let tupled_upvars_ty = substs.as_generator().tupled_upvars_ty();
612+
let witness = substs.as_generator().witness();
613613
match movability {
614614
hir::Movability::Movable => p!(write("[generator")),
615615
hir::Movability::Static => p!(write("[static generator")),
@@ -618,21 +618,40 @@ pub trait PrettyPrinter<'tcx>:
618618
// FIXME(eddyb) should use `def_span`.
619619
if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
620620
p!(write("@{:?}", self.tcx().hir().span(hir_id)));
621-
let mut sep = " ";
622-
for (&var_id, upvar_ty) in
623-
self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys)
624-
{
625-
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
626-
sep = ", ";
621+
622+
// Only print upvars if they're known (i.e. not infer var or param).
623+
if let ty::Tuple(upvar_tys) = tupled_upvars_ty.kind {
624+
let mut sep = " ";
625+
for (&var_id, upvar_ty) in self
626+
.tcx()
627+
.upvars(did)
628+
.as_ref()
629+
.iter()
630+
.flat_map(|v| v.keys())
631+
.zip(upvar_tys)
632+
{
633+
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
634+
sep = ", ";
635+
}
627636
}
628637
} else {
629638
// Cross-crate closure types should only be
630639
// visible in codegen bug reports, I imagine.
631640
p!(write("@{:?}", did));
632-
let mut sep = " ";
633-
for (index, upvar_ty) in upvar_tys.enumerate() {
634-
p!(write("{}{}:", sep, index), print(upvar_ty));
635-
sep = ", ";
641+
642+
// Only print upvars if they're known (i.e. not infer var or param).
643+
if let ty::Tuple(upvar_tys) = tupled_upvars_ty.kind {
644+
let mut sep = " ";
645+
for (index, upvar_ty) in upvar_tys.iter().enumerate() {
646+
p!(write("{}{}:", sep, index), print(upvar_ty));
647+
sep = ", ";
648+
}
649+
}
650+
}
651+
652+
if self.tcx().sess.verbose() {
653+
if !matches!(tupled_upvars_ty.kind, ty::Tuple(_)) {
654+
p!(write(" tupled_upvars_ty="), print(tupled_upvars_ty));
636655
}
637656
}
638657

@@ -642,7 +661,7 @@ pub trait PrettyPrinter<'tcx>:
642661
p!(in_binder(&types));
643662
}
644663
ty::Closure(did, substs) => {
645-
let upvar_tys = substs.as_closure().upvar_tys(did, self.tcx());
664+
let tupled_upvars_ty = substs.as_closure().tupled_upvars_ty();
646665
p!(write("[closure"));
647666

648667
// FIXME(eddyb) should use `def_span`.
@@ -652,30 +671,43 @@ pub trait PrettyPrinter<'tcx>:
652671
} else {
653672
p!(write("@{:?}", self.tcx().hir().span(hir_id)));
654673
}
655-
let mut sep = " ";
656-
for (&var_id, upvar_ty) in
657-
self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys)
658-
{
659-
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
660-
sep = ", ";
674+
675+
// Only print upvars if they're known (i.e. not infer var or param).
676+
if let ty::Tuple(upvar_tys) = tupled_upvars_ty.kind {
677+
let mut sep = " ";
678+
for (&var_id, upvar_ty) in self
679+
.tcx()
680+
.upvars(did)
681+
.as_ref()
682+
.iter()
683+
.flat_map(|v| v.keys())
684+
.zip(upvar_tys)
685+
{
686+
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
687+
sep = ", ";
688+
}
661689
}
662690
} else {
663691
// Cross-crate closure types should only be
664692
// visible in codegen bug reports, I imagine.
665693
p!(write("@{:?}", did));
666-
let mut sep = " ";
667-
for (index, upvar_ty) in upvar_tys.enumerate() {
668-
p!(write("{}{}:", sep, index), print(upvar_ty));
669-
sep = ", ";
694+
695+
// Only print upvars if they're known (i.e. not infer var or param).
696+
if let ty::Tuple(upvar_tys) = tupled_upvars_ty.kind {
697+
let mut sep = " ";
698+
for (index, upvar_ty) in upvar_tys.iter().enumerate() {
699+
p!(write("{}{}:", sep, index), print(upvar_ty));
700+
sep = ", ";
701+
}
670702
}
671703
}
672704

673705
if self.tcx().sess.verbose() {
674-
p!(write(
675-
" closure_kind_ty={:?} closure_sig_ty={:?}",
676-
substs.as_closure().kind_ty(did, self.tcx()),
677-
substs.as_closure().sig_ty(did, self.tcx())
678-
));
706+
p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
707+
p!(write(" closure_sig_ty="), print(substs.as_closure().sig_ty()));
708+
if !matches!(tupled_upvars_ty.kind, ty::Tuple(_)) {
709+
p!(write(" tupled_upvars_ty="), print(tupled_upvars_ty));
710+
}
679711
}
680712

681713
p!(write("]"))

0 commit comments

Comments
 (0)