Skip to content

Commit 0c36cd3

Browse files
committed
Auto merge of #65293 - tmandry:turbo-expander, r=<try>
Optimize `try_expand_impl_trait_type` A lot of time was being spent expanding some large `impl Future` types in fuchsia. This PR takes the number of types being visited in one expansion from >3 billion to about a thousand, and eliminates the compile time regression in #65147 (in fact, compile times are better than they were before). Thanks to @matthewjasper for suggesting this change. Fixes #65147. r? @matthewjasper,@nikomatsakis
2 parents e413dc3 + 6493e6b commit 0c36cd3

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

src/librustc/ty/util.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,9 @@ impl<'tcx> TyCtxt<'tcx> {
697697
// that type, and when we finish expanding that type we remove the
698698
// its DefId.
699699
seen_opaque_tys: FxHashSet<DefId>,
700+
// Cache of all expansions we've seen so far. This is a critical
701+
// optimization for some large types produced by async fn trees.
702+
expanded_cache: FxHashMap<DefId, Ty<'tcx>>,
700703
primary_def_id: DefId,
701704
found_recursion: bool,
702705
tcx: TyCtxt<'tcx>,
@@ -713,10 +716,17 @@ impl<'tcx> TyCtxt<'tcx> {
713716
}
714717
let substs = substs.fold_with(self);
715718
if self.seen_opaque_tys.insert(def_id) {
716-
let generic_ty = self.tcx.type_of(def_id);
717-
let concrete_ty = generic_ty.subst(self.tcx, substs);
718-
let expanded_ty = self.fold_ty(concrete_ty);
719-
self.seen_opaque_tys.remove(&def_id);
719+
let expanded_ty = match self.expanded_cache.get(&def_id) {
720+
Some(expanded_ty) => expanded_ty,
721+
None => {
722+
let generic_ty = self.tcx.type_of(def_id);
723+
let concrete_ty = generic_ty.subst(self.tcx, substs);
724+
let expanded_ty = self.fold_ty(concrete_ty);
725+
self.seen_opaque_tys.remove(&def_id);
726+
self.expanded_cache.insert(def_id, expanded_ty);
727+
expanded_ty
728+
}
729+
};
720730
Some(expanded_ty)
721731
} else {
722732
// If another opaque type that we contain is recursive, then it
@@ -735,14 +745,17 @@ impl<'tcx> TyCtxt<'tcx> {
735745
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
736746
if let ty::Opaque(def_id, substs) = t.kind {
737747
self.expand_opaque_ty(def_id, substs).unwrap_or(t)
738-
} else {
748+
} else if t.has_projections() {
739749
t.super_fold_with(self)
750+
} else {
751+
t
740752
}
741753
}
742754
}
743755

744756
let mut visitor = OpaqueTypeExpander {
745757
seen_opaque_tys: FxHashSet::default(),
758+
expanded_cache: FxHashMap::default(),
746759
primary_def_id: def_id,
747760
found_recursion: false,
748761
tcx: self,

src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ error[E0720]: opaque type expands to a recursive type
2020
LL | fn recursive_wrap() -> impl Sized {
2121
| ^^^^^^^^^^ expands to a recursive type
2222
|
23-
= note: expanded type is `((impl Sized,),)`
23+
= note: expanded type is `(impl Sized,)`
2424

2525
error[E0720]: opaque type expands to a recursive type
2626
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:21:25
2727
|
2828
LL | fn recursive_wrap2() -> impl Sized {
2929
| ^^^^^^^^^^ expands to a recursive type
3030
|
31-
= note: expanded type is `((impl Sized,),)`
31+
= note: expanded type is `(impl Sized,)`
3232

3333
error: aborting due to 4 previous errors
3434

0 commit comments

Comments
 (0)