diff --git a/src/items.rs b/src/items.rs
index 28dfb718af6..7c9b7a235fb 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -522,21 +522,22 @@ impl<'a> FmtVisitor<'a> {
         self.push_rewrite(struct_parts.span, rewrite);
     }
 
-    pub(crate) fn visit_enum(
+    // TODO(ding-young) do I need to make it a separate function instead of a method of FmtVisitor?
+    fn format_enum(
         &mut self,
         ident: symbol::Ident,
         vis: &ast::Visibility,
         enum_def: &ast::EnumDef,
         generics: &ast::Generics,
         span: Span,
-    ) {
+    ) -> Option<String> {
         let enum_header =
             format_header(&self.get_context(), "enum ", ident, vis, self.block_indent);
-        self.push_str(&enum_header);
 
         let enum_snippet = self.snippet(span);
         let brace_pos = enum_snippet.find_uncommented("{").unwrap();
         let body_start = span.lo() + BytePos(brace_pos as u32 + 1);
+        // TODO(ding-young) what if there is no generic?
         let generics_str = format_generics(
             &self.get_context(),
             generics,
@@ -550,21 +551,36 @@ impl<'a> FmtVisitor<'a> {
             // make a span that starts right after `enum Foo`
             mk_sp(ident.span.hi(), body_start),
             last_line_width(&enum_header),
-        )
-        .unwrap();
-        self.push_str(&generics_str);
-
-        self.last_pos = body_start;
+        )?;
 
         match self.format_variant_list(enum_def, body_start, span.hi()) {
-            Some(ref s) if enum_def.variants.is_empty() => self.push_str(s),
-            rw => {
-                self.push_rewrite(mk_sp(body_start, span.hi()), rw);
+            Some(ref s) if enum_def.variants.is_empty() => {
+                Some(format!("{enum_header}{generics_str}{s}"))
+            }
+            Some(rw) => {
+                let indent = self.block_indent.to_string(self.config);
                 self.block_indent = self.block_indent.block_unindent(self.config);
+                Some(format!("{enum_header}{generics_str}\n{indent}{rw}"))
+            }
+            None => {
+                self.block_indent = self.block_indent.block_unindent(self.config);
+                None
             }
         }
     }
 
+    pub(crate) fn visit_enum(
+        &mut self,
+        ident: symbol::Ident,
+        vis: &ast::Visibility,
+        enum_def: &ast::EnumDef,
+        generics: &ast::Generics,
+        span: Span,
+    ) {
+        let rewrite = self.format_enum(ident, vis, enum_def, generics, span);
+        self.push_rewrite(span, rewrite);
+    }
+
     // Format the body of an enum definition
     fn format_variant_list(
         &mut self,
diff --git a/src/visitor.rs b/src/visitor.rs
index fb94819c56f..301cc088699 100644
--- a/src/visitor.rs
+++ b/src/visitor.rs
@@ -515,9 +515,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     self.visit_struct(&StructParts::from_item(item));
                 }
                 ast::ItemKind::Enum(ref def, ref generics) => {
-                    self.format_missing_with_indent(source!(self, item.span).lo());
                     self.visit_enum(item.ident, &item.vis, def, generics, item.span);
-                    self.last_pos = source!(self, item.span).hi();
                 }
                 ast::ItemKind::Mod(safety, ref mod_kind) => {
                     self.format_missing_with_indent(source!(self, item.span).lo());
diff --git a/tests/source/crash-on-enum-generics/issue_5738.rs b/tests/source/crash-on-enum-generics/issue_5738.rs
new file mode 100644
index 00000000000..70d211f0e81
--- /dev/null
+++ b/tests/source/crash-on-enum-generics/issue_5738.rs
@@ -0,0 +1,13 @@
+enum Node where P::<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S>>>>>>>>>>>>>>>>>>>>>>>>:  {
+    Cons,
+}
+
+enum En6
+where
+    T: Tr1<En2<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S>>>>>>>>>>>>>>>>>>>>>>>>,
+{
+    V0,
+    V1,
+        V2, // left unformatted since formatting where clause fails
+    V3,
+}
diff --git a/tests/source/crash-on-enum-generics/issue_6137.rs b/tests/source/crash-on-enum-generics/issue_6137.rs
new file mode 100644
index 00000000000..a8c75f8e179
--- /dev/null
+++ b/tests/source/crash-on-enum-generics/issue_6137.rs
@@ -0,0 +1,3 @@
+enum MZReaderType<
+    D: DeconvolutedCentroidLike + Default + From<DeconvolutedPeak> + BuildFromArrayMap=DeconvolutedPeak
+> {}
diff --git a/tests/source/crash-on-enum-generics/issue_6318.rs b/tests/source/crash-on-enum-generics/issue_6318.rs
new file mode 100644
index 00000000000..73471f3eee1
--- /dev/null
+++ b/tests/source/crash-on-enum-generics/issue_6318.rs
@@ -0,0 +1,14 @@
+// rustfmt-max_width: 80
+fn my_fn() {
+    enum MyEnum
+    where
+    SomeTypeA___: SomeTrait__<
+            _A,
+            Archived = <SomeTypeB____ as SomeTrait__<
+                Option<[u8; 4]>,
+            >>::Archived,
+        >,
+    // left unformatted since formatting where clause fails 
+    {
+    }
+}
diff --git a/tests/target/crash-on-enum-generics/issue_5738.rs b/tests/target/crash-on-enum-generics/issue_5738.rs
new file mode 100644
index 00000000000..70d211f0e81
--- /dev/null
+++ b/tests/target/crash-on-enum-generics/issue_5738.rs
@@ -0,0 +1,13 @@
+enum Node where P::<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S>>>>>>>>>>>>>>>>>>>>>>>>:  {
+    Cons,
+}
+
+enum En6
+where
+    T: Tr1<En2<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S>>>>>>>>>>>>>>>>>>>>>>>>,
+{
+    V0,
+    V1,
+        V2, // left unformatted since formatting where clause fails
+    V3,
+}
diff --git a/tests/target/crash-on-enum-generics/issue_6137.rs b/tests/target/crash-on-enum-generics/issue_6137.rs
new file mode 100644
index 00000000000..a8c75f8e179
--- /dev/null
+++ b/tests/target/crash-on-enum-generics/issue_6137.rs
@@ -0,0 +1,3 @@
+enum MZReaderType<
+    D: DeconvolutedCentroidLike + Default + From<DeconvolutedPeak> + BuildFromArrayMap=DeconvolutedPeak
+> {}
diff --git a/tests/target/crash-on-enum-generics/issue_6318.rs b/tests/target/crash-on-enum-generics/issue_6318.rs
new file mode 100644
index 00000000000..73471f3eee1
--- /dev/null
+++ b/tests/target/crash-on-enum-generics/issue_6318.rs
@@ -0,0 +1,14 @@
+// rustfmt-max_width: 80
+fn my_fn() {
+    enum MyEnum
+    where
+    SomeTypeA___: SomeTrait__<
+            _A,
+            Archived = <SomeTypeB____ as SomeTrait__<
+                Option<[u8; 4]>,
+            >>::Archived,
+        >,
+    // left unformatted since formatting where clause fails 
+    {
+    }
+}