From cb93e9c0ec6058df03e163fd7b3e652f7f22041d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 21 Jan 2022 01:34:19 -0800 Subject: [PATCH] Compute indent never relative to current column Previously the pretty printer would compute indentation always relative to whatever column a block begins at, like this: fn demo(arg1: usize, arg2: usize); This is never the thing to do in the dominant contemporary Rust style. Rustfmt's default and the style used by the vast majority of Rust codebases is block indentation: fn demo( arg1: usize, arg2: usize, ); where every indentation level is a multiple of 4 spaces and each level is indented relative to the indentation of the previous line, not the position that the block starts in. --- compiler/rustc_ast_pretty/src/pp.rs | 39 ++++++++++--------- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index d41cebc98df3c..78b519651644a 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -178,7 +178,7 @@ impl Token { #[derive(Copy, Clone)] enum PrintFrame { Fits, - Broken { offset: isize, breaks: Breaks }, + Broken { indent: usize, breaks: Breaks }, } const SIZE_INFINITY: isize = 0xffff; @@ -204,6 +204,8 @@ pub struct Printer { scan_stack: VecDeque, /// Stack of blocks-in-progress being flushed by print print_stack: Vec, + /// Level of indentation of current line + indent: usize, /// Buffered indentation to avoid writing trailing whitespace pending_indentation: isize, /// The token most recently popped from the left boundary of the @@ -229,6 +231,7 @@ impl Printer { right_total: 0, scan_stack: VecDeque::new(), print_stack: Vec::new(), + indent: 0, pending_indentation: 0, last_printed: None, } @@ -368,38 +371,38 @@ impl Printer { *self .print_stack .last() - .unwrap_or(&PrintFrame::Broken { offset: 0, breaks: Breaks::Inconsistent }) + .unwrap_or(&PrintFrame::Broken { indent: 0, breaks: Breaks::Inconsistent }) } fn print_begin(&mut self, token: BeginToken, size: isize) { if size > self.space { - let col = self.margin - self.space + token.offset; - self.print_stack.push(PrintFrame::Broken { offset: col, breaks: token.breaks }); + self.print_stack.push(PrintFrame::Broken { indent: self.indent, breaks: token.breaks }); + self.indent = (self.indent as isize + token.offset) as usize; } else { self.print_stack.push(PrintFrame::Fits); } } fn print_end(&mut self) { - self.print_stack.pop().unwrap(); + if let PrintFrame::Broken { indent, .. } = self.print_stack.pop().unwrap() { + self.indent = indent; + } } fn print_break(&mut self, token: BreakToken, size: isize) { - let break_offset = - match self.get_top() { - PrintFrame::Fits => None, - PrintFrame::Broken { offset, breaks: Breaks::Consistent } => Some(offset), - PrintFrame::Broken { offset, breaks: Breaks::Inconsistent } => { - if size > self.space { Some(offset) } else { None } - } - }; - if let Some(offset) = break_offset { - self.out.push('\n'); - self.pending_indentation = offset + token.offset; - self.space = self.margin - (offset + token.offset); - } else { + let fits = match self.get_top() { + PrintFrame::Fits => true, + PrintFrame::Broken { breaks: Breaks::Consistent, .. } => false, + PrintFrame::Broken { breaks: Breaks::Inconsistent, .. } => size <= self.space, + }; + if fits { self.pending_indentation += token.blank_space; self.space -= token.blank_space; + } else { + self.out.push('\n'); + let indent = self.indent as isize + token.offset; + self.pending_indentation = indent; + self.space = self.margin - indent; } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 96dbd3dca156e..dff85f52b15c8 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -655,7 +655,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere // Outer-box is consistent. self.cbox(INDENT_UNIT); // Head-box is inconsistent. - self.ibox(w.len() + 1); + self.ibox(0); // Keyword that starts the head. if !w.is_empty() { self.word_nbsp(w);