about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2022-01-21 13:36:08 -0800
committerDavid Tolnay <dtolnay@gmail.com>2022-02-03 10:59:35 -0800
commit40fcbbafa096944a60169fc8a2f65ba4ab6cadf8 (patch)
tree7594f3fbc17398984882d3866cd29f35eb011cf3
parent63406ac771c08597c870cc7b01ca8d8098ea3a2b (diff)
downloadrust-40fcbbafa096944a60169fc8a2f65ba4ab6cadf8.tar.gz
rust-40fcbbafa096944a60169fc8a2f65ba4ab6cadf8.zip
Change struct expr pretty printing to match rustfmt style
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs3
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/delimited.rs41
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs70
3 files changed, 83 insertions, 31 deletions
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index e88d37ec102..b2c62383fb6 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1,3 +1,4 @@
+mod delimited;
 mod expr;
 mod item;
 
@@ -23,6 +24,8 @@ use rustc_span::{BytePos, FileName, Span};
 
 use std::borrow::Cow;
 
+pub use self::delimited::IterDelimited;
+
 pub enum MacHeader<'a> {
     Path(&'a ast::Path),
     Keyword(&'static str),
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/delimited.rs b/compiler/rustc_ast_pretty/src/pprust/state/delimited.rs
new file mode 100644
index 00000000000..fe0640baaa1
--- /dev/null
+++ b/compiler/rustc_ast_pretty/src/pprust/state/delimited.rs
@@ -0,0 +1,41 @@
+use std::iter::Peekable;
+use std::mem;
+use std::ops::Deref;
+
+pub struct Delimited<I: Iterator> {
+    is_first: bool,
+    iter: Peekable<I>,
+}
+
+pub trait IterDelimited: Iterator + Sized {
+    fn delimited(self) -> Delimited<Self> {
+        Delimited { is_first: true, iter: self.peekable() }
+    }
+}
+
+impl<I: Iterator> IterDelimited for I {}
+
+pub struct IteratorItem<T> {
+    value: T,
+    pub is_first: bool,
+    pub is_last: bool,
+}
+
+impl<I: Iterator> Iterator for Delimited<I> {
+    type Item = IteratorItem<I::Item>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let value = self.iter.next()?;
+        let is_first = mem::replace(&mut self.is_first, false);
+        let is_last = self.iter.peek().is_none();
+        Some(IteratorItem { value, is_first, is_last })
+    }
+}
+
+impl<T> Deref for IteratorItem<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.value
+    }
+}
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 6a5bba30b8b..44116fa76a0 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -1,5 +1,5 @@
-use crate::pp::Breaks::{Consistent, Inconsistent};
-use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
+use crate::pp::Breaks::Inconsistent;
+use crate::pprust::state::{AnnNode, IterDelimited, PrintState, State, INDENT_UNIT};
 
 use rustc_ast::ptr::P;
 use rustc_ast::util::parser::{self, AssocOp, Fixity};
@@ -117,38 +117,46 @@ impl<'a> State<'a> {
         } else {
             self.print_path(path, true, 0);
         }
+        self.nbsp();
         self.word("{");
-        self.commasep_cmnt(
-            Consistent,
-            fields,
-            |s, field| {
-                s.print_outer_attributes(&field.attrs);
-                s.ibox(INDENT_UNIT);
-                if !field.is_shorthand {
-                    s.print_ident(field.ident);
-                    s.word_space(":");
-                }
-                s.print_expr(&field.expr);
-                s.end();
-            },
-            |f| f.span,
-        );
-        match rest {
-            ast::StructRest::Base(_) | ast::StructRest::Rest(_) => {
-                self.ibox(INDENT_UNIT);
-                if !fields.is_empty() {
-                    self.word(",");
-                    self.space();
-                }
-                self.word("..");
-                if let ast::StructRest::Base(ref expr) = *rest {
-                    self.print_expr(expr);
-                }
-                self.end();
+        let has_rest = match rest {
+            ast::StructRest::Base(_) | ast::StructRest::Rest(_) => true,
+            ast::StructRest::None => false,
+        };
+        if fields.is_empty() && !has_rest {
+            self.word("}");
+            return;
+        }
+        self.cbox(0);
+        for field in fields.iter().delimited() {
+            self.maybe_print_comment(field.span.hi());
+            self.print_outer_attributes(&field.attrs);
+            if field.is_first {
+                self.space_if_not_bol();
+            }
+            if !field.is_shorthand {
+                self.print_ident(field.ident);
+                self.word_nbsp(":");
+            }
+            self.print_expr(&field.expr);
+            if !field.is_last || has_rest {
+                self.word_space(",");
+            } else {
+                self.trailing_comma();
             }
-            ast::StructRest::None if !fields.is_empty() => self.word(","),
-            _ => {}
         }
+        if has_rest {
+            if fields.is_empty() {
+                self.space();
+            }
+            self.word("..");
+            if let ast::StructRest::Base(expr) = rest {
+                self.print_expr(expr);
+            }
+            self.space();
+        }
+        self.offset(-INDENT_UNIT);
+        self.end();
         self.word("}");
     }