summaryrefslogtreecommitdiff
path: root/rust-mode-tests.el
diff options
context:
space:
mode:
authorJim Blandy <jimb@red-bean.com>2022-11-01 13:22:58 -0700
committerJim Blandy <jimb@red-bean.com>2022-11-02 09:35:45 -0700
commit42ba58df6c3071576f2ddc6e0a285db57b7e690b (patch)
tree36f5ac3cd3d929a7a4c6a27ae131d5ff52a5579b /rust-mode-tests.el
parentb4537b6f5fa65626c1bab944681b35769cab9b5c (diff)
downloadrust-mode-42ba58df6c3071576f2ddc6e0a285db57b7e690b.tar.gz
Simplify and correct angle bracket propertizing and macro argument detection.
Fixes #465. When `rust-syntax-propertize` uses `rust-macro-scopes` to find ranges of text that are macro arguments, it ends up inadvertently poisoning the `syntax-ppss` cache by applying it to text that doesn't have the necessary `syntax-table` properties applied yet - the very job that `rust-syntax-propertize` is trying to do. However, `rust-macro-scopes` does much more work than necessary. Rather than producing a list of ranges of macro arguments, we can just use the list of enclosing opening parens provided by syntax-ppss, checking each paren to see if it seems to be a macro or `macro_rules` call. We have to keep syntax-ppss's cache accurate for other reasons anyway, so we might as well just use its data, rather than introducing another cache of our own - especially a problematic one (see #465). * rust-mode.el (rust-in-macro): Consult `syntax-ppss`'s list of enclosing parens, rather than using `rust-macro-scope`. Remove optional arguments, which were only used by tests. (rust-macro-scopes, rust-macro-scope): Delete. Now we just use `syntax-ppss`'s internal cache. (rust-syntax-propertize): Don't bind `rust-macro-scopes`. (rust-looking-back-macro-rules): New function. (rust-looking-back-macro): Support a space between macro name and `!`, by consulting `rust-expression-introducers`. (rust-expression-introducers): New constant. Use in `rust-looking-back-macro` and `rust-is-in-expression-context`. (rust-is-in-expression-context): Use `rust-expression-introducers`. (rust-looking-back-ident): Don't use `looking-back`. We've already moved to the correct spot for `looking-at`, within a `save-excursion`. * rust-mode-tests.el: Update tests.
Diffstat (limited to 'rust-mode-tests.el')
-rw-r--r--rust-mode-tests.el72
1 files changed, 22 insertions, 50 deletions
diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index e4949b2..abbfcb6 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -3116,7 +3116,7 @@ macro_c!{
(syntax-ppss))))
-(ert-deftest rust-test-in-macro-no-caching ()
+(ert-deftest rust-test-in-macro-around-opening ()
(should-not
(with-temp-buffer
(insert
@@ -3125,66 +3125,38 @@ macro_c!{
struct Boo<D> {}
")
(rust-mode)
- (search-backward "macro")
- ;; do not use the cache
- (let ((rust-macro-scopes nil))
- (rust-in-macro)))))
-
-(ert-deftest rust-test-in-macro-fake-cache ()
- (should
- (with-temp-buffer
- (insert
- "fn foo<A>(a:A) {
- macro_c!{
- struct Boo<D> {}
-")
- (rust-mode)
- (search-backward "macro")
- ;; make the cache lie to make the whole buffer in scope
- ;; we need to be at paren level 1 for this to work
- (let ((rust-macro-scopes `((,(point-min) ,(point-max)))))
- (rust-in-macro)))))
-
-(ert-deftest rust-test-in-macro-broken-cache ()
- (should-error
- (with-temp-buffer
- (insert
- "fn foo<A>(a:A) {
- macro_c!{
- struct Boo<D> {}
-")
- (rust-mode)
- (search-backward "Boo")
- ;; do we use the cache at all
- (let ((rust-macro-scopes '(I should break)))
- (rust-in-macro)))))
+ (search-backward "macro_c")
+ (and
+ (not (rust-in-macro))
+ (progn (forward-thing 'symbol 1) (not (rust-in-macro)))
+ (progn (forward-char 1) (rust-in-macro))
+ (progn (goto-char (point-max)) (rust-in-macro))))))
(ert-deftest rust-test-in-macro-nested ()
- (should
- (equal
- (with-temp-buffer
- (insert
- "macro_rules! outer {
+ (with-temp-buffer
+ (insert
+ "macro_rules! outer {
() => { vec![] };
}")
- (rust-mode)
- (rust-macro-scope (point-min) (point-max)))
- '((38 40) (20 45)))))
+ (rust-mode)
+ (should (progn (goto-char 20) (not (rust-in-macro))))
+ (should (progn (goto-char 21) (eq (rust-in-macro) 20)))
+ (should (progn (goto-char 38) (eq (rust-in-macro) 20)))
+ (should (progn (goto-char 39) (eq (rust-in-macro) 38)))
+ (should (progn (goto-char 40) (eq (rust-in-macro) 20)))
+ (should (progn (goto-char 44) (eq (rust-in-macro) 20)))
+ (should (progn (goto-char 45) (not (rust-in-macro))))))
(ert-deftest rust-test-in-macro-not-with-space ()
- (should
- (equal
- (with-temp-buffer
- (insert
+ (with-temp-buffer
+ (insert
"fn foo<T>() {
if !(mem::size_of::<T>() > 8) {
bar()
}
}")
- (rust-mode)
- (rust-macro-scope (point-min) (point-max)))
- 'empty)))
-
+ (rust-mode)
+ (should (progn (goto-char 24) (not (rust-in-macro))))))
(ert-deftest rust-test-paren-matching-type-with-module-name ()
(rust-test-matching-parens