@@ -12,6 +12,9 @@ use tt::buffer::{Cursor, TokenBuffer};
1212
1313use crate :: { to_parser_input:: to_parser_input, tt_iter:: TtIter , TokenMap } ;
1414
15+ #[ cfg( test) ]
16+ mod tests;
17+
1518/// Convert the syntax node to a `TokenTree` (what macro
1619/// will consume).
1720pub fn syntax_node_to_token_tree ( node : & SyntaxNode ) -> ( tt:: Subtree , TokenMap ) {
@@ -228,7 +231,7 @@ fn convert_tokens<C: TokenConverter>(conv: &mut C) -> tt::Subtree {
228231 }
229232
230233 let spacing = match conv. peek ( ) . map ( |next| next. kind ( conv) ) {
231- Some ( kind) if !kind . is_trivia ( ) => tt:: Spacing :: Joint ,
234+ Some ( kind) if is_single_token_op ( kind ) => tt:: Spacing :: Joint ,
232235 _ => tt:: Spacing :: Alone ,
233236 } ;
234237 let char = match token. to_char ( conv) {
@@ -307,6 +310,35 @@ fn convert_tokens<C: TokenConverter>(conv: &mut C) -> tt::Subtree {
307310 }
308311}
309312
313+ fn is_single_token_op ( kind : SyntaxKind ) -> bool {
314+ matches ! (
315+ kind,
316+ EQ | L_ANGLE
317+ | R_ANGLE
318+ | BANG
319+ | AMP
320+ | PIPE
321+ | TILDE
322+ | AT
323+ | DOT
324+ | COMMA
325+ | SEMICOLON
326+ | COLON
327+ | POUND
328+ | DOLLAR
329+ | QUESTION
330+ | PLUS
331+ | MINUS
332+ | STAR
333+ | SLASH
334+ | PERCENT
335+ | CARET
336+ // LIFETIME_IDENT will be split into a sequence of `'` (a single quote) and an
337+ // identifier.
338+ | LIFETIME_IDENT
339+ )
340+ }
341+
310342/// Returns the textual content of a doc comment block as a quoted string
311343/// That is, strips leading `///` (or `/**`, etc)
312344/// and strips the ending `*/`
@@ -591,10 +623,10 @@ impl SynToken {
591623}
592624
593625impl SrcToken < Converter > for SynToken {
594- fn kind ( & self , _ctx : & Converter ) -> SyntaxKind {
626+ fn kind ( & self , ctx : & Converter ) -> SyntaxKind {
595627 match self {
596628 SynToken :: Ordinary ( token) => token. kind ( ) ,
597- SynToken :: Punch ( token , _ ) => token . kind ( ) ,
629+ SynToken :: Punch ( .. ) => SyntaxKind :: from_char ( self . to_char ( ctx ) . unwrap ( ) ) . unwrap ( ) ,
598630 SynToken :: Synthetic ( token) => token. kind ,
599631 }
600632 }
@@ -651,7 +683,7 @@ impl TokenConverter for Converter {
651683 }
652684
653685 let curr = self . current . clone ( ) ?;
654- if !& self . range . contains_range ( curr. text_range ( ) ) {
686+ if !self . range . contains_range ( curr. text_range ( ) ) {
655687 return None ;
656688 }
657689 let ( new_current, new_synth) =
@@ -809,12 +841,15 @@ impl<'a> TtTreeSink<'a> {
809841 let next = last. bump ( ) ;
810842 if let (
811843 Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( curr) , _) ) ,
812- Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( _ ) , _) ) ,
844+ Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( next ) , _) ) ,
813845 ) = ( last. token_tree ( ) , next. token_tree ( ) )
814846 {
815847 // Note: We always assume the semi-colon would be the last token in
816848 // other parts of RA such that we don't add whitespace here.
817- if curr. spacing == tt:: Spacing :: Alone && curr. char != ';' {
849+ //
850+ // When `next` is a `Punct` of `'`, that's a part of a lifetime identifier so we don't
851+ // need to add whitespace either.
852+ if curr. spacing == tt:: Spacing :: Alone && curr. char != ';' && next. char != '\'' {
818853 self . inner . token ( WHITESPACE , " " ) ;
819854 self . text_pos += TextSize :: of ( ' ' ) ;
820855 }
0 commit comments