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 { 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::>>>>>>>>>>>>>>>>>>>>>>>: { + Cons, +} + +enum En6 +where + T: Tr1>>>>>>>>>>>>>>>>>>>>>>>, +{ + 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 + 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 = , + >>::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::>>>>>>>>>>>>>>>>>>>>>>>: { + Cons, +} + +enum En6 +where + T: Tr1>>>>>>>>>>>>>>>>>>>>>>>, +{ + 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 + 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 = , + >>::Archived, + >, + // left unformatted since formatting where clause fails + { + } +}