Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f85c6de

Browse files
committed
Auto merge of #135783 - compiler-errors:cache-in-closure-binder, r=lcnr
Add cache to `FoldEscapingRegions` Fixes #135780 ty `@lqd` for the tests
2 parents 01a26c0 + d7a6fdc commit f85c6de

File tree

5 files changed

+144
-1
lines changed

5 files changed

+144
-1
lines changed

‎compiler/rustc_type_ir/src/ty_kind/closure.rs‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use std::ops::ControlFlow;
33
use derive_where::derive_where;
44
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
55

6+
use crate::data_structures::DelayedMap;
67
use crate::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region};
78
use crate::inherent::*;
8-
use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
9+
use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt,TypeVisitor};
910
use crate::{self as ty, Interner};
1011

1112
/// A closure can be modeled as a struct that looks like:
@@ -471,6 +472,7 @@ impl<I: Interner> CoroutineClosureSignature<I> {
471472
interner: cx,
472473
region: env_region,
473474
debruijn: ty::INNERMOST,
475+
cache: Default::default(),
474476
});
475477
Ty::new_tup_from_iter(
476478
cx,
@@ -498,13 +500,29 @@ struct FoldEscapingRegions<I: Interner> {
498500
interner: I,
499501
debruijn: ty::DebruijnIndex,
500502
region: I::Region,
503+
504+
// Depends on `debruijn` because we may have types with regions of different
505+
// debruijn depths depending on the binders we've entered.
506+
cache: DelayedMap<(ty::DebruijnIndex, I::Ty), I::Ty>,
501507
}
502508

503509
impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> {
504510
fn cx(&self) -> I {
505511
self.interner
506512
}
507513

514+
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
515+
if !t.has_vars_bound_at_or_above(self.debruijn) {
516+
t
517+
} else if let Some(&t) = self.cache.get(&(self.debruijn, t)) {
518+
t
519+
} else {
520+
let res = t.super_fold_with(self);
521+
assert!(self.cache.insert((self.debruijn, t), res));
522+
res
523+
}
524+
}
525+
508526
fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T>
509527
where
510528
T: TypeFoldable<I>,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ edition: 2021
2+
//@ build-fail
3+
4+
// Regression test for <https://github.com/rust-lang/rust/issues/135780>.
5+
6+
use std::future::Future;
7+
use std::ops::AsyncFn;
8+
use std::pin::Pin;
9+
10+
fn recur<'l>(closure: &'l impl AsyncFn()) -> Pin<Box<dyn Future<Output = ()> + 'l>> {
11+
Box::pin(async move {
12+
let _ = closure();
13+
let _ = recur(&async || {
14+
//~^ ERROR reached the recursion limit
15+
let _ = closure();
16+
});
17+
})
18+
}
19+
20+
fn main() {
21+
let closure = async || {};
22+
let _ = recur(&closure);
23+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error: reached the recursion limit while instantiating `recur::<{async closure@$DIR/post-mono-higher-ranked-hang-2.rs:13:24: 13:32}>`
2+
--> $DIR/post-mono-higher-ranked-hang-2.rs:13:17
3+
|
4+
LL | let _ = recur(&async || {
5+
| _________________^
6+
LL | |
7+
LL | | let _ = closure();
8+
LL | | });
9+
| |__________^
10+
|
11+
note: `recur` defined here
12+
--> $DIR/post-mono-higher-ranked-hang-2.rs:10:1
13+
|
14+
LL | fn recur<'l>(closure: &'l impl AsyncFn()) -> Pin<Box<dyn Future<Output = ()> + 'l>> {
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
17+
error: aborting due to 1 previous error
18+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//@ build-fail
2+
//@ aux-build:block-on.rs
3+
//@ edition:2021
4+
5+
// Regression test for <https://github.com/rust-lang/rust/issues/135780>.
6+
7+
extern crate block_on;
8+
9+
use std::future::Future;
10+
use std::ops::AsyncFnMut;
11+
use std::pin::{Pin, pin};
12+
use std::task::*;
13+
14+
trait Db {}
15+
16+
impl Db for () {}
17+
18+
struct Env<'db> {
19+
db: &'db (),
20+
}
21+
22+
#[derive(Debug)]
23+
enum SymPerm<'db> {
24+
Dummy(&'db ()),
25+
Apply(Box<SymPerm<'db>>, Box<SymPerm<'db>>),
26+
}
27+
28+
pub struct ToChain<'env, 'db> {
29+
db: &'db dyn crate::Db,
30+
env: &'env Env<'db>,
31+
}
32+
33+
impl<'env, 'db> ToChain<'env, 'db> {
34+
fn perm_pairs<'l>(
35+
&'l self,
36+
perm: &'l SymPerm<'db>,
37+
yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>),
38+
) -> Pin<Box<dyn std::future::Future<Output = ()> + 'l>> {
39+
Box::pin(async move {
40+
match perm {
41+
SymPerm::Dummy(_) => yield_chain(perm).await,
42+
SymPerm::Apply(l, r) => {
43+
self.perm_pairs(l, &mut async move |left_pair| {
44+
//~^ ERROR reached the recursion limit while instantiating
45+
self.perm_pairs(r, yield_chain).await
46+
})
47+
.await
48+
}
49+
}
50+
})
51+
}
52+
}
53+
54+
fn main() {
55+
block_on::block_on(async {
56+
let pair = SymPerm::Apply(Box::new(SymPerm::Dummy(&())), Box::new(SymPerm::Dummy(&())));
57+
ToChain { db: &(), env: &Env { db: &() } }
58+
.perm_pairs(&pair, &mut async |p| {
59+
eprintln!("{p:?}");
60+
})
61+
.await;
62+
});
63+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:43:45: 43:67}>`
2+
--> $DIR/post-mono-higher-ranked-hang.rs:43:21
3+
|
4+
LL | / self.perm_pairs(l, &mut async move |left_pair| {
5+
LL | |
6+
LL | | self.perm_pairs(r, yield_chain).await
7+
LL | | })
8+
| |______________________^
9+
|
10+
note: `ToChain::<'env, 'db>::perm_pairs` defined here
11+
--> $DIR/post-mono-higher-ranked-hang.rs:34:5
12+
|
13+
LL | / fn perm_pairs<'l>(
14+
LL | | &'l self,
15+
LL | | perm: &'l SymPerm<'db>,
16+
LL | | yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>),
17+
LL | | ) -> Pin<Box<dyn std::future::Future<Output = ()> + 'l>> {
18+
| |____________________________________________________________^
19+
20+
error: aborting due to 1 previous error
21+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /