Change:
Previously: Now: <!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Inlining exposes a use of unnormalized local in a call terminator (not sure if this is more of an issue with inlining or a validator): Note: revision annotation doesn't work in an auxiliary file (so it isn't tested on CI with mir-opt-level=2). modify labels: +A-mir-opt-inlining
This ICEs again because the fix was reverted Can someone reopen please?
Due to this new requires to trigger. <details<summaryICE:</summary</details
(FWIW can also trigger this: )
fixes this for and , but it still ICEs with on its own or with mir-opt-level 1/2 cc

Discussion:
mod remove_unneeded_drops; mod remove_zsts; mod required_consts; <ins> mod reveal_all; </ins> mod separate_const_switch; mod shim; mod simplify;

// to them. We run some optimizations before that, because they may be harder to do on the state // machine than on MIR with async primitives. let optimizations_with_generators: &[&dyn MirPass<'tcx>] = &[ <ins> &reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode. </ins> &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first &normalize_array_len::NormalizeArrayLen, // has to run after `slice::len` lowering &unreachable_prop::UnreachablePropagation,

trace!("Running RemoveUnneededDrops on {:?}", body.source); let did = body.source.def_id(); <del> let param_env = tcx.param_env(did); </del> <ins> let param_env = tcx.param_env_reveal_all_normalized(did); </ins> let mut should_simplify = false; let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();

<ins> //! Normalizes MIR in RevealAll mode. use crate::MirPass; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; pub struct RevealAll; impl<'tcx> MirPass<'tcx> for RevealAll { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // This pass must run before inlining, since we insert callee bodies in RevealAll mode. // Do not apply this transformation to generators. if (tcx.sess.mir_opt_level() >= 3 || !super::inline::is_enabled(tcx)) && body.generator.is_none() { let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); RevealAllVisitor { tcx, param_env }.visit_body(body); } } } struct RevealAllVisitor<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, } impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } #[inline] fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) { *ty = self.tcx.normalize_erasing_regions(self.param_env, ty); } #[inline] fn process_projection_elem( &mut self, elem: PlaceElem<'tcx>, _: Location, ) -> Option<PlaceElem<'tcx>> { match elem { PlaceElem::Field(field, ty) => { let new_ty = self.tcx.normalize_erasing_regions(self.param_env, ty); if ty != new_ty { Some(PlaceElem::Field(field, new_ty)) } else { None } } // None of those contain a Ty. PlaceElem::Index(..) | PlaceElem::Deref | PlaceElem::ConstantIndex { .. } | PlaceElem::Subslice { .. } | PlaceElem::Downcast(..) => None, } } } </ins>

fn main() -> () { let mut _0: ();                      // return place in scope 0 at $DIR/inline-generator.rs:8:11: 8:11 <del> let _1: std::ops::GeneratorState<<impl std::ops::Generator<bool> as std::ops::Generator<bool>>::Yield, <impl std::ops::Generator<bool> as std::ops::Generator<bool>>::Return>; // in scope 0 at $DIR/inline-generator.rs:9:9: 9:11 let mut _2: std::pin::Pin<&mut impl std::ops::Generator<bool>>; // in scope 0 at $DIR/inline-generator.rs:9:14: 9:32 let mut _3: &mut impl std::ops::Generator<bool>; // in scope 0 at $DIR/inline-generator.rs:9:23: 9:31 let mut _4: impl std::ops::Generator<bool>; // in scope 0 at $DIR/inline-generator.rs:9:28: 9:31 </del> <ins> let _1: std::ops::GeneratorState<i32, bool>; // in scope 0 at $DIR/inline-generator.rs:9:9: 9:11 let mut _2: std::pin::Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:41]>; // in scope 0 at $DIR/inline-generator.rs:9:14: 9:32 let mut _3: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 0 at $DIR/inline-generator.rs:9:23: 9:31 let mut _4: [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 0 at $DIR/inline-generator.rs:9:28: 9:31 </ins> +     let mut _7: bool;                    // in scope 0 at $DIR/inline-generator.rs:9:14: 9:46 scope 1 { debug _r => _1;                  // in scope 1 at $DIR/inline-generator.rs:9:9: 9:11

<ins> // compile-flags: -Z mir-opt-level=3 -Z inline-mir // ignore-wasm32-bare compiled with panic=abort by default #![crate_type = "lib"] // EMIT_MIR issue_78442.bar.RevealAll.diff // EMIT_MIR issue_78442.bar.Inline.diff pub fn bar<P>( // Error won't happen if "bar" is not generic _baz: P, ) { hide_foo()(); } fn hide_foo() -> impl Fn() { // Error won't happen if "iterate" hasn't impl Trait or has generics foo } fn foo() { // Error won't happen if "foo" isn't used in "iterate" or has generics } </ins>

<ins> - // MIR for `bar` before Inline + // MIR for `bar` after Inline fn bar(_1: P) -> () { debug _baz => _1;                    // in scope 0 at $DIR/issue-78442.rs:9:5: 9:9 let mut _0: ();                      // return place in scope 0 at $DIR/issue-78442.rs:10:3: 10:3 let _2: ();                          // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 let mut _3: &fn() {foo};             // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 let _4: fn() {foo};                  // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 let mut _5: ();                      // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 +     scope 1 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) { // at $DIR/issue-78442.rs:11:5: 11:17 +     } bb0: { StorageLive(_2);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 StorageLive(_3);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_4);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 -         _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 +         _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 // + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar(<ZST>)) } } bb1: { _3 = &_4;                        // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_5);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 -         _2 = <impl Fn<()> as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 -                                          // mir::Constant -                                          // + span: $DIR/issue-78442.rs:11:5: 11:15 -                                          // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> <impl std::ops::Fn<()> as std::ops::FnOnce<()>>::Output {<impl std::ops::Fn<()> as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) } +         _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $DIR/issue-78442.rs:11:5: 11:17 } bb2: { -         StorageDead(_5);                 // scope 0 at $DIR/issue-78442.rs:11:16: 11:17 -         StorageDead(_3);                 // scope 0 at $DIR/issue-78442.rs:11:16: 11:17 -         StorageDead(_4);                 // scope 0 at $DIR/issue-78442.rs:11:17: 11:18 -         StorageDead(_2);                 // scope 0 at $DIR/issue-78442.rs:11:17: 11:18 -         _0 = const ();                   // scope 0 at $DIR/issue-78442.rs:10:3: 12:2 -         drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:12:1: 12:2 +         return;                          // scope 0 at $DIR/issue-78442.rs:12:2: 12:2 } -     bb3: { -         return;                          // scope 0 at $DIR/issue-78442.rs:12:2: 12:2 +     bb3 (cleanup): { +         drop(_1) -> bb4;                 // scope 0 at $DIR/issue-78442.rs:12:1: 12:2 } bb4 (cleanup): { -         drop(_1) -> bb5;                 // scope 0 at $DIR/issue-78442.rs:12:1: 12:2 +         resume;                          // scope 0 at $DIR/issue-78442.rs:7:1: 12:2 } -     bb5 (cleanup): { -         resume;                          // scope 0 at $DIR/issue-78442.rs:7:1: 12:2 +     bb5: { +         StorageDead(_5);                 // scope 0 at $DIR/issue-78442.rs:11:16: 11:17 +         StorageDead(_3);                 // scope 0 at $DIR/issue-78442.rs:11:16: 11:17 +         StorageDead(_4);                 // scope 0 at $DIR/issue-78442.rs:11:17: 11:18 +         StorageDead(_2);                 // scope 0 at $DIR/issue-78442.rs:11:17: 11:18 +         _0 = const ();                   // scope 0 at $DIR/issue-78442.rs:10:3: 12:2 +         drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:12:1: 12:2 } } </ins>

<ins> - // MIR for `bar` before RevealAll + // MIR for `bar` after RevealAll fn bar(_1: P) -> () { debug _baz => _1;                    // in scope 0 at $DIR/issue-78442.rs:9:5: 9:9 let mut _0: ();                      // return place in scope 0 at $DIR/issue-78442.rs:10:3: 10:3 let _2: ();                          // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 -     let mut _3: &impl std::ops::Fn<()>;  // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 -     let _4: impl std::ops::Fn<()>;       // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 +     let mut _3: &fn() {foo};             // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 +     let _4: fn() {foo};                  // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 let mut _5: ();                      // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 bb0: { StorageLive(_2);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 StorageLive(_3);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_4);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 // + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar(<ZST>)) } } bb1: { _3 = &_4;                        // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_5);                 // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 nop;                             // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 _2 = <impl Fn<()> as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:15 // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> <impl std::ops::Fn<()> as std::ops::FnOnce<()>>::Output {<impl std::ops::Fn<()> as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) } } bb2: { StorageDead(_5);                 // scope 0 at $DIR/issue-78442.rs:11:16: 11:17 StorageDead(_3);                 // scope 0 at $DIR/issue-78442.rs:11:16: 11:17 StorageDead(_4);                 // scope 0 at $DIR/issue-78442.rs:11:17: 11:18 StorageDead(_2);                 // scope 0 at $DIR/issue-78442.rs:11:17: 11:18 _0 = const ();                   // scope 0 at $DIR/issue-78442.rs:10:3: 12:2 drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:12:1: 12:2 } bb3: { return;                          // scope 0 at $DIR/issue-78442.rs:12:2: 12:2 } bb4 (cleanup): { drop(_1) -> bb5;                 // scope 0 at $DIR/issue-78442.rs:12:1: 12:2 } bb5 (cleanup): { resume;                          // scope 0 at $DIR/issue-78442.rs:7:1: 12:2 } } </ins>