Closed Dushistov closed 4 years ago
I will have a look. What version of the repo do you have installed?
@mookid
What version of the repo do you have installed?
I installed rust-mode via melpa and it is as I mentioned:
rust-mode 20200229.1547
I cloned current master (86650056717be0661feae32e294ff991c087ed4d) and seems it is completely match current master:
LANG=C diff -ur ~/.emacs.d/elpa/rust-mode-20200229.1547/ rust-mode/
Only in rust-mode/: .git
Only in rust-mode/: .github
Only in rust-mode/: .gitignore
Only in rust-mode/: .travis.yml
Only in rust-mode/: LICENSE-APACHE
Only in rust-mode/: LICENSE-MIT
Only in rust-mode/: README.md
Only in rust-mode/: run_rust_emacs_tests.sh
Only in rust-mode/: run_rust_emacs_tests_docker.sh
Only in /home/evgeniy/.emacs.d/elpa/rust-mode-20200229.1547/: rust-mode-autoloads.el
Only in /home/evgeniy/.emacs.d/elpa/rust-mode-20200229.1547/: rust-mode-pkg.el
Only in rust-mode/: rust-mode-tests.el
diff -ur /home/evgeniy/.emacs.d/elpa/rust-mode-20200229.1547/rust-mode.el rust-mode/rust-mode.el
--- /home/evgeniy/.emacs.d/elpa/rust-mode-20200229.1547/rust-mode.el 2020-03-01 20:36:21.753564920 +0300
+++ rust-mode/rust-mode.el 2020-03-02 19:53:22.723344491 +0300
@@ -1,7 +1,6 @@
;;; rust-mode.el --- A major emacs mode for editing Rust source code -*-lexical-binding: t-*-
;; Version: 0.5.0
-;; Package-Version: 20200229.1547
;; Author: Mozilla
;; Url: https://github.com/rust-lang/rust-mode
;; Keywords: languages
Only in /home/evgeniy/.emacs.d/elpa/rust-mode-20200229.1547/: rust-mode.elc
Only in rust-mode/: test-by-cp
Only in rust-mode/: test-from-git
Only in rust-mode/: test-project
@Dushistov I fail to reproduce it for now. Can you please install the last version of master and try again?
Also, can I see your config somewhere?
@mookid
Can you please install the last version of master and try again?
I installed it. And I will wait for bug.
Also, can I see your config somewhere?
;; Rust (require 'req-package) (use-package rust-mode :mode "\\.rs\\'" :init (setq rust-format-on-save t) (setq-default indent-tabs-mode nil))
(require 'rust-mode) (require 'lsp-mode) (add-hook 'rust-mode-hook #'lsp)
(require 'cargo) (setq cargo-process--command-check "check --release --all-targets") (setq cargo-process--command-test "test --release") (setq cargo-process--command-current-test "test --release")
(defun cargo-cmds-release-toggle () (interactive) (if (equal cargo-process--command-check "check --release --all-targets") (progn (setq cargo-process--command-check "check --all-targets") (setq cargo-process--command-test "test") (setq cargo-process--command-current-test "test")) (progn (setq cargo-process--command-check "check --release --all-targets") (setq cargo-process--command-test "test --release") (setq cargo-process--command-current-test "test --release"))))
(add-hook 'rust-mode-hook
(lambda ()
(local-set-key "\C-cj" 'lsp-find-definition)
(local-set-key "\M-*" 'pop-tag-mark)
(local-set-key (kbd "C-
(defun rust-multiline-error-filter () (save-excursion (let ((start compilation-filter-start) (end (point))) (goto-char start) (beginning-of-line) ; is this necessary? should not harm ... (while (re-search-forward "^\(error\|warning\)\(?:\[E[0-9]+\]\)?:[^\n]*[\n]" end t) (put-text-property (match-beginning 0) (match-end 0) 'compilation-multiline t))))) (add-hook 'rust-mode-hook (lambda () (add-hook 'compilation-filter-hook #'rust-multiline-error-filter)))
;; Rust end
I have the same issue, and it seems to happen exactly when the file has a syntax error. Valid code will be formatted fine, but invalid code results in opening stdin.
What kind of syntax error are we talking about? An example would be super useful.
I tried for instance fn func(
or "abcd
and my file is saved normally.
I tried
fn main() {
}
It saved fine and reformatted to fn main() {}
.
But
fn main() {
opens stdin.
This happens for every syntax error I can think of, so likely there is some other difference between our setups.
In *Messages*
I see:
rust--format-error-handler: End of buffer
I have rust-mode 20200303.932 from melpa and emacs 26.3.
Thanks for the repro! I still can't trigger it myself. What is (list rust-format-show-buffer rust-format-goto-problem)
?
What if you redefine rust--format-error-handler
like so?
(defun rust--format-error-handler ()
(condition-case nil
(let ((ok nil))
(when rust-format-show-buffer
(display-buffer (get-buffer rust-rustfmt-buffername))
(setq ok t))
(when rust-format-goto-problem
(rust-goto-format-problem)
(setq ok t))
ok)))
What is
(list rust-format-show-buffer rust-format-goto-problem)
?
(nil t)
What if you redefine
rust--format-error-handler
like so?
Same behaviour.
Also maybe helpful
[nix-shell:~/materialize]$ rustfmt --version
rustfmt 1.4.11-stable (1838235 2019-12-03)
Ok, this is different from what I have. And what is the content of *rustfmt*?
edit: fixed name.
*rust-fmt*
doesn't seem to exist.
I have to head out now, but I'll see tomorrow if I can make a repro with nix.
Closing for now, please repopen with other details if it reappears.
reappears
I just updated rust-mode to 20200322.1749 and I still consistently have this behavior on every save with invalid syntax.
@jamii can you please add more details? what is the content of the rustfmt buffer?
*rustfmt*
contains
error: this file contains an un-closed delimiter
--> <stdin>:1:13
|
1 | fn main() {
| - ^
| |
| un-closed delimiter
*Messages*
contains
Saving file /home/jamie/test.rs...
Quit
(The quit is me exiting the "save file" dialog)
Otherwise the behaviour I see is the same as before - when I hit save it switches to a buffer called <stdin>
and then asks where to save that buffer.
So it gets to
Debugger entered--returning value: 5
1-(6)
* (forward-char (1- (cdr target-point)))
* (progn (switch-to-buffer target-buffer) (goto-char (point-min)) (forward-line (1- (car target-point))) (forward-char (1- (cdr target-point))))
* (if (and target-buffer target-point) (progn (switch-to-buffer target-buffer) (goto-char (point-min)) (forward-line (1- (car target-point))) (forward-char (1- (cdr target-point)))))
* (let ((target-buffer (save-current-buffer (set-buffer rustfmt) (save-excursion (goto-char (point-min)) (if (re-search-forward "--> \\([^:]+\\):" nil t) (progn (match-string 1)))))) (target-point (save-current-buffer (set-buffer rustfmt) (let ((regex "--> [^:]+:\\([0-9]+\\):\\([0-9]+\\)")) (if (or (re-search-forward regex nil t) (progn ... ...)) (progn (cons ... ...)))))) (target-problem (save-current-buffer (set-buffer rustfmt) (save-excursion (if (re-search-backward "^error:.+\n" nil t) (progn (forward-char ...) (let ... ...))))))) (if (and target-buffer target-point) (progn (switch-to-buffer target-buffer) (goto-char (point-min)) (forward-line (1- (car target-point))) (forward-char (1- (cdr target-point))))) (message target-problem))
* (if (not rustfmt) (message "No *rustfmt*, no problems.") (let ((target-buffer (save-current-buffer (set-buffer rustfmt) (save-excursion (goto-char (point-min)) (if (re-search-forward "--> \\([^:]+\\):" nil t) (progn ...))))) (target-point (save-current-buffer (set-buffer rustfmt) (let ((regex "--> [^:]+:\\([0-9]+\\):\\([0-9]+\\)")) (if (or ... ...) (progn ...))))) (target-problem (save-current-buffer (set-buffer rustfmt) (save-excursion (if (re-search-backward "^error:.+\n" nil t) (progn ... ...)))))) (if (and target-buffer target-point) (progn (switch-to-buffer target-buffer) (goto-char (point-min)) (forward-line (1- (car target-point))) (forward-char (1- (cdr target-point))))) (message target-problem)))
* (let ((rustfmt (get-buffer rust-rustfmt-buffername))) (if (not rustfmt) (message "No *rustfmt*, no problems.") (let ((target-buffer (save-current-buffer (set-buffer rustfmt) (save-excursion (goto-char ...) (if ... ...)))) (target-point (save-current-buffer (set-buffer rustfmt) (let (...) (if ... ...)))) (target-problem (save-current-buffer (set-buffer rustfmt) (save-excursion (if ... ...))))) (if (and target-buffer target-point) (progn (switch-to-buffer target-buffer) (goto-char (point-min)) (forward-line (1- (car target-point))) (forward-char (1- (cdr target-point))))) (message target-problem))))
* (lambda nil "Jumps to problem reported by rustfmt, if any.\nIn case of multiple problems cycles through them. Displays the\nrustfmt complain in the echo area." (interactive) (let ((rustfmt (get-buffer rust-rustfmt-buffername))) (if (not rustfmt) (message "No *rustfmt*, no problems.") (let ((target-buffer (save-current-buffer (set-buffer rustfmt) (save-excursion ... ...))) (target-point (save-current-buffer (set-buffer rustfmt) (let ... ...))) (target-problem (save-current-buffer (set-buffer rustfmt) (save-excursion ...)))) (if (and target-buffer target-point) (progn (switch-to-buffer target-buffer) (goto-char (point-min)) (forward-line (1- ...)) (forward-char (1- ...)))) (message target-problem)))))()
* apply((lambda nil "Jumps to problem reported by rustfmt, if any.\nIn case of multiple problems cycles through them. Displays the\nrustfmt complain in the echo area." (interactive) (let ((rustfmt (get-buffer rust-rustfmt-buffername))) (if (not rustfmt) (message "No *rustfmt*, no problems.") (let ((target-buffer (save-current-buffer ... ...)) (target-point (save-current-buffer ... ...)) (target-problem (save-current-buffer ... ...))) (if (and target-buffer target-point) (progn (switch-to-buffer target-buffer) (goto-char ...) (forward-line ...) (forward-char ...))) (message target-problem))))) nil)
* rust-goto-format-problem()
rust--format-error-handler()
rust-format-buffer()
rust-before-save-hook()
run-hooks(before-save-hook)
basic-save-buffer(t)
save-buffer(1)
funcall-interactively(save-buffer 1)
call-interactively(save-buffer nil nil)
command-execute(save-buffer)
At this point target-buffer
is set to "<stdin>"
and that buffer is open. If I hit next it jumps to:
Debugger entered--entering a function:
* format("rust-before-save-hook: %S %S" end-of-buffer nil)
rust-before-save-hook()
run-hooks(before-save-hook)
basic-save-buffer(t)
save-buffer(1)
funcall-interactively(save-buffer 1)
call-interactively(save-buffer nil nil)
command-execute(save-buffer)
It doesn't ever reach (message target-problem)
on L1541 of rust-mode.el, so I assume this jump was some kind of error handler? I'm not really sure how to follow the jump in the debugger.
At this point the <stdin>
buffer is empty, so that forward-char will result in an "end of buffer" error.
The numbers in target-point
seem to be correct for the syntax error in test.rs
, so perhaps target-buffer
is just wrong.
Oh I see why you're asking about *rustfmt*
now - it does have the wrong filename.
I put a breakpoint on rust--format-fix-rustfmt-buffer
and it doesn't seem to get triggered.
@jamii can you try https://github.com/rust-lang/rust-mode/commit/e4bdc1defc8b215835d5e7de5c7f2b4137187455 ?
I believe that for some reason rust--format-fix-rustfmt-buffer
fails to replace the stdin markers, it might be because because of some ansi-color thing (it might explain why it's different across machines as well). The content of rustfmt is supposed to be
error: this file contains an un-closed delimiter
--> foo.rs:1:13
|
1 | fn main() {
| - ^
| |
| un-closed delimiter
after rust--format-fix-rustfmt-buffer.
Oh I see why you're asking about
*rustfmt*
now - it does have the wrong filename.I put a breakpoint on
rust--format-fix-rustfmt-buffer
and it doesn't seem to get triggered.
interesting! and what if ret
in rust--format-call?
ret
is 1.
It seems to skip straight past the call to fix, so I'm suspicious that I have old cached bytecode or something. If I evaluate the source for rust--format-call
I stop seeing this bug until I restart.
Cool. So I guess it can be closed?
Yeah, force-recompiling bytecode fixes it. Sorry for wasting your time :S
no worries.
It is random, I have no idea how to reproduce it.
Time to time when I save current buffer with rust-mode, let's call it
a.rs
, emacs does not save it, and instead it open buffer stdin, in other words I press C-x s and current buffer change to "stdin" buffer. This buffer is empty, anda.rs
still in modified state. I switch back toa.rs
, try to save it and again empty stdin instead of a.rs.So actually I can not save my rust buffer, I have to set "Rust Format On Save" to off to make possible save, or change mode from rust-mode to text-mode.
This bug appear only recently, so I suppose it is related to last "rustfmt" changes in master.
GNU Emacs 26.3 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.10) of 2019-08-29 rust-mode 20200229.1547