From fdb95f54e81532f5a620e79b8930f89e0e9aee80 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:02:49 -0800 Subject: [PATCH 01/15] Inline Printer's advance_right method --- compiler/rustc_ast_pretty/src/pp.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 25437f8b53a94..785125ccafcc5 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -290,7 +290,8 @@ impl Printer { self.right = self.left; self.buf.truncate(1); } else { - self.advance_right(); + self.right += 1; + self.buf.advance_right(); } self.scan_push(BufEntry { token: Token::Begin(b), size: -self.right_total }); } @@ -299,7 +300,8 @@ impl Printer { if self.scan_stack.is_empty() { self.print_end(); } else { - self.advance_right(); + self.right += 1; + self.buf.advance_right(); self.scan_push(BufEntry { token: Token::End, size: -1 }); } } @@ -311,7 +313,8 @@ impl Printer { self.right = self.left; self.buf.truncate(1); } else { - self.advance_right(); + self.right += 1; + self.buf.advance_right(); } self.check_stack(0); self.scan_push(BufEntry { token: Token::Break(b), size: -self.right_total }); @@ -322,7 +325,8 @@ impl Printer { if self.scan_stack.is_empty() { self.print_string(s); } else { - self.advance_right(); + self.right += 1; + self.buf.advance_right(); let len = s.len() as isize; self.buf[self.right] = BufEntry { token: Token::String(s), size: len }; self.right_total += len; @@ -360,11 +364,6 @@ impl Printer { self.scan_stack.pop_back().unwrap() } - fn advance_right(&mut self) { - self.right += 1; - self.buf.advance_right(); - } - fn advance_left(&mut self) { let mut left_size = self.buf[self.left].size; From e219b2b5f90bf48bf56533c16745f2ce85216a2c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:04:12 -0800 Subject: [PATCH 02/15] Inline Printer's scan_push method --- compiler/rustc_ast_pretty/src/pp.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 785125ccafcc5..4f5140349c97b 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -293,7 +293,8 @@ impl Printer { self.right += 1; self.buf.advance_right(); } - self.scan_push(BufEntry { token: Token::Begin(b), size: -self.right_total }); + self.buf[self.right] = BufEntry { token: Token::Begin(b), size: -self.right_total }; + self.scan_stack.push_front(self.right); } fn scan_end(&mut self) { @@ -302,7 +303,8 @@ impl Printer { } else { self.right += 1; self.buf.advance_right(); - self.scan_push(BufEntry { token: Token::End, size: -1 }); + self.buf[self.right] = BufEntry { token: Token::End, size: -1 }; + self.scan_stack.push_front(self.right); } } @@ -317,7 +319,8 @@ impl Printer { self.buf.advance_right(); } self.check_stack(0); - self.scan_push(BufEntry { token: Token::Break(b), size: -self.right_total }); + self.buf[self.right] = BufEntry { token: Token::Break(b), size: -self.right_total }; + self.scan_stack.push_front(self.right); self.right_total += b.blank_space; } @@ -347,11 +350,6 @@ impl Printer { } } - fn scan_push(&mut self, entry: BufEntry) { - self.buf[self.right] = entry; - self.scan_stack.push_front(self.right); - } - fn scan_pop(&mut self) -> usize { self.scan_stack.pop_front().unwrap() } From 50d722a6917eb150362ff05e4881e63b3e7adc62 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:07:12 -0800 Subject: [PATCH 03/15] Simplify ring buffer pushes --- compiler/rustc_ast_pretty/src/pp.rs | 11 ++++------- compiler/rustc_ast_pretty/src/pp/ring.rs | 8 ++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 4f5140349c97b..43a3c792d4ac9 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -288,12 +288,11 @@ impl Printer { self.left_total = 1; self.right_total = 1; self.right = self.left; - self.buf.truncate(1); + self.buf.clear(); } else { self.right += 1; - self.buf.advance_right(); } - self.buf[self.right] = BufEntry { token: Token::Begin(b), size: -self.right_total }; + self.buf.push(BufEntry { token: Token::Begin(b), size: -self.right_total }); self.scan_stack.push_front(self.right); } @@ -302,8 +301,7 @@ impl Printer { self.print_end(); } else { self.right += 1; - self.buf.advance_right(); - self.buf[self.right] = BufEntry { token: Token::End, size: -1 }; + self.buf.push(BufEntry { token: Token::End, size: -1 }); self.scan_stack.push_front(self.right); } } @@ -329,9 +327,8 @@ impl Printer { self.print_string(s); } else { self.right += 1; - self.buf.advance_right(); let len = s.len() as isize; - self.buf[self.right] = BufEntry { token: Token::String(s), size: len }; + self.buf.push(BufEntry { token: Token::String(s), size: len }); self.right_total += len; self.check_stream(); } diff --git a/compiler/rustc_ast_pretty/src/pp/ring.rs b/compiler/rustc_ast_pretty/src/pp/ring.rs index 7e4e353ef1f8c..94bb10382f8af 100644 --- a/compiler/rustc_ast_pretty/src/pp/ring.rs +++ b/compiler/rustc_ast_pretty/src/pp/ring.rs @@ -22,6 +22,10 @@ impl RingBuffer { RingBuffer { data: VecDeque::new(), offset: 0 } } + pub fn push(&mut self, value: T) { + self.data.push_back(value); + } + pub fn advance_right(&mut self) where T: Default, @@ -34,6 +38,10 @@ impl RingBuffer { self.offset += 1; } + pub fn clear(&mut self) { + self.data.clear(); + } + pub fn truncate(&mut self, len: usize) { self.data.truncate(len); } From e20d5abdfb39f38ac9f4919b053029ffb6560641 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:15:02 -0800 Subject: [PATCH 04/15] Inline Printer's scan_pop method --- compiler/rustc_ast_pretty/src/pp.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 43a3c792d4ac9..96d446e363804 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -347,10 +347,6 @@ impl Printer { } } - fn scan_pop(&mut self) -> usize { - self.scan_stack.pop_front().unwrap() - } - fn scan_top(&self) -> usize { *self.scan_stack.front().unwrap() } @@ -396,19 +392,19 @@ impl Printer { match self.buf[x].token { Token::Begin(_) => { if k > 0 { - self.scan_pop(); + self.scan_stack.pop_front().unwrap(); self.buf[x].size += self.right_total; self.check_stack(k - 1); } } Token::End => { // paper says + not =, but that makes no sense. - self.scan_pop(); + self.scan_stack.pop_front().unwrap(); self.buf[x].size = 1; self.check_stack(k + 1); } _ => { - self.scan_pop(); + self.scan_stack.pop_front().unwrap(); self.buf[x].size += self.right_total; if k > 0 { self.check_stack(k); From 2a14275500b5c9cddfab83bb606368a9a4192ea4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:15:21 -0800 Subject: [PATCH 05/15] Inline Printer's scan_top method --- compiler/rustc_ast_pretty/src/pp.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 96d446e363804..4aeb4e4807b38 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -347,10 +347,6 @@ impl Printer { } } - fn scan_top(&self) -> usize { - *self.scan_stack.front().unwrap() - } - fn scan_pop_bottom(&mut self) -> usize { self.scan_stack.pop_back().unwrap() } @@ -388,7 +384,7 @@ impl Printer { fn check_stack(&mut self, k: usize) { if !self.scan_stack.is_empty() { - let x = self.scan_top(); + let x = *self.scan_stack.front().unwrap(); match self.buf[x].token { Token::Begin(_) => { if k > 0 { From ae28ec5a9c09b0ea163ccdff26b5650d4d0ea3c0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:15:38 -0800 Subject: [PATCH 06/15] Inline Printer's scan_pop_bottom method --- compiler/rustc_ast_pretty/src/pp.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 4aeb4e4807b38..e5542eda5961b 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -337,7 +337,7 @@ impl Printer { fn check_stream(&mut self) { if self.right_total - self.left_total > self.space { if Some(&self.left) == self.scan_stack.back() { - let scanned = self.scan_pop_bottom(); + let scanned = self.scan_stack.pop_back().unwrap(); self.buf[scanned].size = SIZE_INFINITY; } self.advance_left(); @@ -347,10 +347,6 @@ impl Printer { } } - fn scan_pop_bottom(&mut self) -> usize { - self.scan_stack.pop_back().unwrap() - } - fn advance_left(&mut self) { let mut left_size = self.buf[self.left].size; From 80139a0f02ef04dc759f47ad59ece2138117c41c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:18:04 -0800 Subject: [PATCH 07/15] Ensure Printer buf is always indexed using self.left or self.right --- compiler/rustc_ast_pretty/src/pp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index e5542eda5961b..8d58eaa82a701 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -336,9 +336,9 @@ impl Printer { fn check_stream(&mut self) { if self.right_total - self.left_total > self.space { - if Some(&self.left) == self.scan_stack.back() { - let scanned = self.scan_stack.pop_back().unwrap(); - self.buf[scanned].size = SIZE_INFINITY; + if self.scan_stack.back() == Some(&self.left) { + self.scan_stack.pop_back().unwrap(); + self.buf[self.left].size = SIZE_INFINITY; } self.advance_left(); if self.left != self.right { From 947a09a4a88f97aa0ab59a5d21afd8ca3d429e60 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:18:47 -0800 Subject: [PATCH 08/15] Replace `if` + `unwrap` with `if let` in check_stack --- compiler/rustc_ast_pretty/src/pp.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 8d58eaa82a701..b2870ac2734fa 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -379,8 +379,7 @@ impl Printer { } fn check_stack(&mut self, k: usize) { - if !self.scan_stack.is_empty() { - let x = *self.scan_stack.front().unwrap(); + if let Some(&x) = self.scan_stack.front() { match self.buf[x].token { Token::Begin(_) => { if k > 0 { From 0490e43422b3061ba3afef9b064a9360871d1455 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:19:18 -0800 Subject: [PATCH 09/15] Implement check_stream nonrecursively --- compiler/rustc_ast_pretty/src/pp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index b2870ac2734fa..d32cc4694d3e5 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -335,14 +335,14 @@ impl Printer { } fn check_stream(&mut self) { - if self.right_total - self.left_total > self.space { + while self.right_total - self.left_total > self.space { if self.scan_stack.back() == Some(&self.left) { self.scan_stack.pop_back().unwrap(); self.buf[self.left].size = SIZE_INFINITY; } self.advance_left(); - if self.left != self.right { - self.check_stream(); + if self.left == self.right { + break; } } } From a37d272892172dfe598d9df182fa908d74359c6e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:20:33 -0800 Subject: [PATCH 10/15] Implement check_stack nonrecursively --- compiler/rustc_ast_pretty/src/pp.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index d32cc4694d3e5..dca0515a33033 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -378,27 +378,28 @@ impl Printer { } } - fn check_stack(&mut self, k: usize) { - if let Some(&x) = self.scan_stack.front() { + fn check_stack(&mut self, mut k: usize) { + while let Some(&x) = self.scan_stack.front() { match self.buf[x].token { Token::Begin(_) => { - if k > 0 { - self.scan_stack.pop_front().unwrap(); - self.buf[x].size += self.right_total; - self.check_stack(k - 1); + if k == 0 { + break; } + self.scan_stack.pop_front().unwrap(); + self.buf[x].size += self.right_total; + k -= 1; } Token::End => { // paper says + not =, but that makes no sense. self.scan_stack.pop_front().unwrap(); self.buf[x].size = 1; - self.check_stack(k + 1); + k += 1; } _ => { self.scan_stack.pop_front().unwrap(); self.buf[x].size += self.right_total; - if k > 0 { - self.check_stack(k); + if k == 0 { + break; } } } From 377c9dbabfe6574ff0161f0fd8e750bb57181530 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:21:18 -0800 Subject: [PATCH 11/15] Index a single time in check_stack --- compiler/rustc_ast_pretty/src/pp.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index dca0515a33033..d9832d560a841 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -380,24 +380,25 @@ impl Printer { fn check_stack(&mut self, mut k: usize) { while let Some(&x) = self.scan_stack.front() { - match self.buf[x].token { + let mut entry = &mut self.buf[x]; + match entry.token { Token::Begin(_) => { if k == 0 { break; } self.scan_stack.pop_front().unwrap(); - self.buf[x].size += self.right_total; + entry.size += self.right_total; k -= 1; } Token::End => { // paper says + not =, but that makes no sense. self.scan_stack.pop_front().unwrap(); - self.buf[x].size = 1; + entry.size = 1; k += 1; } _ => { self.scan_stack.pop_front().unwrap(); - self.buf[x].size += self.right_total; + entry.size += self.right_total; if k == 0 { break; } From fe5c4eab2dbc646f60f748b4b348acf5202ebf59 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:23:22 -0800 Subject: [PATCH 12/15] Eliminate a check_stack call on an empty scan stack --- compiler/rustc_ast_pretty/src/pp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index d9832d560a841..21e685fff4a91 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -315,8 +315,8 @@ impl Printer { } else { self.right += 1; self.buf.advance_right(); + self.check_stack(0); } - self.check_stack(0); self.buf[self.right] = BufEntry { token: Token::Break(b), size: -self.right_total }; self.scan_stack.push_front(self.right); self.right_total += b.blank_space; From 6e8b06015e7f0cfa05208c2d83e0a9140f62ab7a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:24:17 -0800 Subject: [PATCH 13/15] Simplify the buffer push done by scan_break --- compiler/rustc_ast_pretty/src/pp.rs | 7 +++---- compiler/rustc_ast_pretty/src/pp/ring.rs | 4 ---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 21e685fff4a91..b9b2f77431ef4 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -311,13 +311,12 @@ impl Printer { self.left_total = 1; self.right_total = 1; self.right = self.left; - self.buf.truncate(1); + self.buf.clear(); } else { - self.right += 1; - self.buf.advance_right(); self.check_stack(0); + self.right += 1; } - self.buf[self.right] = BufEntry { token: Token::Break(b), size: -self.right_total }; + self.buf.push(BufEntry { token: Token::Break(b), size: -self.right_total }); self.scan_stack.push_front(self.right); self.right_total += b.blank_space; } diff --git a/compiler/rustc_ast_pretty/src/pp/ring.rs b/compiler/rustc_ast_pretty/src/pp/ring.rs index 94bb10382f8af..62900ddfa2d46 100644 --- a/compiler/rustc_ast_pretty/src/pp/ring.rs +++ b/compiler/rustc_ast_pretty/src/pp/ring.rs @@ -41,10 +41,6 @@ impl RingBuffer { pub fn clear(&mut self) { self.data.clear(); } - - pub fn truncate(&mut self, len: usize) { - self.data.truncate(len); - } } impl Index for RingBuffer { From cc66a7ff20d0c8626661fe6f53daab265537425f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 19:59:36 -0800 Subject: [PATCH 14/15] Eliminate eof token state --- compiler/rustc_ast_pretty/src/pp.rs | 51 +++++++++---------- compiler/rustc_ast_pretty/src/pp/ring.rs | 15 +++--- compiler/rustc_ast_pretty/src/pprust/state.rs | 20 +++++--- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index b9b2f77431ef4..0c9d4ef0e950d 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -167,14 +167,9 @@ pub enum Token { Break(BreakToken), Begin(BeginToken), End, - Eof, } impl Token { - crate fn is_eof(&self) -> bool { - matches!(self, Token::Eof) - } - pub fn is_hardbreak_tok(&self) -> bool { matches!(self, Token::Break(BreakToken { offset: 0, blank_space: SIZE_INFINITY })) } @@ -187,7 +182,6 @@ impl fmt::Display for Token { Token::Break(_) => f.write_str("BREAK"), Token::Begin(_) => f.write_str("BEGIN"), Token::End => f.write_str("END"), - Token::Eof => f.write_str("EOF"), } } } @@ -233,6 +227,9 @@ pub struct Printer { print_stack: Vec, /// Buffered indentation to avoid writing trailing whitespace pending_indentation: isize, + /// The token most recently popped from the left boundary of the + /// ring-buffer for printing + last_printed: Option, } #[derive(Clone)] @@ -241,39 +238,36 @@ struct BufEntry { size: isize, } -impl Default for BufEntry { - fn default() -> Self { - BufEntry { token: Token::Eof, size: 0 } - } -} - impl Printer { pub fn new() -> Self { let linewidth = 78; - let mut buf = RingBuffer::new(); - buf.advance_right(); Printer { out: String::new(), margin: linewidth as isize, space: linewidth as isize, left: 0, right: 0, - buf, + buf: RingBuffer::new(), left_total: 0, right_total: 0, scan_stack: VecDeque::new(), print_stack: Vec::new(), pending_indentation: 0, + last_printed: None, } } - pub fn last_token(&self) -> Token { - self.buf[self.right].token.clone() + pub fn last_token(&self) -> Option<&Token> { + self.last_token_still_buffered().or_else(|| self.last_printed.as_ref()) + } + + pub fn last_token_still_buffered(&self) -> Option<&Token> { + self.buf.last().map(|last| &last.token) } /// Be very careful with this! - pub fn replace_last_token(&mut self, t: Token) { - self.buf[self.right].token = t; + pub fn replace_last_token_still_buffered(&mut self, t: Token) { + self.buf.last_mut().unwrap().token = t; } fn scan_eof(&mut self) { @@ -323,7 +317,7 @@ impl Printer { fn scan_string(&mut self, s: Cow<'static, str>) { if self.scan_stack.is_empty() { - self.print_string(s); + self.print_string(&s); } else { self.right += 1; let len = s.len() as isize; @@ -459,7 +453,7 @@ impl Printer { } } - fn print_string(&mut self, s: Cow<'static, str>) { + fn print_string(&mut self, s: &str) { let len = s.len() as isize; // assert!(len <= space); self.space -= len; @@ -473,21 +467,21 @@ impl Printer { self.out.reserve(self.pending_indentation as usize); self.out.extend(std::iter::repeat(' ').take(self.pending_indentation as usize)); self.pending_indentation = 0; - self.out.push_str(&s); + self.out.push_str(s); } fn print(&mut self, token: Token, l: isize) { - match token { - Token::Begin(b) => self.print_begin(b, l), + match &token { + Token::Begin(b) => self.print_begin(*b, l), Token::End => self.print_end(), - Token::Break(b) => self.print_break(b, l), + Token::Break(b) => self.print_break(*b, l), Token::String(s) => { let len = s.len() as isize; assert_eq!(len, l); self.print_string(s); } - Token::Eof => panic!(), // Eof should never get here. } + self.last_printed = Some(token); } // Convenience functions to talk to the printer. @@ -542,7 +536,10 @@ impl Printer { } pub fn is_beginning_of_line(&self) -> bool { - self.last_token().is_eof() || self.last_token().is_hardbreak_tok() + match self.last_token() { + Some(last_token) => last_token.is_hardbreak_tok(), + None => true, + } } pub fn hardbreak_tok_offset(off: isize) -> Token { diff --git a/compiler/rustc_ast_pretty/src/pp/ring.rs b/compiler/rustc_ast_pretty/src/pp/ring.rs index 62900ddfa2d46..86b87614c1986 100644 --- a/compiler/rustc_ast_pretty/src/pp/ring.rs +++ b/compiler/rustc_ast_pretty/src/pp/ring.rs @@ -26,13 +26,6 @@ impl RingBuffer { self.data.push_back(value); } - pub fn advance_right(&mut self) - where - T: Default, - { - self.data.push_back(T::default()); - } - pub fn advance_left(&mut self) { self.data.pop_front().unwrap(); self.offset += 1; @@ -41,6 +34,14 @@ impl RingBuffer { pub fn clear(&mut self) { self.data.clear(); } + + pub fn last(&self) -> Option<&T> { + self.data.back() + } + + pub fn last_mut(&mut self) -> Option<&mut T> { + self.data.back_mut() + } } impl Index for RingBuffer { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 17941058ed6f0..044f6b228dc0b 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -329,9 +329,9 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere CommentStyle::BlankLine => { // We need to do at least one, possibly two hardbreaks. let twice = match self.last_token() { - pp::Token::String(s) => ";" == s, - pp::Token::Begin(_) => true, - pp::Token::End => true, + Some(pp::Token::String(s)) => ";" == s, + Some(pp::Token::Begin(_)) => true, + Some(pp::Token::End) => true, _ => false, }; if twice { @@ -687,11 +687,15 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn break_offset_if_not_bol(&mut self, n: usize, off: isize) { if !self.is_beginning_of_line() { self.break_offset(n, off) - } else if off != 0 && self.last_token().is_hardbreak_tok() { - // We do something pretty sketchy here: tuck the nonzero - // offset-adjustment we were going to deposit along with the - // break into the previous hardbreak. - self.replace_last_token(pp::Printer::hardbreak_tok_offset(off)); + } else if off != 0 { + if let Some(last_token) = self.last_token_still_buffered() { + if last_token.is_hardbreak_tok() { + // We do something pretty sketchy here: tuck the nonzero + // offset-adjustment we were going to deposit along with the + // break into the previous hardbreak. + self.replace_last_token_still_buffered(pp::Printer::hardbreak_tok_offset(off)); + } + } } } From 4d3faae5cd34cc3a34a7c01fb2f22c68e092e0eb Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 18 Jan 2022 20:19:10 -0800 Subject: [PATCH 15/15] Eliminate left and right cursors in favor of ring buffer --- compiler/rustc_ast_pretty/src/pp.rs | 43 ++++++++---------------- compiler/rustc_ast_pretty/src/pp/ring.rs | 20 ++++++++++- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 0c9d4ef0e950d..bdd70148d85a0 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -206,10 +206,6 @@ pub struct Printer { margin: isize, /// Number of spaces left on line space: isize, - /// Index of left side of input stream - left: usize, - /// Index of right side of input stream - right: usize, /// Ring-buffer of tokens and calculated sizes buf: RingBuffer, /// Running size of stream "...left" @@ -245,8 +241,6 @@ impl Printer { out: String::new(), margin: linewidth as isize, space: linewidth as isize, - left: 0, - right: 0, buf: RingBuffer::new(), left_total: 0, right_total: 0, @@ -281,22 +275,18 @@ impl Printer { if self.scan_stack.is_empty() { self.left_total = 1; self.right_total = 1; - self.right = self.left; self.buf.clear(); - } else { - self.right += 1; } - self.buf.push(BufEntry { token: Token::Begin(b), size: -self.right_total }); - self.scan_stack.push_front(self.right); + let right = self.buf.push(BufEntry { token: Token::Begin(b), size: -self.right_total }); + self.scan_stack.push_front(right); } fn scan_end(&mut self) { if self.scan_stack.is_empty() { self.print_end(); } else { - self.right += 1; - self.buf.push(BufEntry { token: Token::End, size: -1 }); - self.scan_stack.push_front(self.right); + let right = self.buf.push(BufEntry { token: Token::End, size: -1 }); + self.scan_stack.push_front(right); } } @@ -304,14 +294,12 @@ impl Printer { if self.scan_stack.is_empty() { self.left_total = 1; self.right_total = 1; - self.right = self.left; self.buf.clear(); } else { self.check_stack(0); - self.right += 1; } - self.buf.push(BufEntry { token: Token::Break(b), size: -self.right_total }); - self.scan_stack.push_front(self.right); + let right = self.buf.push(BufEntry { token: Token::Break(b), size: -self.right_total }); + self.scan_stack.push_front(right); self.right_total += b.blank_space; } @@ -319,7 +307,6 @@ impl Printer { if self.scan_stack.is_empty() { self.print_string(&s); } else { - self.right += 1; let len = s.len() as isize; self.buf.push(BufEntry { token: Token::String(s), size: len }); self.right_total += len; @@ -329,22 +316,22 @@ impl Printer { fn check_stream(&mut self) { while self.right_total - self.left_total > self.space { - if self.scan_stack.back() == Some(&self.left) { + if *self.scan_stack.back().unwrap() == self.buf.index_of_first() { self.scan_stack.pop_back().unwrap(); - self.buf[self.left].size = SIZE_INFINITY; + self.buf.first_mut().unwrap().size = SIZE_INFINITY; } self.advance_left(); - if self.left == self.right { + if self.buf.is_empty() { break; } } } fn advance_left(&mut self) { - let mut left_size = self.buf[self.left].size; + let mut left_size = self.buf.first().unwrap().size; while left_size >= 0 { - let left = self.buf[self.left].token.clone(); + let left = self.buf.first().unwrap().token.clone(); let len = match left { Token::Break(b) => b.blank_space, @@ -360,14 +347,12 @@ impl Printer { self.left_total += len; - if self.left == self.right { + self.buf.advance_left(); + if self.buf.is_empty() { break; } - self.buf.advance_left(); - self.left += 1; - - left_size = self.buf[self.left].size; + left_size = self.buf.first().unwrap().size; } } diff --git a/compiler/rustc_ast_pretty/src/pp/ring.rs b/compiler/rustc_ast_pretty/src/pp/ring.rs index 86b87614c1986..d20142eb591fe 100644 --- a/compiler/rustc_ast_pretty/src/pp/ring.rs +++ b/compiler/rustc_ast_pretty/src/pp/ring.rs @@ -22,8 +22,14 @@ impl RingBuffer { RingBuffer { data: VecDeque::new(), offset: 0 } } - pub fn push(&mut self, value: T) { + pub fn is_empty(&self) -> bool { + self.data.is_empty() + } + + pub fn push(&mut self, value: T) -> usize { + let index = self.offset + self.data.len(); self.data.push_back(value); + index } pub fn advance_left(&mut self) { @@ -35,6 +41,18 @@ impl RingBuffer { self.data.clear(); } + pub fn index_of_first(&self) -> usize { + self.offset + } + + pub fn first(&self) -> Option<&T> { + self.data.front() + } + + pub fn first_mut(&mut self) -> Option<&mut T> { + self.data.front_mut() + } + pub fn last(&self) -> Option<&T> { self.data.back() }