tree-sitter / tree-sitter-haskell

Haskell grammar for tree-sitter.
MIT License
151 stars 36 forks source link

Segfault on large files (in Neovim) #103

Closed mrcjkb closed 10 months ago

mrcjkb commented 10 months ago

Hey :wave:

The following highlight queries cause tree-sitter-haskell (and Neovim) to segfault in large files:

((signature name: (variable) @function)
 (function 
  name: (variable) @_name
  patterns: (patterns))
 (#eq? @function @_name))
((signature name: (variable) @variable)
 (function 
  name: (variable) @_name
  rhs: (exp_infix 
    [
     (exp_literal)
     (exp_apply 
       (exp_name 
         [(constructor)
          (variable)
         ]))
     (quasiquote)
     ((exp_name) . (operator))
    ]))
 (#eq? @variable @_name))

I haven't narrowed it down further yet, but I think it's something to do with top-level ((signature)(function)) queries.

The segfault can be reproduced in Neovim with the Haskell snippet in https://github.com/tree-sitter/tree-sitter-haskell/issues/41#issue-964849242, when navigating to the bottom of the file.

See also: https://github.com/nvim-treesitter/nvim-treesitter/issues/5500

mrcjkb commented 10 months ago

I've been able to solve this by adding anchors to the queries, as follows: ((signature) . (comment)* . (function)+).

e.g.

((signature name: (variable) @function)
 . (comment)*
 . (function 
  name: (variable) @_name
  patterns: (patterns))+
 (#eq? @function @_name))

Technically, this doesn't match everything, as signatures and functions can have anything in between, but I think that's fine for syntax highlighting.

It's probably unrealistic to expect the parser to be able to handle unanchored queries in large files.