Skip to content

Commit c801dda

Browse files
committed
Merge pull request #77 from tromey/fix-byte-compiler-add-lexbind
add lexical binding and have tests check for byte compiler warnings
2 parents 5e51aaa + 866df37 commit c801dda

File tree

2 files changed

+85
-69
lines changed

2 files changed

+85
-69
lines changed

run_rust_emacs_tests.sh

+9
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,13 @@ $( $EMACS -batch --eval "(require 'ert)" > /dev/null 2>&1 ) || {
3131
exit 3
3232
};
3333

34+
warnings="$( $EMACS -Q -batch -f batch-byte-compile rust-mode.el 2>&1 | grep -v '^Wrote ' )"
35+
if [ -n "$warnings" ]; then
36+
echo "Byte-compilation failed:"
37+
echo "$warnings"
38+
exit 4
39+
else
40+
echo "Byte-compilation passed."
41+
fi
42+
3443
$EMACS -batch -l rust-mode.el -l rust-mode-tests.el -f ert-run-tests-batch-and-exit

rust-mode.el

+76-69
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
;;; rust-mode.el --- A major emacs mode for editing Rust source code
1+
;;; rust-mode.el --- A major emacs mode for editing Rust source code -*-lexical-binding: t-*-
22

33
;; Version: 0.2.0
44
;; Author: Mozilla
@@ -11,7 +11,11 @@
1111
;;; Code:
1212

1313
(eval-when-compile (require 'misc)
14-
(require 'rx))
14+
(require 'rx)
15+
(require 'compile)
16+
(require 'url-vars))
17+
18+
(defvar electric-pair-inhibit-predicate)
1519

1620
;; for GNU Emacs < 24.3
1721
(eval-when-compile
@@ -20,6 +24,70 @@
2024
"Set variable VAR to value VAL in current buffer."
2125
(list 'set (list 'make-local-variable (list 'quote var)) val))))
2226

27+
(defconst rust-re-ident "[[:word:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
28+
29+
(defconst rust-re-non-standard-string
30+
(rx
31+
(or
32+
;; Raw string: if it matches, it ends up with the starting character
33+
;; of the string as group 1, any ending backslashes as group 4, and
34+
;; the ending character as either group 5 or group 6.
35+
(seq
36+
;; The "r" starts the raw string. Capture it as group 1 to mark it as such syntactically:
37+
(group "r")
38+
39+
;; Then either:
40+
(or
41+
;; a sequence at least one "#" (followed by quote). Capture all
42+
;; but the last "#" as group 2 for this case.
43+
(seq (group (* "#")) "#\"")
44+
45+
;; ...or a quote without any "#". Capture it as group 3. This is
46+
;; used later to match the opposite quote only if this capture
47+
;; occurred
48+
(group "\""))
49+
50+
;; The contents of the string:
51+
(*? anything)
52+
53+
;; If there are any backslashes at the end of the string, capture
54+
;; them as group 4 so we can suppress the normal escape syntax
55+
;; parsing:
56+
(group (* "\\"))
57+
58+
;; Then the end of the string--the backreferences ensure that we
59+
;; only match the kind of ending that corresponds to the beginning
60+
;; we had:
61+
(or
62+
;; There were "#"s - capture the last one as group 5 to mark it as
63+
;; the end of the string:
64+
(seq "\"" (backref 2) (group "#"))
65+
66+
;; No "#"s - capture the ending quote (using a backref to group 3,
67+
;; so that we can't match a quote if we had "#"s) as group 6
68+
(group (backref 3))
69+
70+
;; If the raw string wasn't actually closed, go all the way to the end
71+
string-end))
72+
73+
;; Character literal: match the beginning ' of a character literal
74+
;; as group 7, and the ending one as group 8
75+
(seq
76+
(group "'")
77+
(or
78+
(seq
79+
"\\"
80+
(or
81+
(: "U" (= 8 xdigit))
82+
(: "u" (= 4 xdigit))
83+
(: "x" (= 2 xdigit))
84+
(any "'nrt0\"\\")))
85+
(not (any "'\\"))
86+
)
87+
(group "'"))
88+
)
89+
))
90+
2391
(defun rust-looking-back-str (str)
2492
"Like `looking-back' but for fixed strings rather than regexps (so that it's not so slow)"
2593
(let ((len (length str)))
@@ -145,8 +213,6 @@
145213
(backward-up-list)
146214
(back-to-indentation))))
147215

148-
(defconst rust-re-ident "[[:word:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
149-
150216
(defun rust-align-to-method-chain ()
151217
(save-excursion
152218
;; for method-chain alignment to apply, we must be looking at
@@ -420,6 +486,9 @@
420486
("fn" . font-lock-function-name-face)
421487
("static" . font-lock-constant-face)))))
422488

489+
(defvar font-lock-beg)
490+
(defvar font-lock-end)
491+
423492
(defun rust-font-lock-extend-region ()
424493
"Extend the region given by `font-lock-beg' and `font-lock-end'
425494
to include the beginning of a string or comment if it includes
@@ -490,68 +559,6 @@
490559
(set-match-data (nth 1 ret-list))
491560
(nth 0 ret-list))))
492561

493-
(defconst rust-re-non-standard-string
494-
(rx
495-
(or
496-
;; Raw string: if it matches, it ends up with the starting character
497-
;; of the string as group 1, any ending backslashes as group 4, and
498-
;; the ending character as either group 5 or group 6.
499-
(seq
500-
;; The "r" starts the raw string. Capture it as group 1 to mark it as such syntactically:
501-
(group "r")
502-
503-
;; Then either:
504-
(or
505-
;; a sequence at least one "#" (followed by quote). Capture all
506-
;; but the last "#" as group 2 for this case.
507-
(seq (group (* "#")) "#\"")
508-
509-
;; ...or a quote without any "#". Capture it as group 3. This is
510-
;; used later to match the opposite quote only if this capture
511-
;; occurred
512-
(group "\""))
513-
514-
;; The contents of the string:
515-
(*? anything)
516-
517-
;; If there are any backslashes at the end of the string, capture
518-
;; them as group 4 so we can suppress the normal escape syntax
519-
;; parsing:
520-
(group (* "\\"))
521-
522-
;; Then the end of the string--the backreferences ensure that we
523-
;; only match the kind of ending that corresponds to the beginning
524-
;; we had:
525-
(or
526-
;; There were "#"s - capture the last one as group 5 to mark it as
527-
;; the end of the string:
528-
(seq "\"" (backref 2) (group "#"))
529-
530-
;; No "#"s - capture the ending quote (using a backref to group 3,
531-
;; so that we can't match a quote if we had "#"s) as group 6
532-
(group (backref 3))
533-
534-
;; If the raw string wasn't actually closed, go all the way to the end
535-
string-end))
536-
537-
;; Character literal: match the beginning ' of a character literal
538-
;; as group 7, and the ending one as group 8
539-
(seq
540-
(group "'")
541-
(or
542-
(seq
543-
"\\"
544-
(or
545-
(: "U" (= 8 xdigit))
546-
(: "u" (= 4 xdigit))
547-
(: "x" (= 2 xdigit))
548-
(any "'nrt0\"\\")))
549-
(not (any "'\\"))
550-
)
551-
(group "'"))
552-
)
553-
))
554-
555562
(defun rust-look-for-non-standard-string (bound)
556563
;; Find a raw string or character literal, but only if it's not in the middle
557564
;; of another string or a comment.
@@ -769,7 +776,7 @@
769776
;; Otherwise, if the ident: appeared with anything other than , or {
770777
;; before it, it can't be part of a struct initializer and therefore
771778
;; must be denoting a type.
772-
nil
779+
(t nil)
773780
))
774781
))
775782

@@ -1096,7 +1103,7 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
10961103
(progn
10971104
(goto-char (match-beginning 0))
10981105
;; Go to the closing brace
1099-
(condition-case err
1106+
(condition-case nil
11001107
(forward-sexp)
11011108
(scan-error
11021109
;; The parentheses are unbalanced; instead of being unable to fontify, just jump to the end of the buffer
@@ -1169,7 +1176,7 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
11691176
(error-or-warning "\\(?:[Ee]rror\\|\\([Ww]arning\\)\\)"))
11701177
(let ((re (concat "^" file ":" start-line ":" start-col
11711178
": " end-line ":" end-col
1172-
" \\(?:[Ee]rror\\|\\([Ww]arning\\)\\):")))
1179+
" " error-or-warning ":")))
11731180
(cons re '(1 (2 . 4) (3 . 5) (6)))))
11741181
"Specifications for matching errors in rustc invocations.
11751182
See `compilation-error-regexp-alist' for help on their format.")

0 commit comments

Comments
 (0)