From 02b01a46de62d26a2769b7546481a6ab08da82b8 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 21 Sep 2023 11:52:06 +0300
Subject: [PATCH 01/13] make region struct and add neccesasry types

---
 compiler/stable_mir/src/ty.rs | 49 +++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 82007e30683..b7cd57f753a 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -1,7 +1,7 @@
 use super::{
     mir::Safety,
     mir::{Body, Mutability},
-    with, AllocId, DefId,
+    with, AllocId, DefId, Symbol,
 };
 use crate::Opaque;
 use std::fmt::{self, Debug, Formatter};
@@ -34,7 +34,52 @@ pub struct Const {
 }
 
 type Ident = Opaque;
-pub type Region = Opaque;
+pub(crate) struct Region {
+    kind: RegionKind,
+}
+
+enum RegionKind {
+    ReEarlyBound(EarlyBoundRegion),
+    ReLateBound(DebruijnIndex, BoundRegion),
+    ReFree(FreeRegion),
+    ReStatic,
+    ReVar(RegionVid),
+    RePlaceholder(Placeholder<BoundRegion>),
+    ReErased,
+    ReError(ErrorGuaranteed),
+}
+
+pub(crate) type DebruijnIndex = u32;
+
+pub struct EarlyBoundRegion {
+    pub def_id: DefId,
+    pub index: u32,
+    pub name: Symbol,
+}
+
+pub(crate) type BoundVar = u32;
+
+pub struct BoundRegion {
+    pub var: BoundVar,
+    pub kind: BoundRegionKind,
+}
+
+pub struct FreeRegion {
+    pub scope: DefId,
+    pub bound_region: BoundRegionKind,
+}
+
+pub(crate) type RegionVid = u32;
+
+pub(crate) type UniverseIndex = u32;
+
+pub struct Placeholder<T> {
+    pub universe: UniverseIndex,
+    pub bound: T,
+}
+
+pub(crate) type ErrorGuaranteed = ();
+
 #[derive(Clone, Copy, PartialEq, Eq)]
 pub struct Span(pub usize);
 

From e49aa04000b3443a8cf1650ee0a75d48ddf115d0 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 21 Sep 2023 12:01:30 +0300
Subject: [PATCH 02/13] add RegionDef

---
 compiler/rustc_smir/src/rustc_internal/mod.rs |  4 +++
 compiler/rustc_smir/src/rustc_smir/mod.rs     | 28 ++++++++++++++++++-
 compiler/stable_mir/src/ty.rs                 |  9 ++++--
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 441aafd1257..1a9dea99f64 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -86,6 +86,10 @@ impl<'tcx> Tables<'tcx> {
         stable_mir::ty::ImplDef(self.create_def_id(did))
     }
 
+    pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef {
+        stable_mir::ty::RegionDef(self.create_def_id(did))
+    }
+
     pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
         stable_mir::ty::Prov(self.create_alloc_id(aid))
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 5ff17613b4e..890faa4538e 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,7 +7,12 @@
 //!
 //! For now, we are developing everything inside `rustc`, thus, we keep this module private.
 
-use hir::def::DefKind;
+use crate::rustc_internal::{self, opaque};
+use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
+use crate::stable_mir::ty::{
+    EarlyBoundRegion, FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy,
+};
+use crate::stable_mir::{self, CompilerError, Context};
 use rustc_hir as hir;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
@@ -1506,6 +1511,27 @@ impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
     }
 }
 
+impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
+    type T = stable_mir::ty::RegionKind;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        match self {
+            ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion {
+                def_id: tables.region_def(early_reg.def_id),
+                index: early_reg.index,
+                name: early_reg.name.to_string(),
+            }),
+            ty::ReLateBound(_, _) => todo!(),
+            ty::ReFree(_) => todo!(),
+            ty::ReStatic => todo!(),
+            ty::ReVar(_) => todo!(),
+            ty::RePlaceholder(_) => todo!(),
+            ty::ReErased => todo!(),
+            ty::ReError(_) => todo!(),
+        }
+    }
+}
+
 impl<'tcx> Stable<'tcx> for rustc_span::Span {
     type T = stable_mir::ty::Span;
 
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index b7cd57f753a..f6f433c2bad 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -38,7 +38,7 @@ pub(crate) struct Region {
     kind: RegionKind,
 }
 
-enum RegionKind {
+pub enum RegionKind {
     ReEarlyBound(EarlyBoundRegion),
     ReLateBound(DebruijnIndex, BoundRegion),
     ReFree(FreeRegion),
@@ -52,7 +52,7 @@ enum RegionKind {
 pub(crate) type DebruijnIndex = u32;
 
 pub struct EarlyBoundRegion {
-    pub def_id: DefId,
+    pub def_id: RegionDef,
     pub index: u32,
     pub name: Symbol,
 }
@@ -65,7 +65,7 @@ pub struct BoundRegion {
 }
 
 pub struct FreeRegion {
-    pub scope: DefId,
+    pub scope: RegionDef,
     pub bound_region: BoundRegionKind,
 }
 
@@ -197,6 +197,9 @@ pub struct ConstDef(pub DefId);
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct ImplDef(pub DefId);
 
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct RegionDef(pub(crate) DefId);
+
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);
 

From 5dc2214884483496ef8cf4a8fa7f1be189669974 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 21 Sep 2023 12:12:06 +0300
Subject: [PATCH 03/13] add stable for RegionKind

---
 compiler/rustc_smir/src/rustc_smir/mod.rs | 37 ++++++++++++++++-------
 compiler/stable_mir/src/ty.rs             |  2 +-
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 890faa4538e..73a4798527d 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -10,7 +10,8 @@
 use crate::rustc_internal::{self, opaque};
 use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
 use crate::stable_mir::ty::{
-    EarlyBoundRegion, FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy,
+    BoundRegion, EarlyBoundRegion, FloatTy, FreeRegion, GenericParamDef, IntTy, Movability, Region,
+    RigidTy, Span, TyKind, UintTy,
 };
 use crate::stable_mir::{self, CompilerError, Context};
 use rustc_hir as hir;
@@ -1505,9 +1506,8 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
 impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
     type T = stable_mir::ty::Region;
 
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
-        // FIXME: add a real implementation of stable regions
-        opaque(self)
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        Region { kind: self.kind().stable(tables) }
     }
 }
 
@@ -1515,19 +1515,34 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
     type T = stable_mir::ty::RegionKind;
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        use crate::stable_mir::ty::RegionKind;
         match self {
             ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion {
                 def_id: tables.region_def(early_reg.def_id),
                 index: early_reg.index,
                 name: early_reg.name.to_string(),
             }),
-            ty::ReLateBound(_, _) => todo!(),
-            ty::ReFree(_) => todo!(),
-            ty::ReStatic => todo!(),
-            ty::ReVar(_) => todo!(),
-            ty::RePlaceholder(_) => todo!(),
-            ty::ReErased => todo!(),
-            ty::ReError(_) => todo!(),
+            ty::ReLateBound(db_index, bound_reg) => RegionKind::ReLateBound(
+                db_index.as_u32(),
+                BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
+            ),
+            ty::ReFree(free_reg) => RegionKind::ReFree(FreeRegion {
+                scope: tables.region_def(free_reg.scope),
+                bound_region: free_reg.bound_region.stable(tables),
+            }),
+            ty::ReStatic => RegionKind::ReStatic,
+            ty::ReVar(vid_reg) => RegionKind::ReVar(vid_reg.as_u32()),
+            ty::RePlaceholder(place_holder) => {
+                RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
+                    universe: place_holder.universe.as_u32(),
+                    bound: BoundRegion {
+                        var: place_holder.bound.var.as_u32(),
+                        kind: place_holder.bound.kind.stable(tables),
+                    },
+                })
+            }
+            ty::ReErased => RegionKind::ReErased,
+            ty::ReError(_) => RegionKind::ReError(()),
         }
     }
 }
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index f6f433c2bad..a47621337f0 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -35,7 +35,7 @@ pub struct Const {
 
 type Ident = Opaque;
 pub(crate) struct Region {
-    kind: RegionKind,
+    pub kind: RegionKind,
 }
 
 pub enum RegionKind {

From d83559939cf89f717d1fcd8266c5f457df6e37dd Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 21 Sep 2023 12:18:10 +0300
Subject: [PATCH 04/13] make reg public and add visit, fold

---
 compiler/stable_mir/src/fold.rs    | 8 +++++++-
 compiler/stable_mir/src/ty.rs      | 9 ++++++++-
 compiler/stable_mir/src/visitor.rs | 8 +++++++-
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs
index 16ae62311aa..edaf55f2aeb 100644
--- a/compiler/stable_mir/src/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -4,7 +4,7 @@ use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
-    GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
+    GenericArgs, Promoted, Region, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
 };
 
 pub trait Folder: Sized {
@@ -106,6 +106,12 @@ impl Foldable for GenericArgs {
     }
 }
 
+impl Foldable for Region {
+    fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
+        ControlFlow::Continue(self.clone())
+    }
+}
+
 impl Foldable for GenericArgKind {
     fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         let mut this = self.clone();
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index a47621337f0..d05fa4a2ed4 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -34,10 +34,13 @@ pub struct Const {
 }
 
 type Ident = Opaque;
-pub(crate) struct Region {
+
+#[derive(Debug, Clone)]
+pub struct Region {
     pub kind: RegionKind,
 }
 
+#[derive(Debug, Clone)]
 pub enum RegionKind {
     ReEarlyBound(EarlyBoundRegion),
     ReLateBound(DebruijnIndex, BoundRegion),
@@ -51,6 +54,7 @@ pub enum RegionKind {
 
 pub(crate) type DebruijnIndex = u32;
 
+#[derive(Debug, Clone)]
 pub struct EarlyBoundRegion {
     pub def_id: RegionDef,
     pub index: u32,
@@ -59,11 +63,13 @@ pub struct EarlyBoundRegion {
 
 pub(crate) type BoundVar = u32;
 
+#[derive(Debug, Clone)]
 pub struct BoundRegion {
     pub var: BoundVar,
     pub kind: BoundRegionKind,
 }
 
+#[derive(Debug, Clone)]
 pub struct FreeRegion {
     pub scope: RegionDef,
     pub bound_region: BoundRegionKind,
@@ -73,6 +79,7 @@ pub(crate) type RegionVid = u32;
 
 pub(crate) type UniverseIndex = u32;
 
+#[derive(Debug, Clone)]
 pub struct Placeholder<T> {
     pub universe: UniverseIndex,
     pub bound: T,
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index 9c3b4cd994a..8d5a25008d7 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -4,7 +4,7 @@ use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
-    Promoted, RigidTy, TermKind, Ty, UnevaluatedConst,
+    Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
 };
 
 pub trait Visitor: Sized {
@@ -101,6 +101,12 @@ impl Visitable for GenericArgs {
     }
 }
 
+impl Visitable for Region {
+    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
+        ControlFlow::Continue(())
+    }
+}
+
 impl Visitable for GenericArgKind {
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         match self {

From 2069e8c218fcc8428ae400fe91b245c977859036 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 11:36:53 +0300
Subject: [PATCH 05/13] fix imports

---
 compiler/rustc_smir/src/rustc_smir/mod.rs | 11 +++--------
 compiler/stable_mir/src/ty.rs             |  2 +-
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 73a4798527d..2623ce8fd11 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,13 +7,8 @@
 //!
 //! For now, we are developing everything inside `rustc`, thus, we keep this module private.
 
-use crate::rustc_internal::{self, opaque};
-use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
-use crate::stable_mir::ty::{
-    BoundRegion, EarlyBoundRegion, FloatTy, FreeRegion, GenericParamDef, IntTy, Movability, Region,
-    RigidTy, Span, TyKind, UintTy,
-};
-use crate::stable_mir::{self, CompilerError, Context};
+use crate::rustc_smir::hir::def::DefKind;
+use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
 use rustc_hir as hir;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
@@ -1515,7 +1510,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
     type T = stable_mir::ty::RegionKind;
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        use crate::stable_mir::ty::RegionKind;
+        use stable_mir::ty::RegionKind;
         match self {
             ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion {
                 def_id: tables.region_def(early_reg.def_id),
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index d05fa4a2ed4..20ef514e4ab 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -205,7 +205,7 @@ pub struct ConstDef(pub DefId);
 pub struct ImplDef(pub DefId);
 
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub struct RegionDef(pub(crate) DefId);
+pub struct RegionDef(pub DefId);
 
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);

From da2f897e590be03eb4acddfd9df804545b738b65 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 11:43:21 +0300
Subject: [PATCH 06/13] remove un-needed variants

---
 compiler/rustc_smir/src/rustc_smir/mod.rs |  9 ++-------
 compiler/stable_mir/src/ty.rs             | 13 -------------
 2 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 2623ce8fd11..3b6bacaa168 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -8,7 +8,7 @@
 //! For now, we are developing everything inside `rustc`, thus, we keep this module private.
 
 use crate::rustc_smir::hir::def::DefKind;
-use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
+use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
 use rustc_hir as hir;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
@@ -1521,12 +1521,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
                 db_index.as_u32(),
                 BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
             ),
-            ty::ReFree(free_reg) => RegionKind::ReFree(FreeRegion {
-                scope: tables.region_def(free_reg.scope),
-                bound_region: free_reg.bound_region.stable(tables),
-            }),
             ty::ReStatic => RegionKind::ReStatic,
-            ty::ReVar(vid_reg) => RegionKind::ReVar(vid_reg.as_u32()),
             ty::RePlaceholder(place_holder) => {
                 RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
                     universe: place_holder.universe.as_u32(),
@@ -1537,7 +1532,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
                 })
             }
             ty::ReErased => RegionKind::ReErased,
-            ty::ReError(_) => RegionKind::ReError(()),
+            _=> unimplemented!()
         }
     }
 }
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 20ef514e4ab..6029e3c11ad 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -44,12 +44,9 @@ pub struct Region {
 pub enum RegionKind {
     ReEarlyBound(EarlyBoundRegion),
     ReLateBound(DebruijnIndex, BoundRegion),
-    ReFree(FreeRegion),
     ReStatic,
-    ReVar(RegionVid),
     RePlaceholder(Placeholder<BoundRegion>),
     ReErased,
-    ReError(ErrorGuaranteed),
 }
 
 pub(crate) type DebruijnIndex = u32;
@@ -69,14 +66,6 @@ pub struct BoundRegion {
     pub kind: BoundRegionKind,
 }
 
-#[derive(Debug, Clone)]
-pub struct FreeRegion {
-    pub scope: RegionDef,
-    pub bound_region: BoundRegionKind,
-}
-
-pub(crate) type RegionVid = u32;
-
 pub(crate) type UniverseIndex = u32;
 
 #[derive(Debug, Clone)]
@@ -85,8 +74,6 @@ pub struct Placeholder<T> {
     pub bound: T,
 }
 
-pub(crate) type ErrorGuaranteed = ();
-
 #[derive(Clone, Copy, PartialEq, Eq)]
 pub struct Span(pub usize);
 

From bb17fe8bf5b32cd7fefbab95b6b1b7ee04628dbd Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 12:32:15 +0300
Subject: [PATCH 07/13] add real folder to Region

---
 compiler/rustc_smir/src/rustc_smir/mod.rs |  2 +-
 compiler/stable_mir/src/fold.rs           | 41 +++++++++++++++++++++--
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 3b6bacaa168..128ba076544 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -1532,7 +1532,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
                 })
             }
             ty::ReErased => RegionKind::ReErased,
-            _=> unimplemented!()
+            _ => unimplemented!(),
         }
     }
 }
diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs
index edaf55f2aeb..bdc80bc8aa3 100644
--- a/compiler/stable_mir/src/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -1,6 +1,9 @@
 use std::ops::ControlFlow;
 
-use crate::Opaque;
+use crate::{
+    ty::{self, BoundRegion, BoundRegionKind},
+    Opaque,
+};
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
@@ -15,6 +18,9 @@ pub trait Folder: Sized {
     fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
         c.super_fold(self)
     }
+    fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break, Region> {
+        reg.super_fold(self)
+    }
 }
 
 pub trait Foldable: Sized + Clone {
@@ -107,8 +113,39 @@ impl Foldable for GenericArgs {
 }
 
 impl Foldable for Region {
+    fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
+        folder.visit_reg(self)
+    }
+    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
+        let mut kind = self.kind.clone();
+        match &mut kind {
+            crate::ty::RegionKind::ReEarlyBound(_) => {}
+            crate::ty::RegionKind::ReLateBound(_, bound_reg) => {
+                *bound_reg = bound_reg.fold(folder)?
+            }
+            crate::ty::RegionKind::ReStatic => {}
+            crate::ty::RegionKind::RePlaceholder(bound_reg) => {
+                bound_reg.bound = bound_reg.bound.fold(folder)?
+            }
+            crate::ty::RegionKind::ReErased => {}
+        }
+        ControlFlow::Continue(ty::Region { kind: kind }.into())
+    }
+}
+
+impl Foldable for BoundRegion {
+    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
+        ControlFlow::Continue(BoundRegion { var: self.var, kind: self.kind.fold(folder)? })
+    }
+}
+
+impl Foldable for BoundRegionKind {
     fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(self.clone())
+        match self {
+            BoundRegionKind::BrAnon => ControlFlow::Continue(self.clone()),
+            BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(self.clone()),
+            BoundRegionKind::BrEnv => ControlFlow::Continue(self.clone()),
+        }
     }
 }
 

From fed72e06644db562c043f2f9cec99f2b2d9cba9d Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 12:47:21 +0300
Subject: [PATCH 08/13] add visitor for Region

---
 compiler/stable_mir/src/visitor.rs | 37 ++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index 8d5a25008d7..a26a1d8cfb9 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -1,6 +1,9 @@
 use std::ops::ControlFlow;
 
-use crate::Opaque;
+use crate::{
+    ty::{BoundRegion, BoundRegionKind},
+    Opaque,
+};
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
@@ -15,6 +18,9 @@ pub trait Visitor: Sized {
     fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> {
         c.super_visit(self)
     }
+    fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break> {
+        reg.super_visit(self)
+    }
 }
 
 pub trait Visitable {
@@ -102,11 +108,38 @@ impl Visitable for GenericArgs {
 }
 
 impl Visitable for Region {
-    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
+    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        visitor.visit_reg(self)
+    }
+
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match self.kind.clone() {
+            crate::ty::RegionKind::ReEarlyBound(_) => {}
+            crate::ty::RegionKind::ReLateBound(_, bound_reg) => bound_reg.visit(visitor)?,
+            crate::ty::RegionKind::ReStatic => {}
+            crate::ty::RegionKind::RePlaceholder(bound_reg) => bound_reg.bound.visit(visitor)?,
+            crate::ty::RegionKind::ReErased => {}
+        }
         ControlFlow::Continue(())
     }
 }
 
+impl Visitable for BoundRegion {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        self.kind.visit(visitor)
+    }
+}
+
+impl Visitable for BoundRegionKind {
+    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
+        match self {
+            BoundRegionKind::BrAnon => ControlFlow::Continue(()),
+            BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(()),
+            BoundRegionKind::BrEnv => ControlFlow::Continue(()),
+        }
+    }
+}
+
 impl Visitable for GenericArgKind {
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         match self {

From 9f2e15d2328df0d32c5515c7b9a922b810403982 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 19:21:12 +0300
Subject: [PATCH 09/13] change visit to fold for ty and reg

---
 compiler/stable_mir/src/fold.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs
index bdc80bc8aa3..90853c104bb 100644
--- a/compiler/stable_mir/src/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -12,13 +12,13 @@ use super::ty::{
 
 pub trait Folder: Sized {
     type Break;
-    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
+    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
         ty.super_fold(self)
     }
     fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
         c.super_fold(self)
     }
-    fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break, Region> {
+    fn fold_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break, Region> {
         reg.super_fold(self)
     }
 }
@@ -32,7 +32,7 @@ pub trait Foldable: Sized + Clone {
 
 impl Foldable for Ty {
     fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        folder.visit_ty(self)
+        folder.fold_ty(self)
     }
     fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         let mut kind = self.kind();
@@ -114,7 +114,7 @@ impl Foldable for GenericArgs {
 
 impl Foldable for Region {
     fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        folder.visit_reg(self)
+        folder.fold_reg(self)
     }
     fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         let mut kind = self.kind.clone();
@@ -257,7 +257,7 @@ pub enum Never {}
 impl Folder for GenericArgs {
     type Break = Never;
 
-    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
+    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
         ControlFlow::Continue(match ty.kind() {
             TyKind::Param(p) => self[p],
             _ => *ty,

From 8c41cd0d78caed65ebd2f057d5209fc564f9cc10 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 19:43:28 +0300
Subject: [PATCH 10/13] simplify fold

---
 compiler/stable_mir/src/fold.rs | 37 +++------------------------------
 1 file changed, 3 insertions(+), 34 deletions(-)

diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs
index 90853c104bb..65b743811ce 100644
--- a/compiler/stable_mir/src/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -1,9 +1,6 @@
 use std::ops::ControlFlow;
 
-use crate::{
-    ty::{self, BoundRegion, BoundRegionKind},
-    Opaque,
-};
+use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
@@ -116,36 +113,8 @@ impl Foldable for Region {
     fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         folder.fold_reg(self)
     }
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let mut kind = self.kind.clone();
-        match &mut kind {
-            crate::ty::RegionKind::ReEarlyBound(_) => {}
-            crate::ty::RegionKind::ReLateBound(_, bound_reg) => {
-                *bound_reg = bound_reg.fold(folder)?
-            }
-            crate::ty::RegionKind::ReStatic => {}
-            crate::ty::RegionKind::RePlaceholder(bound_reg) => {
-                bound_reg.bound = bound_reg.bound.fold(folder)?
-            }
-            crate::ty::RegionKind::ReErased => {}
-        }
-        ControlFlow::Continue(ty::Region { kind: kind }.into())
-    }
-}
-
-impl Foldable for BoundRegion {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(BoundRegion { var: self.var, kind: self.kind.fold(folder)? })
-    }
-}
-
-impl Foldable for BoundRegionKind {
-    fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        match self {
-            BoundRegionKind::BrAnon => ControlFlow::Continue(self.clone()),
-            BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(self.clone()),
-            BoundRegionKind::BrEnv => ControlFlow::Continue(self.clone()),
-        }
+    fn super_fold<V: Folder>(&self, _: &mut V) -> ControlFlow<V::Break, Self> {
+        ControlFlow::Continue(self.clone())
     }
 }
 

From 0cca109473161c5c71de53d8ea0c9b7ff0a9b5c4 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 19:46:39 +0300
Subject: [PATCH 11/13] visit and fold ty::ref

---
 compiler/stable_mir/src/fold.rs    | 5 ++++-
 compiler/stable_mir/src/visitor.rs | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs
index 65b743811ce..4e0b4bc7a73 100644
--- a/compiler/stable_mir/src/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -148,7 +148,10 @@ impl Foldable for RigidTy {
             }
             RigidTy::Slice(inner) => *inner = inner.fold(folder)?,
             RigidTy::RawPtr(ty, _) => *ty = ty.fold(folder)?,
-            RigidTy::Ref(_, ty, _) => *ty = ty.fold(folder)?,
+            RigidTy::Ref(reg, ty, _) => {
+                *reg = reg.fold(folder)?;
+                *ty = ty.fold(folder)?
+            }
             RigidTy::FnDef(_, args) => *args = args.fold(folder)?,
             RigidTy::FnPtr(sig) => *sig = sig.fold(folder)?,
             RigidTy::Closure(_, args) => *args = args.fold(folder)?,
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index a26a1d8cfb9..848a3114b6b 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -167,7 +167,10 @@ impl Visitable for RigidTy {
             }
             RigidTy::Slice(inner) => inner.visit(visitor),
             RigidTy::RawPtr(ty, _) => ty.visit(visitor),
-            RigidTy::Ref(_, ty, _) => ty.visit(visitor),
+            RigidTy::Ref(reg, ty, _) => {
+                reg.visit(visitor);
+                ty.visit(visitor)
+            }
             RigidTy::FnDef(_, args) => args.visit(visitor),
             RigidTy::FnPtr(sig) => sig.visit(visitor),
             RigidTy::Closure(_, args) => args.visit(visitor),

From eb779038de59e028ebbd6533072acec7b5fc98af Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 19:51:49 +0300
Subject: [PATCH 12/13] simplify visit

---
 compiler/stable_mir/src/visitor.rs | 30 ++----------------------------
 1 file changed, 2 insertions(+), 28 deletions(-)

diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index 848a3114b6b..96100958138 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -1,9 +1,6 @@
 use std::ops::ControlFlow;
 
-use crate::{
-    ty::{BoundRegion, BoundRegionKind},
-    Opaque,
-};
+use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
@@ -112,34 +109,11 @@ impl Visitable for Region {
         visitor.visit_reg(self)
     }
 
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match self.kind.clone() {
-            crate::ty::RegionKind::ReEarlyBound(_) => {}
-            crate::ty::RegionKind::ReLateBound(_, bound_reg) => bound_reg.visit(visitor)?,
-            crate::ty::RegionKind::ReStatic => {}
-            crate::ty::RegionKind::RePlaceholder(bound_reg) => bound_reg.bound.visit(visitor)?,
-            crate::ty::RegionKind::ReErased => {}
-        }
+    fn super_visit<V: Visitor>(&self, _: &mut V) -> ControlFlow<V::Break> {
         ControlFlow::Continue(())
     }
 }
 
-impl Visitable for BoundRegion {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        self.kind.visit(visitor)
-    }
-}
-
-impl Visitable for BoundRegionKind {
-    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
-        match self {
-            BoundRegionKind::BrAnon => ControlFlow::Continue(()),
-            BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(()),
-            BoundRegionKind::BrEnv => ControlFlow::Continue(()),
-        }
-    }
-}
-
 impl Visitable for GenericArgKind {
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         match self {

From 34f10e2ab98622e42c38c97530070aa69ad51d86 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 28 Sep 2023 19:52:41 +0300
Subject: [PATCH 13/13] remove unimplemented

---
 compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 128ba076544..c6c97ce35e8 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -1532,7 +1532,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
                 })
             }
             ty::ReErased => RegionKind::ReErased,
-            _ => unimplemented!(),
+            _ => unreachable!("{self:?}"),
         }
     }
 }