From f0b987c32c358703d85d3be010bb2fe0299192be Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 19 Aug 2025 11:12:01 -0700 Subject: [PATCH] rust-ts-mode: handle invalid rust syntax without signaling Don't signal an error when encountering invalid rust syntax. Without this patch, invalid rust code would prevent a chunk of the buffer from being highlighted (bug#79272). * lisp/progmodes/rust-ts-mode.el (rust-ts-mode--fontify-scope): (rust-ts-mode--fontify-pattern): Avoid calling `string-match-p' on nil when a node is missing a parent. * test/lisp/progmodes/rust-ts-mode-resources/font-lock-no-parent.rs: Rust file that reproduces the issue. * test/lisp/progmodes/rust-ts-mode-tests.el: Test case to reproduce the issue. --- lisp/progmodes/rust-ts-mode.el | 9 +++++---- .../rust-ts-mode-resources/font-lock-no-parent.rs | 7 +++++++ test/lisp/progmodes/rust-ts-mode-tests.el | 7 +++++++ 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 test/lisp/progmodes/rust-ts-mode-resources/font-lock-no-parent.rs diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el index a5c217c0a4b..a98d621af65 100644 --- a/lisp/progmodes/rust-ts-mode.el +++ b/lisp/progmodes/rust-ts-mode.el @@ -366,7 +366,8 @@ See https://doc.rust-lang.org/reference/tokens.html#suffixes.") tail-p (string-match-p "\\`\\(?:use_list\\|call_expression\\|use_as_clause\\|use_declaration\\)\\'" - (treesit-node-type (treesit-node-parent (treesit-node-parent node))))) + (or (treesit-node-type (treesit-node-parent (treesit-node-parent node))) + "no_parent"))) nil) (t 'font-lock-constant-face)))) (when face @@ -387,9 +388,9 @@ See https://doc.rust-lang.org/reference/tokens.html#suffixes.") ,(treesit-query-compile 'rust '((identifier) @id (shorthand_field_identifier) @id))))) (pcase-dolist (`(_name . ,id) captures) - (unless (string-match-p "\\`scoped_\\(?:type_\\)?identifier\\'" - (treesit-node-type - (treesit-node-parent id))) + (unless (string-match-p + "\\`scoped_\\(?:type_\\)?identifier\\'" + (or (treesit-node-type (treesit-node-parent id)) "no_parent")) (treesit-fontify-with-override (treesit-node-start id) (treesit-node-end id) 'font-lock-variable-name-face override start end))))))) diff --git a/test/lisp/progmodes/rust-ts-mode-resources/font-lock-no-parent.rs b/test/lisp/progmodes/rust-ts-mode-resources/font-lock-no-parent.rs new file mode 100644 index 00000000000..85d0ccc9bf3 --- /dev/null +++ b/test/lisp/progmodes/rust-ts-mode-resources/font-lock-no-parent.rs @@ -0,0 +1,7 @@ ++// intentionally invalid syntax ++const THING: [u8; 48] = []; + +// should recover here and highlight the text below +trait Foo() { +// ^ font-lock-keyword-face +} diff --git a/test/lisp/progmodes/rust-ts-mode-tests.el b/test/lisp/progmodes/rust-ts-mode-tests.el index d2e28dcfbd7..32d64260a87 100644 --- a/test/lisp/progmodes/rust-ts-mode-tests.el +++ b/test/lisp/progmodes/rust-ts-mode-tests.el @@ -39,6 +39,13 @@ (ert-font-lock-test-file (ert-resource-file "font-lock-number.rs") 'rust-ts-mode))) +(ert-deftest rust-ts-test-no-parent () + (skip-unless (treesit-ready-p 'rust)) + (let ((treesit-font-lock-level 4) + (rust-ts-mode-fontify-number-suffix-as-type t)) + (ert-font-lock-test-file (ert-resource-file "font-lock-no-parent.rs") + 'rust-ts-mode))) + (provide 'rust-ts-mode-tests) ;;; rust-ts-mode-tests.el ends here