Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax Highlighting related panic: IncludedRangesError(1) #3816

Closed
sevenautumns opened this issue Sep 12, 2022 · 9 comments · Fixed by #7621
Closed

Syntax Highlighting related panic: IncludedRangesError(1) #3816

sevenautumns opened this issue Sep 12, 2022 · 9 comments · Fixed by #7621
Labels
A-core Area: Helix core improvements A-tree-sitter Area: Tree-sitter C-bug Category: This is a bug

Comments

@sevenautumns
Copy link

Summary

When adding a '-symbol to a specific line of a specific nix-file, the predefined language-server for nix files (rnix-lsp) seems to provide information which results in an error in the tree_sitter parser which is unwrapped and hence panics.

parser.set_included_ranges(&self.ranges).unwrap();

Reproduction Steps

I tried this:

  1. hx flake.nix
  2. go to line 32
  3. add ' after the =-symbol of that line
  4. crash
flake.nix
{
  inputs = {
    utils.url = "github:numtide/flake-utils";
    devshell.url = "github:numtide/devshell";
    fenix.url = "github:nix-community/fenix";
    fenix.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { self, nixpkgs, utils, devshell, fenix, ... }@inputs:
    utils.lib.eachSystem [ "aarch64-linux" "i686-linux" "x86_64-linux" ]
    (system:
      let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [ devshell.overlay ];
        };
        rust-toolchain = with fenix.packages.${system};
          combine [ stable.rustc stable.cargo stable.clippy stable.rustfmt ];
      in rec {
        devShells.default = (pkgs.devshell.mkShell {
          imports = [
            # "${devshell}/extra/language/rust.nix"
            "${devshell}/extra/git/hooks.nix"
          ];
          name = "apex-rs-vanilla-dev-shell";
          packages = with pkgs; [
            rust-toolchain
            rust-analyzer
            cargo-outdated
            cargo-udeps
          ];
          devshell.startup.bindgen-hook.text = "source ${pkgs.rustPlatform.bindgenHook}/nix-support/setup-hook && populateBindgenEnv";
          git.hooks = {
            enable = true;
            pre-commit.text = "nix flake check";
          };
          commands = [
            {
              package = "git-cliff";
              help = "Changelog generator";
            }
            {
              package = "treefmt";
              help = "Format project tree with recommended formatter";
              category = "formatter";
            }
            {
              name = "udeps";
              command = "cargo-udeps udeps";
              category = "formatter";
              help = "Find unused dependencies in Cargo.toml";
            }
            {
              name = "outdated";
              command = "cargo-outdated outdated";
              category = "formatter";
              help = "Find out-of-date dependencies";
            }
            {
              name = "build";
              command = "cd $PRJ_ROOT && cargo build";
              help = "Build project";
              category = "build";
            }
            {
              name = "build release";
              command = "cd $PRJ_ROOT && cargo build --release";
              help = "Build project in release mode";
              category = "build";
            }
            {
              name = "clippy";
              command = "cd $PRJ_ROOT && cargo clippy";
              help = "Build project";
              category = "build";
            }
            {
              name = "clippy release";
              command = "cd $PRJ_ROOT && cargo clippy --release";
              help = "Build project in release mode";
              category = "build";
            }
            {
              name = "watch";
              command = "cd $PRJ_ROOT && cargo watch -x clippy";
              help = "Watch project and continuesly clippy";
              category = "build";
            }
            {
              name = "watch release";
              command = "cd $PRJ_ROOT && cargo watch -x clippy --release";
              help = "Watch project and continuesly clippy in release mode";
              category = "build";
            }
          ];
        });
        checks = {
          nixpkgs-fmt = pkgs.runCommand "nixpkgs-fmt" {
            nativeBuildInputs = [ pkgs.nixpkgs-fmt ];
          } "nixpkgs-fmt --check ${./.}; touch $out";
          cargo-fmt = pkgs.runCommand "cargo-fmt" {
            nativeBuildInputs = [ rust-toolchain ];
          } "cd ${./.}; cargo fmt --check; touch $out";
        };
      });
}

I expected this to happen:

No crash

Instead, this happened:

Crash

Helix log

~/.cache/helix/helix.log
2022-09-12T15:24:49.391 helix_lsp::transport [ERROR] err: <- StreamClosed
2022-09-12T15:24:49.391 helix_lsp::transport [ERROR] err: <- StreamClosed
console output
❯ RUST_BACKTRACE=full hx flake.nix
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: IncludedRangesError(1)', helix-core/src/syntax.rs:988:50
stack backtrace:
   0:     0x55e7021044d4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h9c2a9d2774d81873
   1:     0x55e701927cac - core::fmt::write::hba4337c43d992f49
   2:     0x55e7020fdeb5 - std::io::Write::write_fmt::heb73de6e02cfabed
   3:     0x55e70210637e - std::panicking::default_hook::{{closure}}::hc9a76eed0b18f82b
   4:     0x55e7021060ad - std::panicking::default_hook::h2e88d02087fae196
   5:     0x55e702106a0b - std::panicking::rust_panic_with_hook::habfdcc2e90f9fd4c
   6:     0x55e702106834 - std::panicking::begin_panic_handler::{{closure}}::he054b2a83a51d2cd
   7:     0x55e702104a04 - std::sys_common::backtrace::__rust_end_short_backtrace::ha48b94ab49b30915
   8:     0x55e70210659d - rust_begin_unwind
   9:     0x55e70189ed93 - core::panicking::panic_fmt::h366d3a309ae17c94
  10:     0x55e70189ee83 - core::result::unwrap_failed::hddd78f4658ac7d0f
  11:     0x55e7019efecf - helix_core::syntax::LanguageLayer::parse::h48fdfccc00f93624
  12:     0x55e7019c9375 - std::thread::local::LocalKey<T>::with::h3872ba0248f25375
  13:     0x55e7019efb32 - helix_core::syntax::Syntax::update::hfabc70c9a1af51f1
  14:     0x55e701ee80ca - helix_view::document::Document::apply_impl::h5831f29c9957f896
  15:     0x55e701ee91b7 - helix_view::document::Document::apply::h597bd3f2f8ff332e
  16:     0x55e701ce541e - helix_term::commands::insert::insert_char::h7a8fb8b8401f39f5
  17:     0x55e701c4e3e0 - helix_term::ui::editor::EditorView::insert_mode::hb6771a242a86bcbf
  18:     0x55e701c501b0 - <helix_term::ui::editor::EditorView as helix_term::compositor::Component>::handle_event::h0fee62f981b2f994
  19:     0x55e701cc9566 - helix_term::compositor::Compositor::handle_event::h6f24a639f104cd8a
  20:     0x55e701c45706 - helix_term::application::Application::handle_terminal_events::hd4a6e6651951166f
  21:     0x55e701f8517f - helix_term::application::Application::event_loop_until_idle::{{closure}}::h44cf1aa2267c2b1c
  22:     0x55e701fa31b5 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h2bcdc355d267fb0f
  23:     0x55e701f80342 - std::thread::local::LocalKey<T>::with::he3043768d7283740
  24:     0x55e701f6e868 - tokio::park::thread::CachedParkThread::block_on::h8a087f435dd2194f
  25:     0x55e701fc9568 - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::he8e9a60150382027
  26:     0x55e701f9f87e - tokio::runtime::Runtime::block_on::hd015e4e225788d29
  27:     0x55e701f64445 - hx::main::hb7285d874580d790
  28:     0x55e701f67733 - std::sys_common::backtrace::__rust_begin_short_backtrace::h9aa95b3790b5aa07
  29:     0x55e701f7fced - std::rt::lang_start::{{closure}}::h5d2638673ea5bf71
  30:     0x55e7020f874b - std::rt::lang_start_internal::h9c06694362b5b80c
  31:     0x55e701f64552 - main
  32:     0x7f1b832e724e - __libc_start_call_main
  33:     0x7f1b832e7309 - __libc_start_main@@GLIBC_2.34
  34:     0x55e7018d67b5 - _start
  35:                0x0 - <unknown>

Platform

Linux (NixOS)

Terminal Emulator

alacritty

Helix Version

helix 22.08.1 (0361217)

@sevenautumns sevenautumns added the C-bug Category: This is a bug label Sep 12, 2022
@AlexanderBrevig
Copy link
Contributor

Unable to reproduce.

Linux 5.15.60-1-MANJARO @ 21.3.7
Kitty 0.25.2
helix 22.08.1 (23027a4)
rnix-lsp 0.2.5-1

Which rnix-lsp are you on?

@archseer
Copy link
Member

Seems to trigger if the start of the range is past the end of the range or if ranges overlap:

            for (i, range) in ranges.iter().enumerate() {
                if range.start_byte < prev_end_byte || range.end_byte < range.start_byte {
                    return Err(IncludedRangesError(i));
                }
                prev_end_byte = range.end_byte;
            }

I also can't replicate: which = sign on this line?

renameOutputs = {"helix-term" = "helix";};
Do you have auto-pairs disabled?

I don't think it has anything to do with the LSP, this is a tree-sitter parsing issue.

@sudormrfbin
Copy link
Member

There's a flake.nix linked in the initial post, it's collapsible so easy to miss. I could reproduce the crash with it (on mobile right now so can't get the hx --version).

@AlexanderBrevig
Copy link
Contributor

I tested that file with 32ggf=a' and I simply just get the normal diagnostic error message. Do you have another set of keys you use to trigger the error?

@sevenautumns
Copy link
Author

@AlexanderBrevig
I am on rnix-lsp 0.2.5.

Do you have another set of keys you use to trigger the error?

At least for me there are no keys required at all. I tested adding the ' with another language selected. It works, but when I reopened the file afterwards helix would just straight up crash.

@archseer

Do you have auto-pairs disabled?

I do not have auto-pairs disabled. I'll provide my config here:

~/.config/helix/config.toml
theme = "autumn"

[editor]
idle-timeout = 0

[editor.cursor-shape]
insert = "bar"
normal = "block"
select = "block"

[keys]
[keys.insert]
down = "move_line_down"
left = "move_char_left"
right = "move_char_right"
up = "move_line_up"

[keys.normal.space]
n = ":new"
u = ":format"
~/.config/helix/languages.toml
[[language]]
name = "latex"

[language.language-server]
command = "ltex-ls"

[[language]]
name = "nix"

[language.formatter]
command = "/nix/store/8i4cph1j35jx722snpd2dbj9s8w60amr-nixfmt-0.5.0/bin/nixfmt"

[[language]]
comment-token = "#"
file-types = ["COMMIT_EDITMSG"]
name = "git-commit"
roots = []
scope = "git.commitmsg"

[language.indent]
tab-width = 2
unit = "  "

[language.language-server]
command = "ltex-ls"

[[language]]
file-types = ["md"]
name = "markdown"
roots = []
scope = "source.markdown"

[language.language-server]
command = "ltex-ls"

Other than these settings, default from 0361217 are used

@sevenautumns
Copy link
Author

@AlexanderBrevig

Here is a flake.nix which just straight up crashes helix.

flake.nix <----- Collapsible
{
  inputs = {
    utils.url = "github:numtide/flake-utils";
    devshell.url = "github:numtide/devshell";
    fenix.url = "github:nix-community/fenix";
    fenix.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { self, nixpkgs, utils, devshell, fenix, ... }@inputs:
    utils.lib.eachSystem [ "aarch64-linux" "i686-linux" "x86_64-linux" ]
    (system:
      let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [ devshell.overlay ];
        };
        rust-toolchain = with fenix.packages.${system};
          combine [ stable.rustc stable.cargo stable.clippy stable.rustfmt ];
      in rec {
        devShells.default = (pkgs.devshell.mkShell {
          imports = [
            # "${devshell}/extra/language/rust.nix"
            "${devshell}/extra/git/hooks.nix"
          ];
          name = "apex-rs-vanilla-dev-shell";
          packages = with pkgs; [
            rust-toolchain
            rust-analyzer
            cargo-outdated
            cargo-udeps
          ];
          devshell.startup.bindgen-hook.text = ''
            source ${pkgs.rustPlatform.bindgenHook}/nix-support/setup-hook
            populateBindgenEnv
          '';
          git.hooks = {
            enable = true;
            pre-commit.text = "nix flake check";
          };
          commands = [
            {
              package = "git-cliff";
              help = "Changelog generator";
            }
            {
              package = "treefmt";
              help = "Format project tree with recommended formatter";
              category = "formatter";
            }
            {
              name = "udeps";
              command = "cargo-udeps udeps";
              category = "formatter";
              help = "Find unused dependencies in Cargo.toml";
            }
            {
              name = "outdated";
              command = "cargo-outdated outdated";
              category = "formatter";
              help = "Find out-of-date dependencies";
            }
            {
              name = "build";
              command = "cd $PRJ_ROOT && cargo build";
              help = "Build project";
              category = "build";
            }
            {
              name = "build release";
              command = "cd $PRJ_ROOT && cargo build --release";
              help = "Build project in release mode";
              category = "build";
            }
            {
              name = "clippy";
              command = "cd $PRJ_ROOT && cargo clippy";
              help = "Build project";
              category = "build";
            }
            {
              name = "clippy release";
              command = "cd $PRJ_ROOT && cargo clippy --release";
              help = "Build project in release mode";
              category = "build";
            }
            {
              name = "watch";
              command = "cd $PRJ_ROOT && cargo watch -x clippy";
              help = "Watch project and continuesly clippy";
              category = "build";
            }
            {
              name = "watch release";
              command = "cd $PRJ_ROOT && cargo watch -x clippy --release";
              help = "Watch project and continuesly clippy in release mode";
              category = "build";
            }
          ];
        });
        checks = {
          nixpkgs-fmt = pkgs.runCommand "nixpkgs-fmt" {
            nativeBuildInputs = [ pkgs.nixpkgs-fmt ];
          } "nixpkgs-fmt --check ${./.}; touch $out";
          cargo-fmt = pkgs.runCommand "cargo-fmt" {
            nativeBuildInputs = [ rust-toolchain ];
          } "cd ${./.}; cargo fmt --check; touch $out";
        };
      });
}

With #3826 of course the output of the program changes to:

Program output
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidRanges', helix-core/src/syntax.rs:618:14
stack backtrace:
   0:     0x55a65d770ed4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h9c2a9d2774d81873
   1:     0x55a65cf94ccc - core::fmt::write::hba4337c43d992f49
   2:     0x55a65d76a8b5 - std::io::Write::write_fmt::heb73de6e02cfabed
   3:     0x55a65d772d7e - std::panicking::default_hook::{{closure}}::hc9a76eed0b18f82b
   4:     0x55a65d772aad - std::panicking::default_hook::h2e88d02087fae196
   5:     0x55a65d773325 - std::panicking::rust_panic_with_hook::habfdcc2e90f9fd4c
   6:     0x55a65d773234 - std::panicking::begin_panic_handler::{{closure}}::he054b2a83a51d2cd
   7:     0x55a65d771404 - std::sys_common::backtrace::__rust_end_short_backtrace::ha48b94ab49b30915
   8:     0x55a65d772f9d - rust_begin_unwind
   9:     0x55a65cf0bd93 - core::panicking::panic_fmt::h366d3a309ae17c94
  10:     0x55a65cf0be83 - core::result::unwrap_failed::hddd78f4658ac7d0f
  11:     0x55a65d05c372 - helix_core::syntax::Syntax::new::h3e77386699b9bd03
  12:     0x55a65d553450 - helix_view::document::Document::set_language::h4013a5d56dd28867
  13:     0x55a65d551e8e - helix_view::document::Document::open::hc8eeb61a7d9ec6b4
  14:     0x55a65d51c8e1 - helix_view::editor::Editor::open::h60cbbb87afa07f7b
  15:     0x55a65d2af6f9 - helix_term::application::Application::new::h626015731ae4f831
  16:     0x55a65d610201 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h5f3b37062c32a82c
  17:     0x55a65d5ecb42 - std::thread::local::LocalKey<T>::with::hb5d8ea16e9cadeef
  18:     0x55a65d5db2c8 - tokio::park::thread::CachedParkThread::block_on::h59b4805dfbf7bc54
  19:     0x55a65d635ed8 - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::h44c594da2be2f6c5
  20:     0x55a65d60c22e - tokio::runtime::Runtime::block_on::hdc7affd610a62c07
  21:     0x55a65d5d0f25 - hx::main::h3502fc2a3489134c
  22:     0x55a65d5d4213 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4f9548a5e84dface
  23:     0x55a65d5ec6ad - std::rt::lang_start::{{closure}}::h1c682f4407c90018
  24:     0x55a65d76514b - std::rt::lang_start_internal::h9c06694362b5b80c
  25:     0x55a65d5d1032 - main
  26:     0x7f7582fd124e - __libc_start_call_main
  27:     0x7f7582fd1309 - __libc_start_main@@GLIBC_2.34
  28:     0x55a65cf437d5 - _start
  29:                0x0 - <unknown>

@kirawi kirawi added A-tree-sitter Area: Tree-sitter A-core Area: Helix core improvements labels Sep 14, 2022
@the-mikedavis
Copy link
Member

It looks like this was introduced by 665e27f

@gabydd
Copy link
Member

gabydd commented Jun 21, 2023

minimal reproduction:

{
  startup.hook = ''
    sh
  ''
}

I assume it has something to do with this:

(#match? @_path "(^\\w*Phase|command|(pre|post)\\w*|(.*\\.)?\\w*([sS]cript|[hH]ook)|(.*\\.)?startup)$")
I'll dig into it a little bit later

@gabydd
Copy link
Member

gabydd commented Jun 22, 2023

looking at this the query:

((binding
attrpath: (attrpath (identifier) @_path)
expression: [
(indented_string_expression (string_fragment) @injection.content)
(binary_expression (indented_string_expression (string_fragment) @injection.content))
])
(#match? @_path "(^\\w*Phase|command|(pre|post)\\w*|(.*\\.)?\\w*([sS]cript|[hH]ook)|(.*\\.)?startup)$")
(#set! injection.language "bash")
(#set! injection.combined))

matches twice for the above nix text

QueryMatch { id: 0, pattern_index: 2, captures: [QueryCapture { node: {Node identifier (1, 2) - (1, 9)}, index: 2 }, QueryCapture { node: {Node string_fragment (1, 19) - (3, 2)}, index: 0 }] }
QueryMatch { id: 1, pattern_index: 2, captures: [QueryCapture { node: {Node identifier (1, 10) - (1, 14)}, index: 2 }, QueryCapture { node: {Node string_fragment (1, 19) - (3, 2)}, index: 0 }] }

so there is duplicated content nodes
[{Node string_fragment (1, 19) - (3, 2)}, {Node string_fragment (1, 19) - (3, 2)}]
which creates duplicated ranges:

helix/helix-core/src/syntax.rs

Lines 1192 to 1197 in eb81cf3

if let Some(config) = (injection_callback)(&lang_name) {
let ranges = intersect_ranges(
&layer.ranges,
&content_nodes,
included_children,
);

adding ranges.dedup(); after the above line did fix this issue but I am pretty sure that is not the correct fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-core Area: Helix core improvements A-tree-sitter Area: Tree-sitter C-bug Category: This is a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants