Skip to content

Commit d7928a9

Browse files
committed
Clarify spacing computation.
The spacing computation is done in two parts. In the first part `next_token` and `bump` use `Spacing::Alone` to mean "preceded by whitespace" and `Spacing::Joint` to mean the opposite. In the second part `parse_token_tree_other` then adjusts the `spacing` value to mean the usual thing (i.e. "is the following token joinable punctuation?"). This shift in meaning is very confusing and it took me some time to understand what was going on. This commit changes the first part to use a bool, and adds some comments, which makes things much clearer.
1 parent 9640d1c commit d7928a9

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed

compiler/rustc_parse/src/lexer/mod.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::lexer::unicode_chars::UNICODE_ARRAY;
22
use rustc_ast::ast::{self, AttrStyle};
33
use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind};
4-
use rustc_ast::tokenstream::{Spacing, TokenStream};
4+
use rustc_ast::tokenstream::TokenStream;
55
use rustc_ast::util::unicode::contains_text_flow_control_chars;
66
use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
77
use rustc_lexer::unescape::{self, Mode};
@@ -67,9 +67,10 @@ impl<'a> StringReader<'a> {
6767
self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi))
6868
}
6969

70-
/// Returns the next token, and info about preceding whitespace, if any.
71-
fn next_token(&mut self) -> (Spacing, Token) {
72-
let mut spacing = Spacing::Joint;
70+
/// Returns the next token, paired with a bool indicating if the token was
71+
/// preceded by whitespace.
72+
fn next_token(&mut self) -> (Token, bool) {
73+
let mut preceded_by_whitespace = false;
7374

7475
// Skip trivial (whitespace & comments) tokens
7576
loop {
@@ -78,7 +79,7 @@ impl<'a> StringReader<'a> {
7879

7980
if text.is_empty() {
8081
let span = self.mk_sp(self.pos, self.pos);
81-
return (spacing, Token::new(token::Eof, span));
82+
return (Token::new(token::Eof, span), preceded_by_whitespace);
8283
}
8384

8485
let token = rustc_lexer::first_token(text);
@@ -91,9 +92,9 @@ impl<'a> StringReader<'a> {
9192
match self.cook_lexer_token(token.kind, start) {
9293
Some(kind) => {
9394
let span = self.mk_sp(start, self.pos);
94-
return (spacing, Token::new(kind, span));
95+
return (Token::new(kind, span), preceded_by_whitespace);
9596
}
96-
None => spacing = Spacing::Alone,
97+
None => preceded_by_whitespace = true,
9798
}
9899
}
99100
}

compiler/rustc_parse/src/lexer/tokentrees.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,16 +246,22 @@ impl<'a> TokenTreesReader<'a> {
246246

247247
#[inline]
248248
fn parse_token_tree_other(&mut self) -> TokenTree {
249+
// `spacing` for the returned token is determined by the next token:
250+
// its kind and its `preceded_by_whitespace` status.
249251
let tok = self.token.take();
250-
let mut spacing = self.bump();
251-
if !self.token.is_op() {
252-
spacing = Spacing::Alone;
253-
}
252+
let is_next_tok_preceded_by_whitespace = self.bump();
253+
let spacing = if is_next_tok_preceded_by_whitespace || !self.token.is_op() {
254+
Spacing::Alone
255+
} else {
256+
Spacing::Joint
257+
};
254258
TokenTree::Token(tok, spacing)
255259
}
256260

257-
fn bump(&mut self) -> Spacing {
258-
let (spacing, token) = self.string_reader.next_token();
261+
// Set `self.token` to the next token. Returns a bool indicating if that
262+
// token was preceded by whitespace.
263+
fn bump(&mut self) -> bool {
264+
let (token, spacing) = self.string_reader.next_token();
259265
self.token = token;
260266
spacing
261267
}

0 commit comments

Comments
 (0)