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 e6789c8

Browse files
committedMar 8, 2025·
Allow more top-down inlining for single-BB callees
This means that things like `<usize as Step>::forward_unchecked` and `<PartialOrd for f32>::le` will inline even if we've already done a bunch of inlining to find the calls to them.
1 parent 30f168e commit e6789c8

13 files changed

+368
-196
lines changed
 

Diff for: ‎compiler/rustc_mir_transform/src/inline.rs

+53-35
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use crate::{check_inline, util};
2626

2727
pub(crate) mod cycle;
2828

29+
const HISTORY_DEPTH_LIMIT: usize = 20;
2930
const TOP_DOWN_DEPTH_LIMIT: usize = 5;
3031

3132
#[derive(Clone, Debug)]
@@ -117,6 +118,13 @@ trait Inliner<'tcx> {
117118
/// Should inlining happen for a given callee?
118119
fn should_inline_for_callee(&self, def_id: DefId) -> bool;
119120

121+
fn check_codegen_attributes_extra(
122+
&self,
123+
_callee_attrs: &CodegenFnAttrs,
124+
) -> Result<(), &'static str> {
125+
Ok(())
126+
}
127+
120128
fn check_caller_mir_body(&self, body: &Body<'tcx>) -> bool;
121129

122130
/// Returns inlining decision that is based on the examination of callee MIR body.
@@ -128,10 +136,6 @@ trait Inliner<'tcx> {
128136
callee_attrs: &CodegenFnAttrs,
129137
) -> Result<(), &'static str>;
130138

131-
// How many callsites in a body are we allowed to inline? We need to limit this in order
132-
// to prevent super-linear growth in MIR size.
133-
fn inline_limit_for_block(&self) -> Option<usize>;
134-
135139
/// Called when inlining succeeds.
136140
fn on_inline_success(
137141
&mut self,
@@ -142,9 +146,6 @@ trait Inliner<'tcx> {
142146

143147
/// Called when inlining failed or was not performed.
144148
fn on_inline_failure(&self, callsite: &CallSite<'tcx>, reason: &'static str);
145-
146-
/// Called when the inline limit for a body is reached.
147-
fn on_inline_limit_reached(&self) -> bool;
148149
}
149150

150151
struct ForceInliner<'tcx> {
@@ -224,10 +225,6 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
224225
}
225226
}
226227

227-
fn inline_limit_for_block(&self) -> Option<usize> {
228-
Some(usize::MAX)
229-
}
230-
231228
fn on_inline_success(
232229
&mut self,
233230
callsite: &CallSite<'tcx>,
@@ -261,10 +258,6 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
261258
justification: justification.map(|sym| crate::errors::ForceInlineJustification { sym }),
262259
});
263260
}
264-
265-
fn on_inline_limit_reached(&self) -> bool {
266-
false
267-
}
268261
}
269262

270263
struct NormalInliner<'tcx> {
@@ -278,13 +271,23 @@ struct NormalInliner<'tcx> {
278271
/// The number of `DefId`s is finite, so checking history is enough
279272
/// to ensure that we do not loop endlessly while inlining.
280273
history: Vec<DefId>,
274+
/// How many (multi-call) callsites have we inlined for the top-level call?
275+
///
276+
/// We need to limit this in order to prevent super-linear growth in MIR size.
277+
top_down_counter: usize,
281278
/// Indicates that the caller body has been modified.
282279
changed: bool,
283280
/// Indicates that the caller is #[inline] and just calls another function,
284281
/// and thus we can inline less into it as it'll be inlined itself.
285282
caller_is_inline_forwarder: bool,
286283
}
287284

285+
impl<'tcx> NormalInliner<'tcx> {
286+
fn past_depth_limit(&self) -> bool {
287+
self.history.len() > HISTORY_DEPTH_LIMIT || self.top_down_counter > TOP_DOWN_DEPTH_LIMIT
288+
}
289+
}
290+
288291
impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
289292
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, body: &Body<'tcx>) -> Self {
290293
let typing_env = body.typing_env(tcx);
@@ -295,6 +298,7 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
295298
typing_env,
296299
def_id,
297300
history: Vec::new(),
301+
top_down_counter: 0,
298302
changed: false,
299303
caller_is_inline_forwarder: matches!(
300304
codegen_fn_attrs.inline,
@@ -327,6 +331,17 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
327331
true
328332
}
329333

334+
fn check_codegen_attributes_extra(
335+
&self,
336+
callee_attrs: &CodegenFnAttrs,
337+
) -> Result<(), &'static str> {
338+
if self.past_depth_limit() && matches!(callee_attrs.inline, InlineAttr::None) {
339+
Err("Past depth limit so not inspecting unmarked callee")
340+
} else {
341+
Ok(())
342+
}
343+
}
344+
330345
fn check_caller_mir_body(&self, body: &Body<'tcx>) -> bool {
331346
// Avoid inlining into coroutines, since their `optimized_mir` is used for layout computation,
332347
// which can create a cycle, even when no attempt is made to inline the function in the other
@@ -351,6 +366,10 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
351366
return Err("body has errors");
352367
}
353368

369+
if self.past_depth_limit() && callee_body.basic_blocks.len() > 1 {
370+
return Err("Not inlining multi-block body as we're past a depth limit");
371+
}
372+
354373
let mut threshold = if self.caller_is_inline_forwarder {
355374
tcx.sess.opts.unstable_opts.inline_mir_forwarder_threshold.unwrap_or(30)
356375
} else if tcx.cross_crate_inlinable(callsite.callee.def_id()) {
@@ -431,14 +450,6 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
431450
}
432451
}
433452

434-
fn inline_limit_for_block(&self) -> Option<usize> {
435-
match self.history.len() {
436-
0 => Some(usize::MAX),
437-
1..=TOP_DOWN_DEPTH_LIMIT => Some(1),
438-
_ => None,
439-
}
440-
}
441-
442453
fn on_inline_success(
443454
&mut self,
444455
callsite: &CallSite<'tcx>,
@@ -447,13 +458,26 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
447458
) {
448459
self.changed = true;
449460

461+
let new_calls_count = new_blocks
462+
.clone()
463+
.filter(|&bb| {
464+
matches!(
465+
caller_body.basic_blocks[bb].terminator().kind,
466+
TerminatorKind::Call { .. },
467+
)
468+
})
469+
.count();
470+
if new_calls_count > 1 {
471+
self.top_down_counter += 1;
472+
}
473+
450474
self.history.push(callsite.callee.def_id());
451475
process_blocks(self, caller_body, new_blocks);
452476
self.history.pop();
453-
}
454477

455-
fn on_inline_limit_reached(&self) -> bool {
456-
true
478+
if self.history.is_empty() {
479+
self.top_down_counter = 0;
480+
}
457481
}
458482

459483
fn on_inline_failure(&self, _: &CallSite<'tcx>, _: &'static str) {}
@@ -482,8 +506,6 @@ fn process_blocks<'tcx, I: Inliner<'tcx>>(
482506
caller_body: &mut Body<'tcx>,
483507
blocks: Range<BasicBlock>,
484508
) {
485-
let Some(inline_limit) = inliner.inline_limit_for_block() else { return };
486-
let mut inlined_count = 0;
487509
for bb in blocks {
488510
let bb_data = &caller_body[bb];
489511
if bb_data.is_cleanup {
@@ -505,13 +527,6 @@ fn process_blocks<'tcx, I: Inliner<'tcx>>(
505527
Ok(new_blocks) => {
506528
debug!("inlined {}", callsite.callee);
507529
inliner.on_inline_success(&callsite, caller_body, new_blocks);
508-
509-
inlined_count += 1;
510-
if inlined_count == inline_limit {
511-
if inliner.on_inline_limit_reached() {
512-
return;
513-
}
514-
}
515530
}
516531
}
517532
}
@@ -584,6 +599,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
584599
let callee_attrs = tcx.codegen_fn_attrs(callsite.callee.def_id());
585600
check_inline::is_inline_valid_on_fn(tcx, callsite.callee.def_id())?;
586601
check_codegen_attributes(inliner, callsite, callee_attrs)?;
602+
inliner.check_codegen_attributes_extra(callee_attrs)?;
587603

588604
let terminator = caller_body[callsite.block].terminator.as_ref().unwrap();
589605
let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
@@ -770,6 +786,8 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
770786
return Err("has DoNotOptimize attribute");
771787
}
772788

789+
inliner.check_codegen_attributes_extra(callee_attrs)?;
790+
773791
// Reachability pass defines which functions are eligible for inlining. Generally inlining
774792
// other functions is incorrect because they could reference symbols that aren't exported.
775793
let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();

Diff for: ‎tests/mir-opt/inline/exponential_runtime.rs

+5
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,15 @@ fn main() {
8787
// CHECK-LABEL: fn main(
8888
// CHECK-NOT: inlined
8989
// CHECK: (inlined <() as G>::call)
90+
// CHECK-NOT: inlined
9091
// CHECK: (inlined <() as F>::call)
92+
// CHECK-NOT: inlined
9193
// CHECK: (inlined <() as E>::call)
94+
// CHECK-NOT: inlined
9295
// CHECK: (inlined <() as D>::call)
96+
// CHECK-NOT: inlined
9397
// CHECK: (inlined <() as C>::call)
98+
// CHECK-NOT: inlined
9499
// CHECK: (inlined <() as B>::call)
95100
// CHECK-NOT: inlined
96101
<() as G>::call();

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

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

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

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

Diff for: ‎tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff

+99-30
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,50 @@
5555
+ let _26: ();
5656
+ scope 9 {
5757
+ }
58+
+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
59+
+ }
60+
+ scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
61+
+ let mut _42: ();
62+
+ let mut _43: std::option::Option<()>;
63+
+ let mut _44: &mut std::option::Option<()>;
64+
+ let mut _45: &mut std::future::Ready<()>;
65+
+ let mut _46: &mut std::pin::Pin<&mut std::future::Ready<()>>;
66+
+ scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
67+
+ let mut _47: std::pin::Pin<&mut std::future::Ready<()>>;
68+
+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
69+
+ let mut _48: &mut &mut std::future::Ready<()>;
70+
+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
71+
+ }
72+
+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
73+
+ }
74+
+ }
75+
+ scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) {
76+
+ }
77+
+ }
78+
+ scope 19 (inlined Option::<()>::take) {
79+
+ let mut _49: std::option::Option<()>;
80+
+ scope 20 (inlined std::mem::replace::<Option<()>>) {
81+
+ scope 21 {
82+
+ scope 23 (inlined std::ptr::write::<Option<()>>) {
83+
+ }
84+
+ }
85+
+ scope 22 (inlined std::ptr::read::<Option<()>>) {
86+
+ }
87+
+ }
88+
+ }
89+
+ scope 24 (inlined #[track_caller] Option::<()>::expect) {
90+
+ let mut _50: isize;
91+
+ let mut _51: !;
92+
+ scope 25 {
93+
+ }
94+
+ }
95+
+ }
5896
+ }
5997
+ scope 10 (inlined ready::<()>) {
6098
+ let mut _41: std::option::Option<()>;
6199
+ }
100+
+ scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
101+
+ }
62102
+ }
63103
+ }
64104
}
@@ -113,7 +153,7 @@
113153
+ StorageLive(_40);
114154
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
115155
+ _32 = discriminant((*_33));
116-
+ switchInt(move _32) -> [0: bb3, 1: bb13, 3: bb12, otherwise: bb8];
156+
+ switchInt(move _32) -> [0: bb3, 1: bb10, 3: bb9, otherwise: bb5];
117157
}
118158

119159
- bb3: {
@@ -164,19 +204,16 @@
164204
+ _13 = std::future::Ready::<()>(move _41);
165205
+ StorageDead(_41);
166206
+ StorageDead(_14);
167-
+ _12 = <std::future::Ready<()> as IntoFuture>::into_future(move _13) -> [return: bb4, unwind unreachable];
168-
+ }
169-
+
170-
bb4: {
171-
- StorageDead(_2);
172-
- return;
207+
+ _12 = move _13;
173208
+ StorageDead(_13);
174209
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
175210
+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
176-
+ goto -> bb5;
211+
+ goto -> bb4;
177212
+ }
178213
+
179-
+ bb5: {
214+
bb4: {
215+
- StorageDead(_2);
216+
- return;
180217
+ StorageLive(_17);
181218
+ StorageLive(_18);
182219
+ StorageLive(_19);
@@ -185,10 +222,7 @@
185222
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
186223
+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
187224
+ _20 = &mut (*_21);
188-
+ _19 = Pin::<&mut std::future::Ready<()>>::new_unchecked(move _20) -> [return: bb6, unwind unreachable];
189-
+ }
190-
+
191-
+ bb6: {
225+
+ _19 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _20 };
192226
+ StorageDead(_20);
193227
+ StorageLive(_22);
194228
+ StorageLive(_23);
@@ -197,21 +231,36 @@
197231
+ _23 = move _24;
198232
+ _22 = &mut (*_23);
199233
+ StorageDead(_24);
200-
+ _18 = <std::future::Ready<()> as Future>::poll(move _19, move _22) -> [return: bb7, unwind unreachable];
201-
+ }
202-
+
203-
+ bb7: {
204-
+ StorageDead(_22);
205-
+ StorageDead(_19);
206-
+ _25 = discriminant(_18);
207-
+ switchInt(move _25) -> [0: bb10, 1: bb9, otherwise: bb8];
234+
+ StorageLive(_45);
235+
+ StorageLive(_46);
236+
+ StorageLive(_49);
237+
+ StorageLive(_51);
238+
+ StorageLive(_42);
239+
+ StorageLive(_43);
240+
+ StorageLive(_44);
241+
+ _46 = &mut _19;
242+
+ StorageLive(_47);
243+
+ StorageLive(_48);
244+
+ _48 = &mut (_19.0: &mut std::future::Ready<()>);
245+
+ _45 = copy (_19.0: &mut std::future::Ready<()>);
246+
+ StorageDead(_48);
247+
+ _47 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _45 };
248+
+ StorageDead(_47);
249+
+ _44 = &mut ((*_45).0: std::option::Option<()>);
250+
+ _49 = Option::<()>::None;
251+
+ _43 = copy ((*_45).0: std::option::Option<()>);
252+
+ ((*_45).0: std::option::Option<()>) = copy _49;
253+
+ StorageDead(_44);
254+
+ StorageLive(_50);
255+
+ _50 = discriminant(_43);
256+
+ switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5];
208257
+ }
209258
+
210-
+ bb8: {
259+
+ bb5: {
211260
+ unreachable;
212261
+ }
213262
+
214-
+ bb9: {
263+
+ bb6: {
215264
+ _17 = const ();
216265
+ StorageDead(_23);
217266
+ StorageDead(_21);
@@ -229,7 +278,7 @@
229278
+ goto -> bb2;
230279
+ }
231280
+
232-
+ bb10: {
281+
+ bb7: {
233282
+ StorageLive(_26);
234283
+ _26 = copy ((_18 as Ready).0: ());
235284
+ _30 = copy _26;
@@ -240,17 +289,17 @@
240289
+ StorageDead(_17);
241290
+ StorageDead(_12);
242291
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
243-
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb11, unwind unreachable];
292+
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable];
244293
+ }
245294
+
246-
+ bb11: {
295+
+ bb8: {
247296
+ _7 = Poll::<()>::Ready(move _30);
248297
+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
249298
+ discriminant((*_40)) = 1;
250299
+ goto -> bb2;
251300
+ }
252301
+
253-
+ bb12: {
302+
+ bb9: {
254303
+ StorageLive(_12);
255304
+ StorageLive(_28);
256305
+ StorageLive(_29);
@@ -259,11 +308,31 @@
259308
+ _31 = move _28;
260309
+ StorageDead(_28);
261310
+ _16 = const ();
262-
+ goto -> bb5;
311+
+ goto -> bb4;
263312
+ }
264313
+
265-
+ bb13: {
266-
+ assert(const false, "`async fn` resumed after completion") -> [success: bb13, unwind unreachable];
314+
+ bb10: {
315+
+ assert(const false, "`async fn` resumed after completion") -> [success: bb10, unwind unreachable];
316+
+ }
317+
+
318+
+ bb11: {
319+
+ _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
320+
+ }
321+
+
322+
+ bb12: {
323+
+ _42 = move ((_43 as Some).0: ());
324+
+ StorageDead(_50);
325+
+ StorageDead(_43);
326+
+ _18 = Poll::<()>::Ready(move _42);
327+
+ StorageDead(_42);
328+
+ StorageDead(_51);
329+
+ StorageDead(_49);
330+
+ StorageDead(_46);
331+
+ StorageDead(_45);
332+
+ StorageDead(_22);
333+
+ StorageDead(_19);
334+
+ _25 = discriminant(_18);
335+
+ switchInt(move _25) -> [0: bb7, 1: bb6, otherwise: bb5];
267336
}
268337
}
269338

Diff for: ‎tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff

+108-58
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,50 @@
5757
+ let _26: ();
5858
+ scope 9 {
5959
+ }
60+
+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
61+
+ }
62+
+ scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
63+
+ let mut _44: ();
64+
+ let mut _45: std::option::Option<()>;
65+
+ let mut _46: &mut std::option::Option<()>;
66+
+ let mut _47: &mut std::future::Ready<()>;
67+
+ let mut _48: &mut std::pin::Pin<&mut std::future::Ready<()>>;
68+
+ scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
69+
+ let mut _49: std::pin::Pin<&mut std::future::Ready<()>>;
70+
+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
71+
+ let mut _50: &mut &mut std::future::Ready<()>;
72+
+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
73+
+ }
74+
+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
75+
+ }
76+
+ }
77+
+ scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) {
78+
+ }
79+
+ }
80+
+ scope 19 (inlined Option::<()>::take) {
81+
+ let mut _51: std::option::Option<()>;
82+
+ scope 20 (inlined std::mem::replace::<Option<()>>) {
83+
+ scope 21 {
84+
+ scope 23 (inlined std::ptr::write::<Option<()>>) {
85+
+ }
86+
+ }
87+
+ scope 22 (inlined std::ptr::read::<Option<()>>) {
88+
+ }
89+
+ }
90+
+ }
91+
+ scope 24 (inlined #[track_caller] Option::<()>::expect) {
92+
+ let mut _52: isize;
93+
+ let mut _53: !;
94+
+ scope 25 {
95+
+ }
96+
+ }
97+
+ }
6098
+ }
6199
+ scope 10 (inlined ready::<()>) {
62100
+ let mut _43: std::option::Option<()>;
63101
+ }
102+
+ scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
103+
+ }
64104
+ }
65105
+ }
66106
}
@@ -117,7 +157,7 @@
117157
+ StorageLive(_42);
118158
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
119159
+ _32 = discriminant((*_33));
120-
+ switchInt(move _32) -> [0: bb5, 1: bb22, 2: bb21, 3: bb20, otherwise: bb10];
160+
+ switchInt(move _32) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7];
121161
}
122162

123163
- bb3: {
@@ -181,21 +221,16 @@
181221
+ _13 = std::future::Ready::<()>(move _43);
182222
+ StorageDead(_43);
183223
+ StorageDead(_14);
184-
+ _12 = <std::future::Ready<()> as IntoFuture>::into_future(move _13) -> [return: bb6, unwind: bb17];
185-
}
186-
187-
- bb5 (cleanup): {
188-
- drop(_2) -> [return: bb6, unwind terminate(cleanup)];
189-
+ bb6: {
224+
+ _12 = move _13;
190225
+ StorageDead(_13);
191226
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
192227
+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
193-
+ goto -> bb7;
228+
+ goto -> bb6;
194229
}
195230

196-
- bb6 (cleanup): {
197-
- resume;
198-
+ bb7: {
231+
- bb5 (cleanup): {
232+
- drop(_2) -> [return: bb6, unwind terminate(cleanup)];
233+
+ bb6: {
199234
+ StorageLive(_17);
200235
+ StorageLive(_18);
201236
+ StorageLive(_19);
@@ -204,10 +239,7 @@
204239
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
205240
+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
206241
+ _20 = &mut (*_21);
207-
+ _19 = Pin::<&mut std::future::Ready<()>>::new_unchecked(move _20) -> [return: bb8, unwind: bb15];
208-
+ }
209-
+
210-
+ bb8: {
242+
+ _19 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _20 };
211243
+ StorageDead(_20);
212244
+ StorageLive(_22);
213245
+ StorageLive(_23);
@@ -216,21 +248,38 @@
216248
+ _23 = move _24;
217249
+ _22 = &mut (*_23);
218250
+ StorageDead(_24);
219-
+ _18 = <std::future::Ready<()> as Future>::poll(move _19, move _22) -> [return: bb9, unwind: bb14];
220-
+ }
221-
+
222-
+ bb9: {
223-
+ StorageDead(_22);
224-
+ StorageDead(_19);
225-
+ _25 = discriminant(_18);
226-
+ switchInt(move _25) -> [0: bb12, 1: bb11, otherwise: bb10];
227-
+ }
228-
+
229-
+ bb10: {
251+
+ StorageLive(_47);
252+
+ StorageLive(_48);
253+
+ StorageLive(_51);
254+
+ StorageLive(_53);
255+
+ StorageLive(_44);
256+
+ StorageLive(_45);
257+
+ StorageLive(_46);
258+
+ _48 = &mut _19;
259+
+ StorageLive(_49);
260+
+ StorageLive(_50);
261+
+ _50 = &mut (_19.0: &mut std::future::Ready<()>);
262+
+ _47 = copy (_19.0: &mut std::future::Ready<()>);
263+
+ StorageDead(_50);
264+
+ _49 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _47 };
265+
+ StorageDead(_49);
266+
+ _46 = &mut ((*_47).0: std::option::Option<()>);
267+
+ _51 = Option::<()>::None;
268+
+ _45 = copy ((*_47).0: std::option::Option<()>);
269+
+ ((*_47).0: std::option::Option<()>) = copy _51;
270+
+ StorageDead(_46);
271+
+ StorageLive(_52);
272+
+ _52 = discriminant(_45);
273+
+ switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7];
274+
}
275+
276+
- bb6 (cleanup): {
277+
- resume;
278+
+ bb7: {
230279
+ unreachable;
231280
+ }
232281
+
233-
+ bb11: {
282+
+ bb8: {
234283
+ _17 = const ();
235284
+ StorageDead(_23);
236285
+ StorageDead(_21);
@@ -248,7 +297,7 @@
248297
+ goto -> bb4;
249298
+ }
250299
+
251-
+ bb12: {
300+
+ bb9: {
252301
+ StorageLive(_26);
253302
+ _26 = copy ((_18 as Ready).0: ());
254303
+ _30 = copy _26;
@@ -259,54 +308,35 @@
259308
+ StorageDead(_17);
260309
+ StorageDead(_12);
261310
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
262-
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb13, unwind: bb19];
311+
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12];
263312
+ }
264313
+
265-
+ bb13: {
314+
+ bb10: {
266315
+ _7 = Poll::<()>::Ready(move _30);
267316
+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
268317
+ discriminant((*_40)) = 1;
269318
+ goto -> bb4;
270319
+ }
271320
+
272-
+ bb14 (cleanup): {
321+
+ bb11 (cleanup): {
273322
+ StorageDead(_22);
274323
+ StorageDead(_19);
275324
+ StorageDead(_23);
276-
+ goto -> bb16;
277-
+ }
278-
+
279-
+ bb15 (cleanup): {
280-
+ StorageDead(_20);
281-
+ StorageDead(_19);
282-
+ goto -> bb16;
283-
+ }
284-
+
285-
+ bb16 (cleanup): {
286325
+ StorageDead(_21);
287326
+ StorageDead(_18);
288327
+ StorageDead(_17);
289-
+ goto -> bb18;
290-
+ }
291-
+
292-
+ bb17 (cleanup): {
293-
+ StorageDead(_13);
294-
+ goto -> bb18;
295-
+ }
296-
+
297-
+ bb18 (cleanup): {
298328
+ StorageDead(_12);
299329
+ _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
300-
+ drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb19, unwind terminate(cleanup)];
330+
+ drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)];
301331
+ }
302332
+
303-
+ bb19 (cleanup): {
333+
+ bb12 (cleanup): {
304334
+ _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
305335
+ discriminant((*_42)) = 2;
306336
+ goto -> bb2;
307337
+ }
308338
+
309-
+ bb20: {
339+
+ bb13: {
310340
+ StorageLive(_12);
311341
+ StorageLive(_28);
312342
+ StorageLive(_29);
@@ -315,15 +345,35 @@
315345
+ _31 = move _28;
316346
+ StorageDead(_28);
317347
+ _16 = const ();
318-
+ goto -> bb7;
348+
+ goto -> bb6;
319349
+ }
320350
+
321-
+ bb21: {
322-
+ assert(const false, "`async fn` resumed after panicking") -> [success: bb21, unwind: bb2];
351+
+ bb14: {
352+
+ assert(const false, "`async fn` resumed after panicking") -> [success: bb14, unwind: bb2];
323353
+ }
324354
+
325-
+ bb22: {
326-
+ assert(const false, "`async fn` resumed after completion") -> [success: bb22, unwind: bb2];
355+
+ bb15: {
356+
+ assert(const false, "`async fn` resumed after completion") -> [success: bb15, unwind: bb2];
357+
+ }
358+
+
359+
+ bb16: {
360+
+ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
361+
+ }
362+
+
363+
+ bb17: {
364+
+ _44 = move ((_45 as Some).0: ());
365+
+ StorageDead(_52);
366+
+ StorageDead(_45);
367+
+ _18 = Poll::<()>::Ready(move _44);
368+
+ StorageDead(_44);
369+
+ StorageDead(_53);
370+
+ StorageDead(_51);
371+
+ StorageDead(_48);
372+
+ StorageDead(_47);
373+
+ StorageDead(_22);
374+
+ StorageDead(_19);
375+
+ _25 = discriminant(_18);
376+
+ switchInt(move _25) -> [0: bb9, 1: bb8, otherwise: bb7];
327377
}
328378
}
329379

Diff for: ‎tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir

+15-9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ fn int_range(_1: usize, _2: usize) -> () {
2626
let mut _12: usize;
2727
scope 6 {
2828
debug old => _11;
29+
scope 8 (inlined <usize as Step>::forward_unchecked) {
30+
debug start => _11;
31+
debug n => const 1_usize;
32+
scope 9 (inlined core::num::<impl usize>::unchecked_add) {
33+
debug self => _11;
34+
debug rhs => const 1_usize;
35+
scope 10 (inlined core::ub_checks::check_language_ub) {
36+
scope 11 (inlined core::ub_checks::check_language_ub::runtime) {
37+
}
38+
}
39+
}
40+
}
2941
}
3042
scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
3143
debug self => _6;
@@ -50,7 +62,6 @@ fn int_range(_1: usize, _2: usize) -> () {
5062
bb1: {
5163
StorageLive(_13);
5264
_5 = &mut _4;
53-
StorageLive(_11);
5465
StorageLive(_10);
5566
StorageLive(_6);
5667
_6 = &(_4.0: usize);
@@ -70,7 +81,6 @@ fn int_range(_1: usize, _2: usize) -> () {
7081
StorageDead(_7);
7182
StorageDead(_6);
7283
StorageDead(_10);
73-
StorageDead(_11);
7484
StorageDead(_13);
7585
StorageDead(_4);
7686
return;
@@ -81,20 +91,16 @@ fn int_range(_1: usize, _2: usize) -> () {
8191
StorageDead(_6);
8292
_11 = copy (_4.0: usize);
8393
StorageLive(_12);
84-
_12 = <usize as Step>::forward_unchecked(copy _11, const 1_usize) -> [return: bb4, unwind continue];
85-
}
86-
87-
bb4: {
94+
_12 = AddUnchecked(copy _11, const 1_usize);
8895
(_4.0: usize) = move _12;
8996
StorageDead(_12);
9097
_13 = Option::<usize>::Some(copy _11);
9198
StorageDead(_10);
92-
StorageDead(_11);
9399
_14 = copy ((_13 as Some).0: usize);
94-
_15 = opaque::<usize>(move _14) -> [return: bb5, unwind continue];
100+
_15 = opaque::<usize>(move _14) -> [return: bb4, unwind continue];
95101
}
96102

97-
bb5: {
103+
bb4: {
98104
StorageDead(_13);
99105
goto -> bb1;
100106
}

Diff for: ‎tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir

+11-9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
2323
let _7: u32;
2424
let mut _8: u32;
2525
scope 6 {
26+
scope 8 (inlined <u32 as Step>::forward_unchecked) {
27+
scope 9 (inlined core::num::<impl u32>::unchecked_add) {
28+
scope 10 (inlined core::ub_checks::check_language_ub) {
29+
scope 11 (inlined core::ub_checks::check_language_ub::runtime) {
30+
}
31+
}
32+
}
33+
}
2634
}
2735
scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
2836
let mut _5: u32;
@@ -41,7 +49,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
4149

4250
bb1: {
4351
StorageLive(_9);
44-
StorageLive(_7);
4552
StorageLive(_6);
4653
StorageLive(_5);
4754
_5 = copy _4;
@@ -52,7 +59,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
5259

5360
bb2: {
5461
StorageDead(_6);
55-
StorageDead(_7);
5662
StorageDead(_9);
5763
StorageDead(_4);
5864
drop(_3) -> [return: bb3, unwind unreachable];
@@ -65,24 +71,20 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
6571
bb4: {
6672
_7 = copy _4;
6773
StorageLive(_8);
68-
_8 = <u32 as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind unreachable];
69-
}
70-
71-
bb5: {
74+
_8 = AddUnchecked(copy _7, const 1_u32);
7275
_4 = move _8;
7376
StorageDead(_8);
7477
_9 = Option::<u32>::Some(copy _7);
7578
StorageDead(_6);
76-
StorageDead(_7);
7779
_10 = copy ((_9 as Some).0: u32);
7880
StorageLive(_11);
7981
_11 = &_3;
8082
StorageLive(_12);
8183
_12 = (copy _10,);
82-
_13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb6, unwind unreachable];
84+
_13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind unreachable];
8385
}
8486

85-
bb6: {
87+
bb5: {
8688
StorageDead(_12);
8789
StorageDead(_11);
8890
StorageDead(_9);

Diff for: ‎tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir

+14-12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
2323
let _7: u32;
2424
let mut _8: u32;
2525
scope 6 {
26+
scope 8 (inlined <u32 as Step>::forward_unchecked) {
27+
scope 9 (inlined core::num::<impl u32>::unchecked_add) {
28+
scope 10 (inlined core::ub_checks::check_language_ub) {
29+
scope 11 (inlined core::ub_checks::check_language_ub::runtime) {
30+
}
31+
}
32+
}
33+
}
2634
}
2735
scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
2836
let mut _5: u32;
@@ -41,7 +49,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
4149

4250
bb1: {
4351
StorageLive(_9);
44-
StorageLive(_7);
4552
StorageLive(_6);
4653
StorageLive(_5);
4754
_5 = copy _4;
@@ -52,7 +59,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
5259

5360
bb2: {
5461
StorageDead(_6);
55-
StorageDead(_7);
5662
StorageDead(_9);
5763
StorageDead(_4);
5864
drop(_3) -> [return: bb3, unwind continue];
@@ -65,35 +71,31 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
6571
bb4: {
6672
_7 = copy _4;
6773
StorageLive(_8);
68-
_8 = <u32 as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind: bb7];
69-
}
70-
71-
bb5: {
74+
_8 = AddUnchecked(copy _7, const 1_u32);
7275
_4 = move _8;
7376
StorageDead(_8);
7477
_9 = Option::<u32>::Some(copy _7);
7578
StorageDead(_6);
76-
StorageDead(_7);
7779
_10 = copy ((_9 as Some).0: u32);
7880
StorageLive(_11);
7981
_11 = &_3;
8082
StorageLive(_12);
8183
_12 = (copy _10,);
82-
_13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb6, unwind: bb7];
84+
_13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb6];
8385
}
8486

85-
bb6: {
87+
bb5: {
8688
StorageDead(_12);
8789
StorageDead(_11);
8890
StorageDead(_9);
8991
goto -> bb1;
9092
}
9193

92-
bb7 (cleanup): {
93-
drop(_3) -> [return: bb8, unwind terminate(cleanup)];
94+
bb6 (cleanup): {
95+
drop(_3) -> [return: bb7, unwind terminate(cleanup)];
9496
}
9597

96-
bb8 (cleanup): {
98+
bb7 (cleanup): {
9799
resume;
98100
}
99101
}

Diff for: ‎tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir

+12-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
99
let _5: u32;
1010
let mut _6: u32;
1111
scope 3 {
12+
scope 5 (inlined <u32 as Step>::forward_unchecked) {
13+
scope 6 (inlined core::num::<impl u32>::unchecked_add) {
14+
scope 7 (inlined core::ub_checks::check_language_ub) {
15+
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
16+
}
17+
}
18+
}
19+
}
1220
}
1321
scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
1422
let mut _2: u32;
@@ -18,7 +26,6 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
1826
}
1927

2028
bb0: {
21-
StorageLive(_5);
2229
StorageLive(_4);
2330
StorageLive(_2);
2431
_2 = copy ((*_1).0: u32);
@@ -32,25 +39,21 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
3239

3340
bb1: {
3441
_0 = const Option::<u32>::None;
35-
goto -> bb4;
42+
goto -> bb3;
3643
}
3744

3845
bb2: {
3946
_5 = copy ((*_1).0: u32);
4047
StorageLive(_6);
41-
_6 = <u32 as Step>::forward_unchecked(copy _5, const 1_usize) -> [return: bb3, unwind unreachable];
42-
}
43-
44-
bb3: {
48+
_6 = AddUnchecked(copy _5, const 1_u32);
4549
((*_1).0: u32) = move _6;
4650
StorageDead(_6);
4751
_0 = Option::<u32>::Some(copy _5);
48-
goto -> bb4;
52+
goto -> bb3;
4953
}
5054

51-
bb4: {
55+
bb3: {
5256
StorageDead(_4);
53-
StorageDead(_5);
5457
return;
5558
}
5659
}

Diff for: ‎tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir

+12-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
99
let _5: u32;
1010
let mut _6: u32;
1111
scope 3 {
12+
scope 5 (inlined <u32 as Step>::forward_unchecked) {
13+
scope 6 (inlined core::num::<impl u32>::unchecked_add) {
14+
scope 7 (inlined core::ub_checks::check_language_ub) {
15+
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
16+
}
17+
}
18+
}
19+
}
1220
}
1321
scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
1422
let mut _2: u32;
@@ -18,7 +26,6 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
1826
}
1927

2028
bb0: {
21-
StorageLive(_5);
2229
StorageLive(_4);
2330
StorageLive(_2);
2431
_2 = copy ((*_1).0: u32);
@@ -32,25 +39,21 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
3239

3340
bb1: {
3441
_0 = const Option::<u32>::None;
35-
goto -> bb4;
42+
goto -> bb3;
3643
}
3744

3845
bb2: {
3946
_5 = copy ((*_1).0: u32);
4047
StorageLive(_6);
41-
_6 = <u32 as Step>::forward_unchecked(copy _5, const 1_usize) -> [return: bb3, unwind continue];
42-
}
43-
44-
bb3: {
48+
_6 = AddUnchecked(copy _5, const 1_u32);
4549
((*_1).0: u32) = move _6;
4650
StorageDead(_6);
4751
_0 = Option::<u32>::Some(copy _5);
48-
goto -> bb4;
52+
goto -> bb3;
4953
}
5054

51-
bb4: {
55+
bb3: {
5256
StorageDead(_4);
53-
StorageDead(_5);
5457
return;
5558
}
5659
}

Diff for: ‎tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir

+13-11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
2828
let _7: usize;
2929
let mut _8: usize;
3030
scope 7 {
31+
scope 9 (inlined <usize as Step>::forward_unchecked) {
32+
scope 10 (inlined core::num::<impl usize>::unchecked_add) {
33+
scope 11 (inlined core::ub_checks::check_language_ub) {
34+
scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
35+
}
36+
}
37+
}
38+
}
3139
}
3240
scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
3341
let mut _5: usize;
@@ -47,7 +55,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
4755

4856
bb1: {
4957
StorageLive(_9);
50-
StorageLive(_7);
5158
StorageLive(_6);
5259
StorageLive(_5);
5360
_5 = copy _4;
@@ -58,7 +65,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
5865

5966
bb2: {
6067
StorageDead(_6);
61-
StorageDead(_7);
6268
StorageDead(_9);
6369
StorageDead(_4);
6470
drop(_2) -> [return: bb3, unwind unreachable];
@@ -71,30 +77,26 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
7177
bb4: {
7278
_7 = copy _4;
7379
StorageLive(_8);
74-
_8 = <usize as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind unreachable];
75-
}
76-
77-
bb5: {
80+
_8 = AddUnchecked(copy _7, const 1_usize);
7881
_4 = move _8;
7982
StorageDead(_8);
8083
_9 = Option::<usize>::Some(copy _7);
8184
StorageDead(_6);
82-
StorageDead(_7);
8385
_10 = copy ((_9 as Some).0: usize);
8486
_11 = Lt(copy _10, copy _3);
85-
assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind unreachable];
87+
assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind unreachable];
8688
}
8789

88-
bb6: {
90+
bb5: {
8991
_12 = &(*_1)[_10];
9092
StorageLive(_13);
9193
_13 = &_2;
9294
StorageLive(_14);
9395
_14 = (copy _10, copy _12);
94-
_15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind unreachable];
96+
_15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb6, unwind unreachable];
9597
}
9698

97-
bb7: {
99+
bb6: {
98100
StorageDead(_14);
99101
StorageDead(_13);
100102
StorageDead(_9);

Diff for: ‎tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir

+16-14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
2828
let _7: usize;
2929
let mut _8: usize;
3030
scope 7 {
31+
scope 9 (inlined <usize as Step>::forward_unchecked) {
32+
scope 10 (inlined core::num::<impl usize>::unchecked_add) {
33+
scope 11 (inlined core::ub_checks::check_language_ub) {
34+
scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
35+
}
36+
}
37+
}
38+
}
3139
}
3240
scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
3341
let mut _5: usize;
@@ -47,7 +55,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
4755

4856
bb1: {
4957
StorageLive(_9);
50-
StorageLive(_7);
5158
StorageLive(_6);
5259
StorageLive(_5);
5360
_5 = copy _4;
@@ -58,7 +65,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
5865

5966
bb2: {
6067
StorageDead(_6);
61-
StorageDead(_7);
6268
StorageDead(_9);
6369
StorageDead(_4);
6470
drop(_2) -> [return: bb3, unwind continue];
@@ -71,41 +77,37 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
7177
bb4: {
7278
_7 = copy _4;
7379
StorageLive(_8);
74-
_8 = <usize as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind: bb8];
75-
}
76-
77-
bb5: {
80+
_8 = AddUnchecked(copy _7, const 1_usize);
7881
_4 = move _8;
7982
StorageDead(_8);
8083
_9 = Option::<usize>::Some(copy _7);
8184
StorageDead(_6);
82-
StorageDead(_7);
8385
_10 = copy ((_9 as Some).0: usize);
8486
_11 = Lt(copy _10, copy _3);
85-
assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind: bb8];
87+
assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind: bb7];
8688
}
8789

88-
bb6: {
90+
bb5: {
8991
_12 = &(*_1)[_10];
9092
StorageLive(_13);
9193
_13 = &_2;
9294
StorageLive(_14);
9395
_14 = (copy _10, copy _12);
94-
_15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind: bb8];
96+
_15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb6, unwind: bb7];
9597
}
9698

97-
bb7: {
99+
bb6: {
98100
StorageDead(_14);
99101
StorageDead(_13);
100102
StorageDead(_9);
101103
goto -> bb1;
102104
}
103105

104-
bb8 (cleanup): {
105-
drop(_2) -> [return: bb9, unwind terminate(cleanup)];
106+
bb7 (cleanup): {
107+
drop(_2) -> [return: bb8, unwind terminate(cleanup)];
106108
}
107109

108-
bb9 (cleanup): {
110+
bb8 (cleanup): {
109111
resume;
110112
}
111113
}

0 commit comments

Comments
 (0)
Please sign in to comment.