@@ -146,37 +146,49 @@ pub fn print_crate<'a>(
146
146
s. s . eof ( )
147
147
}
148
148
149
- /// This makes printed token streams look slightly nicer,
150
- /// and also addresses some specific regressions described in #63896 and #73345.
151
- fn space_between ( prev : & TokenTree , curr : & TokenTree ) -> bool {
152
- if let TokenTree :: Token ( token, _) = prev {
153
- // No space after these tokens, e.g. `x.y`, `$e`
154
- // (The carets point to `prev`.) ^ ^
155
- if matches ! ( token. kind, token:: Dot | token:: Dollar ) {
156
- return false ;
157
- }
158
- if let token:: DocComment ( comment_kind, ..) = token. kind {
159
- return comment_kind != CommentKind :: Line ;
160
- }
161
- }
162
- match curr {
163
- // No space before these tokens, e.g. `foo,`, `println!`, `x.y`
164
- // (The carets point to `curr`.) ^ ^ ^
149
+ /// Should two consecutive tokens be printed with a space between them?
150
+ ///
151
+ /// Note: some old proc macros parse pretty-printed output, so changes here can
152
+ /// break old code. For example:
153
+ /// - #63896: `#[allow(unused,` must be printed rather than `#[allow(unused ,`
154
+ /// - #73345: `#[allow(unused)] must be printed rather than `# [allow(unused)]
155
+ ///
156
+ fn space_between ( tt1 : & TokenTree , tt2 : & TokenTree ) -> bool {
157
+ use token:: * ;
158
+ use Delimiter :: * ;
159
+ use TokenTree :: Delimited as Del ;
160
+ use TokenTree :: Token as Tok ;
161
+
162
+ // Each match arm has one or more examples in comments. The default is to
163
+ // insert space between adjacent tokens, except for the cases listed in
164
+ // this match.
165
+ match ( tt1, tt2) {
166
+ // No space after line doc comments.
167
+ ( Tok ( Token { kind : DocComment ( CommentKind :: Line , ..) , .. } , _) , _) => false ,
168
+
169
+ // `.` + ANYTHING: `x.y`, `tup.0`
170
+ // `$` + ANYTHING: `$e`
171
+ ( Tok ( Token { kind : Dot | Dollar , .. } , _) , _) => false ,
172
+
173
+ // ANYTHING + `,`: `foo,`
174
+ // ANYTHING + `.`: `x.y`, `tup.0`
175
+ // ANYTHING + `!`: `foo! { ... }`
165
176
//
166
- // FIXME: having `Not` here works well for macro invocations like
167
- // `println!()`, but is bad when `!` means "logical not" or "the never
168
- // type", where the lack of space causes ugliness like this:
169
- // `Fn() ->!`, `x =! y`, `if! x { f(); }`.
170
- TokenTree :: Token ( token, _) => !matches ! ( token. kind, token:: Comma | token:: Not | token:: Dot ) ,
171
- // No space before parentheses if preceded by these tokens, e.g. `foo(...)`
172
- TokenTree :: Delimited ( _, Delimiter :: Parenthesis , _) => {
173
- !matches ! ( prev, TokenTree :: Token ( Token { kind: token:: Ident ( ..) , .. } , _) )
174
- }
175
- // No space before brackets if preceded by these tokens, e.g. `#[...]`
176
- TokenTree :: Delimited ( _, Delimiter :: Bracket , _) => {
177
- !matches ! ( prev, TokenTree :: Token ( Token { kind: token:: Pound , .. } , _) )
178
- }
179
- TokenTree :: Delimited ( ..) => true ,
177
+ // FIXME: Incorrect cases:
178
+ // - Logical not: `x =! y`, `if! x { f(); }`
179
+ // - Never type: `Fn() ->!`
180
+ ( _, Tok ( Token { kind : Comma | Dot | Not , .. } , _) ) => false ,
181
+
182
+ // IDENT + `(`: `f(3)`
183
+ //
184
+ // FIXME: Incorrect cases:
185
+ // - Let: `let(a, b) = (1, 2)`
186
+ ( Tok ( Token { kind : Ident ( ..) , .. } , _) , Del ( _, Parenthesis , _) ) => false ,
187
+
188
+ // `#` + `[`: `#[attr]`
189
+ ( Tok ( Token { kind : Pound , .. } , _) , Del ( _, Bracket , _) ) => false ,
190
+
191
+ _ => true ,
180
192
}
181
193
}
182
194
0 commit comments