diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
index 1cc049d5a2265..e5be7c0ca76e2 100644
--- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
+++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
@@ -24,6 +24,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
         rvalue: &mut Rvalue<'tcx>,
         location: Location,
     ) {
+        // We don't need to do anything for deref temps as they are
+        // not part of the source code, but used for desugaring purposes.
+        if self.local_decls[place.local].is_deref_temp() {
+            return;
+        }
         let mut place_ty = place.ty(self.local_decls, self.tcx).ty;
         let mut rval_ty = rvalue.ty(self.local_decls, self.tcx);
         // Not erasing this causes `Free Regions` errors in validator,
@@ -48,7 +53,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
 // // gets transformed to
 // let temp: rval_ty = rval;
 // let place: place_ty = temp as place_ty;
-//
 pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let patch = MirPatch::new(body);
     let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 22381844d6dc2..c0a09b7a76127 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -467,7 +467,6 @@ pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
 /// After this series of passes, no lifetime analysis based on borrowing can be done.
 fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let passes: &[&dyn MirPass<'tcx>] = &[
-        &add_subtyping_projections::Subtyper,
         &cleanup_post_borrowck::CleanupPostBorrowck,
         &remove_noop_landing_pads::RemoveNoopLandingPads,
         &simplify::SimplifyCfg::EarlyOpt,
@@ -483,6 +482,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // These next passes must be executed together
         &add_call_guards::CriticalCallEdges,
         &reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too.
+        &add_subtyping_projections::Subtyper, // calling this after reveal_all ensures that we don't deal with opaque types
         &elaborate_drops::ElaborateDrops,
         // This will remove extraneous landing pads which are no longer
         // necessary as well as well as forcing any call in a non-unwinding
diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs
index 55f1eac6f8468..1626cf3c035e6 100644
--- a/compiler/rustc_mir_transform/src/reveal_all.rs
+++ b/compiler/rustc_mir_transform/src/reveal_all.rs
@@ -46,16 +46,18 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
                 .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
                 .collect::<Vec<_>>(),
         );
+        self.super_place(place, _context, _location);
     }
 
     #[inline]
-    fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) {
+    fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
         // We have to use `try_normalize_erasing_regions` here, since it's
         // possible that we visit impossible-to-satisfy where clauses here,
         // see #91745
         if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) {
             constant.const_ = c;
         }
+        self.super_constant(constant, location);
     }
 
     #[inline]
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
index d592ddfd183a0..06ee8c464d5ba 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
@@ -7,12 +7,11 @@
       let mut _2: std::pin::Pin<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>;
       let mut _3: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
       let mut _4: {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+     let mut _6: bool;
++     let mut _5: bool;
       scope 1 {
           debug _r => _1;
       }
 +     scope 2 (inlined g) {
-+         let mut _5: {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +     }
 +     scope 3 (inlined Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new) {
 +         debug pointer => _3;
@@ -23,10 +22,10 @@
 +         }
 +     }
 +     scope 6 (inlined g::{closure#0}) {
-+         debug a => _6;
-+         let mut _7: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+         let mut _8: u32;
-+         let mut _9: i32;
++         debug a => _5;
++         let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
++         let mut _7: u32;
++         let mut _8: i32;
 +     }
   
       bb0: {
@@ -35,28 +34,25 @@
           StorageLive(_3);
           StorageLive(_4);
 -         _4 = g() -> [return: bb1, unwind unreachable];
-+         StorageLive(_5);
-+         _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
-+         _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         StorageDead(_5);
++         _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
 +         _3 = &mut _4;
 +         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
 +         StorageDead(_3);
++         StorageLive(_5);
++         _5 = const false;
 +         StorageLive(_6);
-+         _6 = const false;
 +         StorageLive(_7);
-+         StorageLive(_8);
-+         _7 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         _8 = discriminant((*_7));
-+         switchInt(move _8) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
++         _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _7 = discriminant((*_6));
++         switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
       }
   
       bb1: {
 -         _3 = &mut _4;
 -         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind unreachable];
-+         StorageDead(_8);
 +         StorageDead(_7);
 +         StorageDead(_6);
++         StorageDead(_5);
 +         StorageDead(_2);
 +         drop(_4) -> [return: bb2, unwind unreachable];
       }
@@ -73,8 +69,8 @@
       bb3: {
 -         StorageDead(_2);
 -         drop(_4) -> [return: bb4, unwind unreachable];
-+         StorageLive(_9);
-+         switchInt(_6) -> [0: bb4, otherwise: bb5];
++         StorageLive(_8);
++         switchInt(_5) -> [0: bb4, otherwise: bb5];
       }
   
       bb4: {
@@ -82,18 +78,18 @@
 -         _0 = const ();
 -         StorageDead(_1);
 -         return;
-+         _9 = const 13_i32;
++         _8 = const 13_i32;
 +         goto -> bb6;
 +     }
 + 
 +     bb5: {
-+         _9 = const 7_i32;
++         _8 = const 7_i32;
 +         goto -> bb6;
 +     }
 + 
 +     bb6: {
-+         _1 = GeneratorState::<i32, bool>::Yielded(move _9);
-+         discriminant((*_7)) = 3;
++         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
++         discriminant((*_6)) = 3;
 +         goto -> bb1;
 +     }
 + 
@@ -102,10 +98,10 @@
 +     }
 + 
 +     bb8: {
-+         StorageLive(_9);
-+         StorageDead(_9);
-+         _1 = GeneratorState::<i32, bool>::Complete(_6);
-+         discriminant((*_7)) = 1;
++         StorageLive(_8);
++         StorageDead(_8);
++         _1 = GeneratorState::<i32, bool>::Complete(_5);
++         discriminant((*_6)) = 1;
 +         goto -> bb1;
 +     }
 + 
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
index 120aa52ac0129..da29ba5f50d73 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
@@ -7,12 +7,11 @@
       let mut _2: std::pin::Pin<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>;
       let mut _3: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
       let mut _4: {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+     let mut _6: bool;
++     let mut _5: bool;
       scope 1 {
           debug _r => _1;
       }
 +     scope 2 (inlined g) {
-+         let mut _5: {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +     }
 +     scope 3 (inlined Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new) {
 +         debug pointer => _3;
@@ -23,10 +22,10 @@
 +         }
 +     }
 +     scope 6 (inlined g::{closure#0}) {
-+         debug a => _6;
-+         let mut _7: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+         let mut _8: u32;
-+         let mut _9: i32;
++         debug a => _5;
++         let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
++         let mut _7: u32;
++         let mut _8: i32;
 +     }
   
       bb0: {
@@ -38,10 +37,7 @@
 -     }
 - 
 -     bb1: {
-+         StorageLive(_5);
-+         _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
-+         _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         StorageDead(_5);
++         _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
           _3 = &mut _4;
 -         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind: bb5];
 -     }
@@ -50,20 +46,20 @@
 +         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
           StorageDead(_3);
 -         _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
++         StorageLive(_5);
++         _5 = const false;
 +         StorageLive(_6);
-+         _6 = const false;
 +         StorageLive(_7);
-+         StorageLive(_8);
-+         _7 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         _8 = discriminant((*_7));
-+         switchInt(move _8) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
++         _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _7 = discriminant((*_6));
++         switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
       }
   
 -     bb3: {
 +     bb1: {
-+         StorageDead(_8);
 +         StorageDead(_7);
 +         StorageDead(_6);
++         StorageDead(_5);
           StorageDead(_2);
 -         drop(_4) -> [return: bb4, unwind: bb6];
 +         drop(_4) -> [return: bb2, unwind: bb4];
@@ -89,23 +85,23 @@
 +     }
 + 
 +     bb5: {
-+         StorageLive(_9);
-+         switchInt(_6) -> [0: bb6, otherwise: bb7];
++         StorageLive(_8);
++         switchInt(_5) -> [0: bb6, otherwise: bb7];
 +     }
 + 
 +     bb6: {
-+         _9 = const 13_i32;
++         _8 = const 13_i32;
 +         goto -> bb8;
 +     }
 + 
 +     bb7: {
-+         _9 = const 7_i32;
++         _8 = const 7_i32;
 +         goto -> bb8;
 +     }
 + 
 +     bb8: {
-+         _1 = GeneratorState::<i32, bool>::Yielded(move _9);
-+         discriminant((*_7)) = 3;
++         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
++         discriminant((*_6)) = 3;
 +         goto -> bb1;
 +     }
 + 
@@ -114,10 +110,10 @@
 +     }
 + 
 +     bb10: {
-+         StorageLive(_9);
-+         StorageDead(_9);
-+         _1 = GeneratorState::<i32, bool>::Complete(_6);
-+         discriminant((*_7)) = 1;
++         StorageLive(_8);
++         StorageDead(_8);
++         _1 = GeneratorState::<i32, bool>::Complete(_5);
++         discriminant((*_6)) = 1;
 +         goto -> bb1;
 +     }
 + 
diff --git a/tests/ui/impl-trait/impl-subtyper.rs b/tests/ui/impl-trait/impl-subtyper.rs
new file mode 100644
index 0000000000000..2d99cdd4f506e
--- /dev/null
+++ b/tests/ui/impl-trait/impl-subtyper.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![crate_type = "lib"]
+fn checkpoints() -> impl Iterator {
+    Some(()).iter().flat_map(|_| std::iter::once(()))
+}
+
+fn block_checkpoints() -> impl Iterator {
+    checkpoints()
+}
+
+fn iter_raw() -> impl Iterator {
+    let mut iter = block_checkpoints();
+
+    (0..9).map(move |_| {
+        iter.next();
+    })
+}
diff --git a/tests/ui/impl-trait/impl-subtyper2.rs b/tests/ui/impl-trait/impl-subtyper2.rs
new file mode 100644
index 0000000000000..2e0acbae68b82
--- /dev/null
+++ b/tests/ui/impl-trait/impl-subtyper2.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+fn ages() -> Option<impl Iterator> {
+    None::<std::slice::Iter<()>>
+}
+
+fn main(){}
diff --git a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs
new file mode 100644
index 0000000000000..7c62002b931be
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs
@@ -0,0 +1,32 @@
+// check-pass
+// compile-flags: -Z mir-opt-level=3
+#![feature(type_alias_impl_trait)]
+#![crate_type = "lib"]
+pub trait Tr {
+    fn get(&self) -> u32;
+}
+
+impl Tr for (u32,) {
+    #[inline]
+    fn get(&self) -> u32 { self.0 }
+}
+
+pub fn tr1() -> impl Tr {
+    (32,)
+}
+
+pub fn tr2() -> impl Tr {
+    struct Inner {
+        x: X,
+    }
+    type X = impl Tr;
+    impl Tr for Inner {
+        fn get(&self) -> u32 {
+            self.x.get()
+        }
+    }
+
+    Inner {
+        x: tr1(),
+    }
+}
diff --git a/tests/ui/type-alias-impl-trait/tait-normalize.rs b/tests/ui/type-alias-impl-trait/tait-normalize.rs
new file mode 100644
index 0000000000000..26d94dbb42a36
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/tait-normalize.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+fn enum_upvar() {
+    type T = impl Copy;
+    let foo: T = Some((1u32, 2u32));
+    let x = move || match foo {
+        None => (),
+        Some((a, b)) => (),
+    };
+}
+
+fn main(){}
diff --git a/tests/ui/type/subtyping-opaque-type.rs b/tests/ui/type/subtyping-opaque-type.rs
new file mode 100644
index 0000000000000..beda232ea8b37
--- /dev/null
+++ b/tests/ui/type/subtyping-opaque-type.rs
@@ -0,0 +1,19 @@
+// check-pass
+// compile-flags: -Zvalidate-mir
+trait Duh {}
+
+impl Duh for i32 {}
+
+trait Trait {
+    type Assoc: Duh;
+}
+
+impl<R: Duh, F: FnMut() -> R> Trait for F {
+    type Assoc = R;
+}
+
+fn foo() -> impl Trait<Assoc = impl Send> {
+    || 42
+}
+
+fn main() {}