Skip to content

Commit

Permalink
Compute indent never relative to current column
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dtolnay committed Jan 31, 2022
1 parent e58e7b1 commit cb93e9c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 19 deletions.
39 changes: 21 additions & 18 deletions compiler/rustc_ast_pretty/src/pp.rs
Expand Up @@ -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;
Expand All @@ -204,6 +204,8 @@ pub struct Printer {
scan_stack: VecDeque<usize>,
/// Stack of blocks-in-progress being flushed by print
print_stack: Vec<PrintFrame>,
/// 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
Expand All @@ -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,
}
Expand Down Expand Up @@ -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;
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Expand Up @@ -655,7 +655,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + 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);
Expand Down

0 comments on commit cb93e9c

Please sign in to comment.