Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f8f376e

Browse files
committedMar 3, 2025·
Inline FnOnce once again
1 parent 42323e3 commit f8f376e

23 files changed

+382
-116
lines changed
 

‎compiler/rustc_mir_transform/src/inline.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -625,13 +625,6 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
625625
return Err("implementation limitation -- return type mismatch");
626626
}
627627
if callsite.fn_sig.abi() == ExternAbi::RustCall {
628-
// FIXME: Don't inline user-written `extern "rust-call"` functions,
629-
// since this is generally perf-negative on rustc, and we hope that
630-
// LLVM will inline these functions instead.
631-
if callee_body.spread_arg.is_some() {
632-
return Err("user-written rust-call functions");
633-
}
634-
635628
let (self_arg, arg_tuple) = match &args[..] {
636629
[arg_tuple] => (None, arg_tuple),
637630
[self_arg, arg_tuple] => (Some(self_arg), arg_tuple),
@@ -641,18 +634,23 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
641634
let self_arg_ty = self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, tcx));
642635

643636
let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, tcx);
644-
let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
645-
bug!("Closure arguments are not passed as a tuple");
637+
let arg_tys = if callee_body.spread_arg.is_some() {
638+
std::slice::from_ref(&arg_tuple_ty)
639+
} else {
640+
let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
641+
bug!("Closure arguments are not passed as a tuple");
642+
};
643+
arg_tuple_tys.as_slice()
646644
};
647645

648646
for (arg_ty, input) in
649-
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
647+
self_arg_ty.into_iter().chain(arg_tys.iter().copied()).zip(callee_body.args_iter())
650648
{
651649
let input_type = callee_body.local_decls[input].ty;
652650
if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) {
653651
trace!(?arg_ty, ?input_type);
654652
debug!("failed to normalize tuple argument type");
655-
return Err("implementation limitation -- arg mismatch");
653+
return Err("implementation limitation");
656654
}
657655
}
658656
} else {
@@ -1059,8 +1057,7 @@ fn make_call_args<'tcx, I: Inliner<'tcx>>(
10591057

10601058
closure_ref_arg.chain(tuple_tmp_args).collect()
10611059
} else {
1062-
// FIXME(edition_2024): switch back to a normal method call.
1063-
<_>::into_iter(args)
1060+
args.into_iter()
10641061
.map(|a| create_temp_if_necessary(inliner, a.node, callsite, caller_body, return_block))
10651062
.collect()
10661063
}

‎tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,42 @@
77
let mut _0: ();
88
let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
99
let mut _4: I;
10+
+ scope 1 (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut) {
11+
+ let mut _5: &mut dyn std::ops::FnMut<I, Output = ()>;
12+
+ let mut _6: std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
13+
+ let mut _7: *const dyn std::ops::FnMut<I, Output = ()>;
14+
+ }
1015

1116
bb0: {
1217
StorageLive(_3);
1318
_3 = &mut _1;
1419
StorageLive(_4);
1520
_4 = move _2;
16-
_0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable];
21+
- _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable];
22+
+ StorageLive(_6);
23+
+ StorageLive(_7);
24+
+ StorageLive(_5);
25+
+ _6 = copy (*_3);
26+
+ _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::FnMut<I, Output = ()>>).0: std::ptr::NonNull<dyn std::ops::FnMut<I, Output = ()>>) as *const dyn std::ops::FnMut<I, Output = ()> (Transmute);
27+
+ _5 = &mut (*_7);
28+
+ _0 = <dyn FnMut<I, Output = ()> as FnMut<I>>::call_mut(move _5, move _4) -> [return: bb2, unwind unreachable];
1729
}
1830

1931
bb1: {
20-
StorageDead(_4);
21-
StorageDead(_3);
22-
drop(_1) -> [return: bb2, unwind unreachable];
32+
- StorageDead(_4);
33+
- StorageDead(_3);
34+
- drop(_1) -> [return: bb2, unwind unreachable];
35+
+ return;
2336
}
2437

2538
bb2: {
26-
return;
39+
- return;
40+
+ StorageDead(_5);
41+
+ StorageDead(_7);
42+
+ StorageDead(_6);
43+
+ StorageDead(_4);
44+
+ StorageDead(_3);
45+
+ drop(_1) -> [return: bb1, unwind unreachable];
2746
}
2847
}
2948

‎tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,54 @@
77
let mut _0: ();
88
let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
99
let mut _4: I;
10+
+ scope 1 (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut) {
11+
+ let mut _5: &mut dyn std::ops::FnMut<I, Output = ()>;
12+
+ let mut _6: std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
13+
+ let mut _7: *const dyn std::ops::FnMut<I, Output = ()>;
14+
+ }
1015

1116
bb0: {
1217
StorageLive(_3);
1318
_3 = &mut _1;
1419
StorageLive(_4);
1520
_4 = move _2;
16-
_0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3];
21+
- _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3];
22+
+ StorageLive(_6);
23+
+ StorageLive(_7);
24+
+ StorageLive(_5);
25+
+ _6 = copy (*_3);
26+
+ _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::FnMut<I, Output = ()>>).0: std::ptr::NonNull<dyn std::ops::FnMut<I, Output = ()>>) as *const dyn std::ops::FnMut<I, Output = ()> (Transmute);
27+
+ _5 = &mut (*_7);
28+
+ _0 = <dyn FnMut<I, Output = ()> as FnMut<I>>::call_mut(move _5, move _4) -> [return: bb4, unwind: bb2];
1729
}
1830

1931
bb1: {
20-
StorageDead(_4);
21-
StorageDead(_3);
22-
drop(_1) -> [return: bb2, unwind: bb4];
32+
- StorageDead(_4);
33+
- StorageDead(_3);
34+
- drop(_1) -> [return: bb2, unwind: bb4];
35+
+ return;
2336
}
2437

25-
bb2: {
26-
return;
38+
- bb2: {
39+
- return;
40+
+ bb2 (cleanup): {
41+
+ drop(_1) -> [return: bb3, unwind terminate(cleanup)];
2742
}
2843

2944
bb3 (cleanup): {
30-
drop(_1) -> [return: bb4, unwind terminate(cleanup)];
45+
- drop(_1) -> [return: bb4, unwind terminate(cleanup)];
46+
+ resume;
3147
}
3248

33-
bb4 (cleanup): {
34-
resume;
49+
- bb4 (cleanup): {
50+
- resume;
51+
+ bb4: {
52+
+ StorageDead(_5);
53+
+ StorageDead(_7);
54+
+ StorageDead(_6);
55+
+ StorageDead(_4);
56+
+ StorageDead(_3);
57+
+ drop(_1) -> [return: bb1, unwind: bb3];
3558
}
3659
}
3760

‎tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ use std::marker::Tuple;
88
// EMIT_MIR dont_ice_on_generic_rust_call.call.Inline.diff
99
pub fn call<I: Tuple>(mut mock: Box<dyn FnMut<I, Output = ()>>, input: I) {
1010
// CHECK-LABEL: fn call(
11-
// CHECK-NOT: inlined
11+
// CHECK: (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut)
1212
mock.call_mut(input)
1313
}

‎tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,46 @@
77
let _2: ();
88
let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>;
99
let mut _4: (i32,);
10+
+ scope 1 (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call) {
11+
+ let mut _5: &dyn std::ops::Fn(i32);
12+
+ let mut _6: std::boxed::Box<dyn std::ops::Fn(i32)>;
13+
+ let mut _7: *const dyn std::ops::Fn(i32);
14+
+ }
1015

1116
bb0: {
1217
StorageLive(_2);
1318
StorageLive(_3);
1419
_3 = &_1;
1520
StorageLive(_4);
1621
_4 = (const 1_i32,);
17-
_2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable];
22+
- _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable];
23+
+ StorageLive(_6);
24+
+ StorageLive(_7);
25+
+ StorageLive(_5);
26+
+ _6 = copy (*_3);
27+
+ _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::Fn(i32)>).0: std::ptr::NonNull<dyn std::ops::Fn(i32)>) as *const dyn std::ops::Fn(i32) (Transmute);
28+
+ _5 = &(*_7);
29+
+ _2 = <dyn Fn(i32) as Fn<(i32,)>>::call(move _5, move _4) -> [return: bb2, unwind unreachable];
1830
}
1931

2032
bb1: {
33+
+ return;
34+
+ }
35+
+
36+
+ bb2: {
37+
+ StorageDead(_5);
38+
+ StorageDead(_7);
39+
+ StorageDead(_6);
2140
StorageDead(_4);
2241
StorageDead(_3);
2342
StorageDead(_2);
2443
_0 = const ();
25-
drop(_1) -> [return: bb2, unwind unreachable];
26-
}
27-
28-
bb2: {
29-
return;
44+
- drop(_1) -> [return: bb2, unwind unreachable];
45+
- }
46+
-
47+
- bb2: {
48+
- return;
49+
+ drop(_1) -> [return: bb1, unwind unreachable];
3050
}
3151
}
3252

‎tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,59 @@
77
let _2: ();
88
let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>;
99
let mut _4: (i32,);
10+
+ scope 1 (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call) {
11+
+ let mut _5: &dyn std::ops::Fn(i32);
12+
+ let mut _6: std::boxed::Box<dyn std::ops::Fn(i32)>;
13+
+ let mut _7: *const dyn std::ops::Fn(i32);
14+
+ }
1015

1116
bb0: {
1217
StorageLive(_2);
1318
StorageLive(_3);
1419
_3 = &_1;
1520
StorageLive(_4);
1621
_4 = (const 1_i32,);
17-
_2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3];
22+
- _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3];
23+
+ StorageLive(_6);
24+
+ StorageLive(_7);
25+
+ StorageLive(_5);
26+
+ _6 = copy (*_3);
27+
+ _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::Fn(i32)>).0: std::ptr::NonNull<dyn std::ops::Fn(i32)>) as *const dyn std::ops::Fn(i32) (Transmute);
28+
+ _5 = &(*_7);
29+
+ _2 = <dyn Fn(i32) as Fn<(i32,)>>::call(move _5, move _4) -> [return: bb4, unwind: bb2];
1830
}
1931

2032
bb1: {
21-
StorageDead(_4);
22-
StorageDead(_3);
23-
StorageDead(_2);
24-
_0 = const ();
25-
drop(_1) -> [return: bb2, unwind: bb4];
33+
- StorageDead(_4);
34+
- StorageDead(_3);
35+
- StorageDead(_2);
36+
- _0 = const ();
37+
- drop(_1) -> [return: bb2, unwind: bb4];
38+
+ return;
2639
}
2740

28-
bb2: {
29-
return;
41+
- bb2: {
42+
- return;
43+
+ bb2 (cleanup): {
44+
+ drop(_1) -> [return: bb3, unwind terminate(cleanup)];
3045
}
3146

3247
bb3 (cleanup): {
33-
drop(_1) -> [return: bb4, unwind terminate(cleanup)];
48+
- drop(_1) -> [return: bb4, unwind terminate(cleanup)];
49+
+ resume;
3450
}
3551

36-
bb4 (cleanup): {
37-
resume;
52+
- bb4 (cleanup): {
53+
- resume;
54+
+ bb4: {
55+
+ StorageDead(_5);
56+
+ StorageDead(_7);
57+
+ StorageDead(_6);
58+
+ StorageDead(_4);
59+
+ StorageDead(_3);
60+
+ StorageDead(_2);
61+
+ _0 = const ();
62+
+ drop(_1) -> [return: bb1, unwind: bb3];
3863
}
3964
}
4065

‎tests/mir-opt/inline/inline_box_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
// EMIT_MIR inline_box_fn.call.Inline.diff
66
fn call(x: Box<dyn Fn(i32)>) {
77
// CHECK-LABEL: fn call(
8-
// CHECK-NOT: inlined
8+
// CHECK: (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call)
99
x(1);
1010
}

‎tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
let mut _0: ();
66
let _1: ();
77
+ let mut _2: fn() {f};
8+
+ let mut _4: ();
89
+ scope 1 (inlined call::<fn() {f}>) {
910
+ debug f => _2;
1011
+ let _3: ();
12+
+ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
13+
+ scope 3 (inlined f) {
14+
+ let _5: ();
15+
+ }
16+
+ }
1117
+ }
1218

1319
bb0: {
@@ -16,10 +22,15 @@
1622
+ StorageLive(_2);
1723
+ _2 = f;
1824
+ StorageLive(_3);
19-
+ _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind unreachable];
25+
+ StorageLive(_4);
26+
+ _4 = const ();
27+
+ StorageLive(_5);
28+
+ _5 = call::<fn() {f}>(f) -> [return: bb1, unwind unreachable];
2029
}
2130

2231
bb1: {
32+
+ StorageDead(_5);
33+
+ StorageDead(_4);
2334
+ StorageDead(_3);
2435
+ StorageDead(_2);
2536
StorageDead(_1);

‎tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
let mut _0: ();
66
let _1: ();
77
+ let mut _2: fn() {f};
8+
+ let mut _4: ();
89
+ scope 1 (inlined call::<fn() {f}>) {
910
+ debug f => _2;
1011
+ let _3: ();
12+
+ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
13+
+ scope 3 (inlined f) {
14+
+ let _5: ();
15+
+ }
16+
+ }
1117
+ }
1218

1319
bb0: {
@@ -16,10 +22,15 @@
1622
+ StorageLive(_2);
1723
+ _2 = f;
1824
+ StorageLive(_3);
19-
+ _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind continue];
25+
+ StorageLive(_4);
26+
+ _4 = const ();
27+
+ StorageLive(_5);
28+
+ _5 = call::<fn() {f}>(f) -> [return: bb1, unwind continue];
2029
}
2130

2231
bb1: {
32+
+ StorageDead(_5);
33+
+ StorageDead(_4);
2334
+ StorageDead(_3);
2435
+ StorageDead(_2);
2536
StorageDead(_1);

‎tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
let mut _0: ();
66
let _1: (!, !);
77
+ let mut _2: fn() -> ! {sleep};
8+
+ let mut _7: ();
89
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
910
+ debug f => _2;
1011
+ let mut _3: &fn() -> ! {sleep};
@@ -17,6 +18,10 @@
1718
+ debug b => _6;
1819
+ }
1920
+ }
21+
+ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
22+
+ scope 5 (inlined sleep) {
23+
+ }
24+
+ }
2025
+ }
2126

2227
bb0: {
@@ -28,24 +33,13 @@
2833
+ StorageLive(_6);
2934
+ StorageLive(_3);
3035
+ _3 = &_2;
31-
+ _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind unreachable];
36+
+ StorageLive(_7);
37+
+ _7 = const ();
38+
+ goto -> bb1;
3239
+ }
3340
+
3441
+ bb1: {
35-
+ StorageDead(_3);
36-
+ StorageLive(_5);
37-
+ _5 = &_2;
38-
+ _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind unreachable];
39-
+ }
40-
+
41-
+ bb2: {
42-
+ StorageDead(_5);
43-
+ _1 = (copy _4, copy _6);
44-
+ drop(_2) -> [return: bb3, unwind unreachable];
45-
+ }
46-
+
47-
+ bb3: {
48-
+ unreachable;
42+
+ goto -> bb1;
4943
}
5044
}
5145

‎tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
let mut _0: ();
66
let _1: (!, !);
77
+ let mut _2: fn() -> ! {sleep};
8+
+ let mut _8: ();
89
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
910
+ debug f => _2;
1011
+ let mut _3: &fn() -> ! {sleep};
@@ -18,6 +19,10 @@
1819
+ debug b => _6;
1920
+ }
2021
+ }
22+
+ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
23+
+ scope 5 (inlined sleep) {
24+
+ }
25+
+ }
2126
+ }
2227

2328
bb0: {
@@ -29,40 +34,13 @@
2934
+ StorageLive(_4);
3035
+ StorageLive(_3);
3136
+ _3 = &_2;
32-
+ _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind: bb5];
37+
+ StorageLive(_8);
38+
+ _8 = const ();
39+
+ goto -> bb1;
3340
+ }
3441
+
3542
+ bb1: {
36-
+ StorageDead(_3);
37-
+ StorageLive(_5);
38-
+ _5 = &_2;
39-
+ _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind: bb4];
40-
+ }
41-
+
42-
+ bb2: {
43-
+ StorageDead(_5);
44-
+ StorageLive(_7);
45-
+ _7 = move _4;
46-
+ _1 = (move _7, copy _6);
47-
+ StorageDead(_7);
48-
+ StorageDead(_4);
49-
+ drop(_2) -> [return: bb3, unwind continue];
50-
+ }
51-
+
52-
+ bb3: {
53-
+ unreachable;
54-
+ }
55-
+
56-
+ bb4 (cleanup): {
57-
+ drop(_4) -> [return: bb5, unwind terminate(cleanup)];
58-
+ }
59-
+
60-
+ bb5 (cleanup): {
61-
+ drop(_2) -> [return: bb6, unwind terminate(cleanup)];
62-
+ }
63-
+
64-
+ bb6 (cleanup): {
65-
+ resume;
43+
+ goto -> bb1;
6644
}
6745
}
6846

‎tests/mir-opt/inline/inline_diverging.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ pub fn g(i: i32) -> u32 {
2626
pub fn h() {
2727
// CHECK-LABEL: fn h(
2828
// CHECK: (inlined call_twice::<!, fn() -> ! {sleep}>)
29-
// CHECK-NOT: inlined
29+
// CHECK: (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep}))
30+
// CHECK: (inlined sleep)
3031
call_twice(sleep);
3132
}
3233

‎tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
let _4: fn() {foo};
1010
let mut _5: ();
1111
+ scope 1 (inlined hide_foo) {
12+
+ }
13+
+ scope 2 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
14+
+ scope 3 (inlined foo) {
15+
+ }
1216
+ }
1317

1418
bb0: {
@@ -23,22 +27,20 @@
2327
StorageLive(_5);
2428
_5 = ();
2529
- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
26-
+ _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind unreachable];
27-
}
28-
30+
- }
31+
-
2932
- bb2: {
30-
+ bb1: {
3133
StorageDead(_5);
3234
StorageDead(_3);
3335
StorageDead(_4);
3436
StorageDead(_2);
3537
_0 = const ();
3638
- drop(_1) -> [return: bb3, unwind unreachable];
37-
+ drop(_1) -> [return: bb2, unwind unreachable];
39+
+ drop(_1) -> [return: bb1, unwind unreachable];
3840
}
3941

4042
- bb3: {
41-
+ bb2: {
43+
+ bb1: {
4244
return;
4345
}
4446
}

‎tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
let _4: fn() {foo};
1010
let mut _5: ();
1111
+ scope 1 (inlined hide_foo) {
12+
+ }
13+
+ scope 2 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
14+
+ scope 3 (inlined foo) {
15+
+ }
1216
+ }
1317

1418
bb0: {
@@ -23,33 +27,29 @@
2327
StorageLive(_5);
2428
_5 = ();
2529
- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
26-
+ _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind: bb3];
27-
}
28-
30+
- }
31+
-
2932
- bb2: {
30-
+ bb1: {
3133
StorageDead(_5);
3234
StorageDead(_3);
3335
StorageDead(_4);
3436
StorageDead(_2);
3537
_0 = const ();
3638
- drop(_1) -> [return: bb3, unwind: bb5];
37-
+ drop(_1) -> [return: bb2, unwind: bb4];
39+
+ drop(_1) -> [return: bb1, unwind: bb2];
3840
}
3941

4042
- bb3: {
41-
+ bb2: {
43+
+ bb1: {
4244
return;
4345
}
4446

4547
- bb4 (cleanup): {
4648
- drop(_1) -> [return: bb5, unwind terminate(cleanup)];
47-
+ bb3 (cleanup): {
48-
+ drop(_1) -> [return: bb4, unwind terminate(cleanup)];
49-
}
50-
49+
- }
50+
-
5151
- bb5 (cleanup): {
52-
+ bb4 (cleanup): {
52+
+ bb2 (cleanup): {
5353
resume;
5454
}
5555
}

‎tests/mir-opt/inline/issue_78442.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ pub fn bar<P>(
99
_baz: P,
1010
) {
1111
// CHECK-LABEL: fn bar(
12-
// CHECK: let mut {{.*}}: &fn() {foo};
13-
// CHECK: let {{.*}}: fn() {foo};
1412
// CHECK: (inlined hide_foo)
15-
// CHECK-NOT: inlined
13+
// CHECK: (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo}))
14+
// CHECK: (inlined foo)
1615
hide_foo()();
1716
}
1817

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ test-mir-pass: Inline
2+
//@ compile-flags: --crate-type=lib -C panic=abort
3+
4+
// EMIT_MIR inline_fn_call_for_fn_def.test.Inline.diff
5+
6+
fn inline_fn(x: impl FnOnce() -> i32) -> i32 {
7+
x()
8+
}
9+
10+
fn yield_number() -> i32 {
11+
64
12+
}
13+
14+
fn test() -> i32 {
15+
// CHECK: (inlined inline_fn::<fn() -> i32 {yield_number}>)
16+
// CHECK: (inlined <fn() -> i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number}))
17+
// CHECK: (inlined yield_number)
18+
inline_fn(yield_number)
19+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
- // MIR for `test` before Inline
2+
+ // MIR for `test` after Inline
3+
4+
fn test() -> i32 {
5+
let mut _0: i32;
6+
-
7+
- bb0: {
8+
- _0 = inline_fn::<fn() -> i32 {yield_number}>(yield_number) -> [return: bb1, unwind unreachable];
9+
+ let mut _1: fn() -> i32 {yield_number};
10+
+ scope 1 (inlined inline_fn::<fn() -> i32 {yield_number}>) {
11+
+ let mut _2: fn() -> i32 {yield_number};
12+
+ let mut _3: ();
13+
+ scope 2 (inlined <fn() -> i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number})) {
14+
+ scope 3 (inlined yield_number) {
15+
+ }
16+
+ }
17+
}
18+
19+
- bb1: {
20+
+ bb0: {
21+
+ StorageLive(_1);
22+
+ _1 = yield_number;
23+
+ StorageLive(_2);
24+
+ _2 = move _1;
25+
+ StorageLive(_3);
26+
+ _3 = ();
27+
+ _0 = const 64_i32;
28+
+ StorageDead(_3);
29+
+ StorageDead(_2);
30+
+ StorageDead(_1);
31+
return;
32+
}
33+
}
34+
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// MIR for `num_to_digit` after PreCodegen
2+
3+
fn num_to_digit(_1: char) -> u32 {
4+
debug num => _1;
5+
let mut _0: u32;
6+
let mut _2: bool;
7+
let mut _3: std::option::Option<u32>;
8+
scope 1 (inlined #[track_caller] Option::<u32>::unwrap) {
9+
let mut _4: isize;
10+
let mut _5: !;
11+
scope 2 {
12+
}
13+
}
14+
15+
bb0: {
16+
StorageLive(_2);
17+
_2 = char::methods::<impl char>::is_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue];
18+
}
19+
20+
bb1: {
21+
switchInt(move _2) -> [0: bb2, otherwise: bb3];
22+
}
23+
24+
bb2: {
25+
_0 = const 0_u32;
26+
goto -> bb7;
27+
}
28+
29+
bb3: {
30+
StorageLive(_3);
31+
_3 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb4, unwind continue];
32+
}
33+
34+
bb4: {
35+
StorageLive(_4);
36+
_4 = discriminant(_3);
37+
switchInt(move _4) -> [0: bb5, 1: bb6, otherwise: bb8];
38+
}
39+
40+
bb5: {
41+
_5 = option::unwrap_failed() -> unwind continue;
42+
}
43+
44+
bb6: {
45+
_0 = move ((_3 as Some).0: u32);
46+
StorageDead(_4);
47+
StorageDead(_3);
48+
goto -> bb7;
49+
}
50+
51+
bb7: {
52+
StorageDead(_2);
53+
return;
54+
}
55+
56+
bb8: {
57+
unreachable;
58+
}
59+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// MIR for `num_to_digit` after PreCodegen
2+
3+
fn num_to_digit(_1: char) -> u32 {
4+
debug num => _1;
5+
let mut _0: u32;
6+
let mut _4: std::option::Option<u32>;
7+
scope 1 (inlined char::methods::<impl char>::is_digit) {
8+
let _2: std::option::Option<u32>;
9+
scope 2 (inlined Option::<u32>::is_some) {
10+
let mut _3: isize;
11+
}
12+
}
13+
scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
14+
let mut _5: isize;
15+
let mut _6: !;
16+
scope 4 {
17+
}
18+
}
19+
20+
bb0: {
21+
StorageLive(_2);
22+
_2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable];
23+
}
24+
25+
bb1: {
26+
StorageLive(_3);
27+
_3 = discriminant(_2);
28+
StorageDead(_2);
29+
switchInt(move _3) -> [1: bb2, otherwise: bb7];
30+
}
31+
32+
bb2: {
33+
StorageDead(_3);
34+
StorageLive(_4);
35+
_4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable];
36+
}
37+
38+
bb3: {
39+
StorageLive(_5);
40+
_5 = discriminant(_4);
41+
switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6];
42+
}
43+
44+
bb4: {
45+
_6 = option::unwrap_failed() -> unwind unreachable;
46+
}
47+
48+
bb5: {
49+
_0 = move ((_4 as Some).0: u32);
50+
StorageDead(_5);
51+
StorageDead(_4);
52+
goto -> bb8;
53+
}
54+
55+
bb6: {
56+
unreachable;
57+
}
58+
59+
bb7: {
60+
StorageDead(_3);
61+
_0 = const 0_u32;
62+
goto -> bb8;
63+
}
64+
65+
bb8: {
66+
return;
67+
}
68+
}

‎tests/mir-opt/issues/issue_59352.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
2+
// EMIT_MIR_FOR_EACH_BIT_WIDTH
3+
24
// This test is a mirror of codegen/issue-59352.rs.
35
// The LLVM inliner doesn't inline `char::method::is_digit()` and so it doesn't recognize this case
46
// as effectively `if x.is_some() { x.unwrap() } else { 0 }`.

‎tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
2929
let mut _12: U;
3030
scope 6 {
3131
debug x => _10;
32+
scope 7 (inlined ops::function::impls::<impl FnOnce<(T,)> for &mut impl Fn(T) -> U>::call_once) {
33+
debug self => _8;
34+
debug args => _11;
35+
}
3236
}
3337
}
3438
}
@@ -85,7 +89,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
8589
StorageLive(_12);
8690
StorageLive(_11);
8791
_11 = (copy _10,);
88-
_12 = <&mut impl Fn(T) -> U as FnOnce<(T,)>>::call_once(move _8, move _11) -> [return: bb7, unwind: bb10];
92+
_12 = <impl Fn(T) -> U as FnMut<(T,)>>::call_mut(move _8, move _11) -> [return: bb7, unwind: bb10];
8993
}
9094

9195
bb7: {

0 commit comments

Comments
 (0)
Please sign in to comment.