Skip to content

Commit 3128b8f

Browse files
committed
Enable MIR inlining on generators.
1 parent 0369ff2 commit 3128b8f

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

compiler/rustc_mir_transform/src/inline.rs

-6
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,6 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
7979
if body.source.promoted.is_some() {
8080
return false;
8181
}
82-
// Avoid inlining into generators, since their `optimized_mir` is used for layout computation,
83-
// which can create a cycle, even when no attempt is made to inline the function in the other
84-
// direction.
85-
if tcx.generator_kind(def_id).is_some() {
86-
return false;
87-
}
8882

8983
let param_env = tcx.param_env_reveal_all_normalized(def_id);
9084

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Checks that inliner doesn't introduce cycles when optimizing generators.
2-
// The outcome of optimization is not verfied, just the absence of the cycle.
32
// Regression test for #76181.
43
//
54
// edition:2018
@@ -8,11 +7,13 @@
87

98
pub struct S;
109

11-
impl S {
12-
pub async fn g(&mut self) {
13-
self.h();
14-
}
15-
pub fn h(&mut self) {
16-
let _ = self.g();
17-
}
10+
// EMIT_MIR inline_async.g.Inline.diff
11+
pub async fn g(s: &mut S) {
12+
h(s);
13+
}
14+
15+
// EMIT_MIR inline_async.h.Inline.diff
16+
#[inline(always)]
17+
pub fn h(s: &mut S) {
18+
let _ = g(s);
1819
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
- // MIR for `g` before Inline
2+
+ // MIR for `g` after Inline
3+
4+
fn g(_1: &mut S) -> std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]> {
5+
debug s => _1; // in scope 0 at $DIR/inline-async.rs:+0:16: +0:17
6+
let mut _0: std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]>; // return place in scope 0 at $DIR/inline-async.rs:+0:27: +0:27
7+
let mut _2: [static generator@$DIR/inline-async.rs:11:27: 13:2]; // in scope 0 at $DIR/inline-async.rs:+0:27: +2:2
8+
+ scope 1 (inlined std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>) { // at $DIR/inline-async.rs:11:27: 13:2
9+
+ debug gen => _2; // in scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
10+
+ let mut _3: [static generator@$DIR/inline-async.rs:11:27: 13:2]; // in scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
11+
+ }
12+
13+
bb0: {
14+
StorageLive(_2); // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
15+
Deinit(_2); // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
16+
(_2.0: &mut S) = move _1; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
17+
discriminant(_2) = 0; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
18+
- _0 = std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>(move _2) -> bb1; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
19+
- // mir::Constant
20+
- // + span: $DIR/inline-async.rs:11:27: 13:2
21+
- // + literal: Const { ty: fn([static generator@$DIR/inline-async.rs:11:27: 13:2]) -> impl Future<Output = ()> {std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>}, val: Value(<ZST>) }
22+
- }
23+
-
24+
- bb1: {
25+
+ StorageLive(_3); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
26+
+ _3 = move _2; // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
27+
+ Deinit(_0); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
28+
+ (_0.0: [static generator@$DIR/inline-async.rs:11:27: 13:2]) = move _3; // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
29+
+ StorageDead(_3); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
30+
StorageDead(_2); // scope 0 at $DIR/inline-async.rs:+2:1: +2:2
31+
return; // scope 0 at $DIR/inline-async.rs:+2:2: +2:2
32+
}
33+
}
34+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
- // MIR for `h` before Inline
2+
+ // MIR for `h` after Inline
3+
4+
fn h(_1: &mut S) -> () {
5+
debug s => _1; // in scope 0 at $DIR/inline-async.rs:+0:10: +0:11
6+
let mut _0: (); // return place in scope 0 at $DIR/inline-async.rs:+0:21: +0:21
7+
let mut _2: std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]>; // in scope 0 at $DIR/inline-async.rs:+1:13: +1:17
8+
let mut _3: &mut S; // in scope 0 at $DIR/inline-async.rs:+1:15: +1:16
9+
scope 1 {
10+
}
11+
12+
bb0: {
13+
StorageLive(_2); // scope 0 at $DIR/inline-async.rs:+1:13: +1:17
14+
StorageLive(_3); // scope 0 at $DIR/inline-async.rs:+1:15: +1:16
15+
_3 = &mut (*_1); // scope 0 at $DIR/inline-async.rs:+1:15: +1:16
16+
_2 = g(move _3) -> bb1; // scope 0 at $DIR/inline-async.rs:+1:13: +1:17
17+
// mir::Constant
18+
// + span: $DIR/inline-async.rs:18:13: 18:14
19+
// + literal: Const { ty: for<'r> fn(&'r mut S) -> impl for<'r> Future<Output = ()> {g}, val: Value(<ZST>) }
20+
}
21+
22+
bb1: {
23+
StorageDead(_3); // scope 0 at $DIR/inline-async.rs:+1:16: +1:17
24+
StorageDead(_2); // scope 0 at $DIR/inline-async.rs:+1:17: +1:18
25+
_0 = const (); // scope 0 at $DIR/inline-async.rs:+0:21: +2:2
26+
return; // scope 0 at $DIR/inline-async.rs:+2:2: +2:2
27+
}
28+
}
29+

0 commit comments

Comments
 (0)