Skip to content

Commit 2cd3cf9

Browse files
committed
Merge pull request #116 from Wilfred/type_annotation_highlighting
Fix type annotations incorrectly highlighted as modules.
2 parents 061e6d8 + dd6d417 commit 2cd3cf9

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

rust-mode-tests.el

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,27 @@ this_is_not_a_string();)"
14031403
"\"/*! doc */\""
14041404
'("\"/*! doc */\"" font-lock-string-face)))
14051405

1406+
(ert-deftest font-lock-module ()
1407+
(rust-test-font-lock
1408+
"foo::bar"
1409+
'("foo" font-lock-type-face)))
1410+
1411+
(ert-deftest font-lock-submodule ()
1412+
(rust-test-font-lock
1413+
"foo::bar::baz"
1414+
'("foo" font-lock-type-face
1415+
"bar" font-lock-type-face)))
1416+
1417+
(ert-deftest font-lock-type-annotation ()
1418+
"Ensure type annotations are not confused with modules."
1419+
(rust-test-font-lock
1420+
"parse::<i32>();"
1421+
;; Only the i32 should have been highlighted.
1422+
'("i32" font-lock-type-face))
1423+
(rust-test-font-lock
1424+
"foo:: <i32>"
1425+
;; Only the i32 should have been highlighted.
1426+
'("i32" font-lock-type-face)))
14061427

14071428
(ert-deftest indent-method-chains-no-align ()
14081429
(let ((rust-indent-method-chain nil)) (test-indent

rust-mode.el

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
;;; Code:
1515

1616
(eval-when-compile (require 'rx)
17+
(require 'cl)
1718
(require 'compile)
1819
(require 'url-vars))
1920

@@ -525,6 +526,21 @@ function or trait. When nil, where will be aligned with fn or trait."
525526
(concat "\\_<" (regexp-opt words t) "\\_>"))
526527
(defconst rust-re-special-types (regexp-opt-symbols rust-special-types))
527528

529+
530+
(defun rust-module-font-lock-matcher (limit)
531+
"Matches module names \"foo::\" but does not match type annotations \"foo::<\"."
532+
(block nil
533+
(while t
534+
(let* ((symbol-then-colons (rx-to-string `(seq (group (regexp ,rust-re-ident)) "::")))
535+
(match (re-search-forward symbol-then-colons limit t)))
536+
(cond
537+
;; If we didn't find a match, there are no more occurrences
538+
;; of foo::, so return.
539+
((null match) (return nil))
540+
;; If this isn't a type annotation foo::<, we've found a
541+
;; match, so a return it!
542+
((not (looking-at (rx (0+ space) "<"))) (return match)))))))
543+
528544
(defvar rust-mode-font-lock-keywords
529545
(append
530546
`(
@@ -548,8 +564,8 @@ function or trait. When nil, where will be aligned with fn or trait."
548564
;; Field names like `foo:`, highlight excluding the :
549565
(,(concat (rust-re-grab rust-re-ident) ":[^:]") 1 font-lock-variable-name-face)
550566

551-
;; Module names like `foo::`, highlight including the ::
552-
(,(rust-re-grab (concat rust-re-ident "::")) 1 font-lock-type-face)
567+
;; Module names like `foo::`, highlight excluding the ::
568+
(rust-module-font-lock-matcher 1 font-lock-type-face)
553569

554570
;; Lifetimes like `'foo`
555571
(,(concat "'" (rust-re-grab rust-re-ident) "[^']") 1 font-lock-variable-name-face)

0 commit comments

Comments
 (0)