emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/rust-mode dd6d417 215/486: Fix type annotations incorrectl


From: ELPA Syncer
Subject: [nongnu] elpa/rust-mode dd6d417 215/486: Fix type annotations incorrectly highlighted as modules.
Date: Sat, 7 Aug 2021 09:25:21 -0400 (EDT)

branch: elpa/rust-mode
commit dd6d417c1404efcf2364a61fd7e855ec134a991f
Author: Wilfred Hughes <me@wilfred.me.uk>
Commit: Wilfred Hughes <me@wilfred.me.uk>

    Fix type annotations incorrectly highlighted as modules.
    
    Previously, we were always treating :: as a module, but Rust
    allows type annotations using :: e.g.
    
        parse::<i32>();
    
    This also changes module highlighting so that only the module name is
    highlighted, excluding the ::. This makes rust-mode consistent with
    other Emacs modes, such as c++-mode and ruby-mode.
---
 rust-mode-tests.el | 21 +++++++++++++++++++++
 rust-mode.el       | 20 ++++++++++++++++++--
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index e7a0429..e41245f 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -1403,6 +1403,27 @@ this_is_not_a_string();)"
    "\"/*! doc */\""
    '("\"/*! doc */\"" font-lock-string-face)))
 
+(ert-deftest font-lock-module ()
+  (rust-test-font-lock
+   "foo::bar"
+   '("foo" font-lock-type-face)))
+
+(ert-deftest font-lock-submodule ()
+  (rust-test-font-lock
+   "foo::bar::baz"
+   '("foo" font-lock-type-face
+     "bar" font-lock-type-face)))
+
+(ert-deftest font-lock-type-annotation ()
+  "Ensure type annotations are not confused with modules."
+  (rust-test-font-lock
+   "parse::<i32>();"
+   ;; Only the i32 should have been highlighted.
+   '("i32" font-lock-type-face))
+  (rust-test-font-lock
+   "foo:: <i32>"
+   ;; Only the i32 should have been highlighted.
+   '("i32" font-lock-type-face)))
 
 (ert-deftest indent-method-chains-no-align ()
   (let ((rust-indent-method-chain nil)) (test-indent
diff --git a/rust-mode.el b/rust-mode.el
index 8049273..4697c70 100644
--- a/rust-mode.el
+++ b/rust-mode.el
@@ -14,6 +14,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'rx)
+                   (require 'cl)
                    (require 'compile)
                    (require 'url-vars))
 
@@ -525,6 +526,21 @@ function or trait.  When nil, where will be aligned with 
fn or trait."
   (concat "\\_<" (regexp-opt words t) "\\_>"))
 (defconst rust-re-special-types (regexp-opt-symbols rust-special-types))
 
+
+(defun rust-module-font-lock-matcher (limit)
+  "Matches module names \"foo::\" but does not match type annotations 
\"foo::<\"."
+  (block nil
+    (while t
+      (let* ((symbol-then-colons (rx-to-string `(seq (group (regexp 
,rust-re-ident)) "::")))
+             (match (re-search-forward symbol-then-colons limit t)))
+        (cond
+         ;; If we didn't find a match, there are no more occurrences
+         ;; of foo::, so return.
+         ((null match) (return nil))
+         ;; If this isn't a type annotation foo::<, we've found a
+         ;; match, so a return it!
+         ((not (looking-at (rx (0+ space) "<"))) (return match)))))))
+
 (defvar rust-mode-font-lock-keywords
   (append
    `(
@@ -548,8 +564,8 @@ function or trait.  When nil, where will be aligned with fn 
or trait."
      ;; Field names like `foo:`, highlight excluding the :
      (,(concat (rust-re-grab rust-re-ident) ":[^:]") 1 
font-lock-variable-name-face)
 
-     ;; Module names like `foo::`, highlight including the ::
-     (,(rust-re-grab (concat rust-re-ident "::")) 1 font-lock-type-face)
+     ;; Module names like `foo::`, highlight excluding the ::
+     (rust-module-font-lock-matcher 1 font-lock-type-face)
 
      ;; Lifetimes like `'foo`
      (,(concat "'" (rust-re-grab rust-re-ident) "[^']") 1 
font-lock-variable-name-face)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]