Subject: bug#61369: Problem with keeping tree-sitter parse tree up-to-date

From: Dmitry Gutov <[email-masked]>
Date: Wed, 8 Feb 2023 17:34:25 +0200

1. Have some buffer with text

"use std::Path::{self, Path, PathBuf};  // good: std is a crate name
... (maybe something else
"

2. Have this text in a different buffer (I used scratch):

"

let date = DateTime::<chrono::Utc>::from_utc(date, chrono::Utc);
"

Meaning, the buffer starts with two empty lines.

3. Select the first line from the first buffer including the trailing 
newline, yank and then paste at the beginning of the second buffer.

The second buffer will now look like this:

"use std::Path::{self, Path, PathBuf};  // good: std is a crate name

let date = DateTime::<chrono::Utc>::from_utc(date, chrono::Utc);
"

The parse tree will, however, be (according to treesit-explore-mode):

(source_file
  (use_declaration use
   argument:
    (scoped_use_list
     path: (scoped_identifier path: (identifier) :: name: (identifier))
     ::
     list: (use_list { (self) , (identifier) , (identifier) }))
   ;)
  (line_comment)
  (let_declaration let pattern: (identifier) =
   value:
    (scoped_identifier
     path:
      (generic_type type: (type_identifier) ::
       type_arguments:
        (type_arguments <
         (scoped_type_identifier path: (identifier) :: name: 
(type_identifier))
         >))
     :: name: (identifier))
   (ERROR ( (identifier) ,
    (scoped_identifier path: (identifier) :: name: (identifier))
    ;)
   ;))

But if I edit the buffer after that, e.g. add and remove a space at the 
beginning, the error node disappears:

(source_file
  (use_declaration use
   argument:
    (scoped_use_list
     path: (scoped_identifier path: (identifier) :: name: (identifier))
     ::
     list: (use_list { (self) , (identifier) , (identifier) }))
   ;)
  (line_comment)
  (let_declaration let pattern: (identifier) =
   value:
    (call_expression
     function:
      (scoped_identifier
       path:
        (generic_type type: (type_identifier) ::
         type_arguments:
          (type_arguments <
           (scoped_type_identifier path: (identifier) :: name: 
(type_identifier))
           >))
       :: name: (identifier))
     arguments:
      (arguments ( (identifier) ,
       (scoped_identifier path: (identifier) :: name: (identifier))
       )))
   ;))