Skip to content

Commit bee074f

Browse files
authored
Rollup merge of #69968 - eddyb:tupled-closure-captures, r=nikomatsakis
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 906b399 + d9a15cc commit bee074f

File tree

65 files changed

+356
-367
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

+356
-367
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
@@ -341,7 +341,7 @@ impl<'tcx> Instance<'tcx> {
341341
substs: ty::SubstsRef<'tcx>,
342342
requested_kind: ty::ClosureKind,
343343
) -> Instance<'tcx> {
344-
let actual_kind = substs.as_closure().kind(def_id, tcx);
344+
let actual_kind = substs.as_closure().kind();
345345

346346
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
347347
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
@@ -372,7 +372,7 @@ impl<'tcx> Instance<'tcx> {
372372

373373
let self_ty = tcx.mk_closure(closure_did, substs);
374374

375-
let sig = substs.as_closure().sig(closure_did, tcx);
375+
let sig = substs.as_closure().sig();
376376
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
377377
assert_eq!(sig.inputs().len(), 1);
378378
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
@@ -628,8 +628,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
628628

629629
ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, substs)?,
630630

631-
ty::Closure(def_id, ref substs) => {
632-
let tys = substs.as_closure().upvar_tys(def_id, tcx);
631+
ty::Closure(_, ref substs) => {
632+
let tys = substs.as_closure().upvar_tys();
633633
univariant(
634634
&tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
635635
&ReprOptions::default(),
@@ -1402,7 +1402,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
14021402
// Build a prefix layout, including "promoting" all ineligible
14031403
// locals as part of the prefix. We compute the layout of all of
14041404
// these fields at once to get optimal packing.
1405-
let discr_index = substs.as_generator().prefix_tys(def_id, tcx).count();
1405+
let discr_index = substs.as_generator().prefix_tys().count();
14061406

14071407
// `info.variant_fields` already accounts for the reserved variants, so no need to add them.
14081408
let max_discr = (info.variant_fields.len() - 1) as u128;
@@ -1419,7 +1419,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
14191419
.map(|ty| self.layout_of(ty));
14201420
let prefix_layouts = substs
14211421
.as_generator()
1422-
.prefix_tys(def_id, tcx)
1422+
.prefix_tys()
14231423
.map(|ty| self.layout_of(ty))
14241424
.chain(iter::once(Ok(discr_layout)))
14251425
.chain(promoted_layouts)
@@ -2095,9 +2095,7 @@ where
20952095
ty::Str => tcx.types.u8,
20962096

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

21022100
ty::Generator(def_id, ref substs, _) => match this.variants {
21032101
Variants::Single { index } => substs
@@ -2111,7 +2109,7 @@ where
21112109
if i == discr_index {
21122110
return discr_layout(discr);
21132111
}
2114-
substs.as_generator().prefix_tys(def_id, tcx).nth(i).unwrap()
2112+
substs.as_generator().prefix_tys().nth(i).unwrap()
21152113
}
21162114
},
21172115

@@ -2298,7 +2296,7 @@ impl<'tcx> ty::Instance<'tcx> {
22982296
sig
22992297
}
23002298
ty::Closure(def_id, substs) => {
2301-
let sig = substs.as_closure().sig(def_id, tcx);
2299+
let sig = substs.as_closure().sig();
23022300

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

23152313
let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
23162314
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

+57-30
Original file line numberDiff line numberDiff line change
@@ -617,8 +617,6 @@ pub trait PrettyPrinter<'tcx>:
617617
}
618618
ty::Str => p!(write("str")),
619619
ty::Generator(did, substs, movability) => {
620-
let upvar_tys = substs.as_generator().upvar_tys(did, self.tcx());
621-
let witness = substs.as_generator().witness(did, self.tcx());
622620
match movability {
623621
hir::Movability::Movable => p!(write("[generator")),
624622
hir::Movability::Static => p!(write("[static generator")),
@@ -627,31 +625,47 @@ pub trait PrettyPrinter<'tcx>:
627625
// FIXME(eddyb) should use `def_span`.
628626
if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
629627
p!(write("@{:?}", self.tcx().hir().span(hir_id)));
630-
let mut sep = " ";
631-
for (&var_id, upvar_ty) in
632-
self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys)
633-
{
634-
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
635-
sep = ", ";
628+
629+
if substs.as_generator().is_valid() {
630+
let upvar_tys = substs.as_generator().upvar_tys();
631+
let mut sep = " ";
632+
for (&var_id, upvar_ty) in self
633+
.tcx()
634+
.upvars(did)
635+
.as_ref()
636+
.iter()
637+
.flat_map(|v| v.keys())
638+
.zip(upvar_tys)
639+
{
640+
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
641+
sep = ", ";
642+
}
636643
}
637644
} else {
638645
// Cross-crate closure types should only be
639646
// visible in codegen bug reports, I imagine.
640647
p!(write("@{:?}", did));
641-
let mut sep = " ";
642-
for (index, upvar_ty) in upvar_tys.enumerate() {
643-
p!(write("{}{}:", sep, index), print(upvar_ty));
644-
sep = ", ";
648+
649+
if substs.as_generator().is_valid() {
650+
let upvar_tys = substs.as_generator().upvar_tys();
651+
let mut sep = " ";
652+
for (index, upvar_ty) in upvar_tys.enumerate() {
653+
p!(write("{}{}:", sep, index), print(upvar_ty));
654+
sep = ", ";
655+
}
645656
}
646657
}
647658

648-
p!(write(" "), print(witness), write("]"))
659+
if substs.as_generator().is_valid() {
660+
p!(write(" "), print(substs.as_generator().witness()));
661+
}
662+
663+
p!(write("]"))
649664
}
650665
ty::GeneratorWitness(types) => {
651666
p!(in_binder(&types));
652667
}
653668
ty::Closure(did, substs) => {
654-
let upvar_tys = substs.as_closure().upvar_tys(did, self.tcx());
655669
p!(write("[closure"));
656670

657671
// FIXME(eddyb) should use `def_span`.
@@ -661,30 +675,43 @@ pub trait PrettyPrinter<'tcx>:
661675
} else {
662676
p!(write("@{:?}", self.tcx().hir().span(hir_id)));
663677
}
664-
let mut sep = " ";
665-
for (&var_id, upvar_ty) in
666-
self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys)
667-
{
668-
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
669-
sep = ", ";
678+
679+
if substs.as_closure().is_valid() {
680+
let upvar_tys = substs.as_closure().upvar_tys();
681+
let mut sep = " ";
682+
for (&var_id, upvar_ty) in self
683+
.tcx()
684+
.upvars(did)
685+
.as_ref()
686+
.iter()
687+
.flat_map(|v| v.keys())
688+
.zip(upvar_tys)
689+
{
690+
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
691+
sep = ", ";
692+
}
670693
}
671694
} else {
672695
// Cross-crate closure types should only be
673696
// visible in codegen bug reports, I imagine.
674697
p!(write("@{:?}", did));
675-
let mut sep = " ";
676-
for (index, upvar_ty) in upvar_tys.enumerate() {
677-
p!(write("{}{}:", sep, index), print(upvar_ty));
678-
sep = ", ";
698+
699+
if substs.as_closure().is_valid() {
700+
let upvar_tys = substs.as_closure().upvar_tys();
701+
let mut sep = " ";
702+
for (index, upvar_ty) in upvar_tys.enumerate() {
703+
p!(write("{}{}:", sep, index), print(upvar_ty));
704+
sep = ", ";
705+
}
679706
}
680707
}
681708

682-
if self.tcx().sess.verbose() {
683-
p!(write(
684-
" closure_kind_ty={:?} closure_sig_as_fn_ptr_ty={:?}",
685-
substs.as_closure().kind_ty(did, self.tcx()),
686-
substs.as_closure().sig_as_fn_ptr_ty(did, self.tcx())
687-
));
709+
if self.tcx().sess.verbose() && substs.as_closure().is_valid() {
710+
p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
711+
p!(
712+
write(" closure_sig_as_fn_ptr_ty="),
713+
print(substs.as_closure().sig_as_fn_ptr_ty())
714+
);
688715
}
689716

690717
p!(write("]"))

0 commit comments

Comments
 (0)