Skip to content

Commit a8f76ed

Browse files
fmdkddswsnr
authored andcommitted
Fix error related to multiple binary targets
When both 'src/lib.rs' and 'src/main.rs' are present in the project, we default to invoking `cargo rustc`. This command requires an explicit binary name with the `--bin` flag, otherwise it causes the error described in GH-23. This commit adds logic to parse the output of `cargo read-manifest` to determine the target type to check, based on the buffer file name. If the file name matches one of the targets, this target is chosen. Otherwise, the first target is chosen as a default. If the target is a binary, we also extract the binary name and set a new `flycheck-rust-binary-name` variable (see flycheck/flycheck#958) to solve the error. I've tested this work with 'src/main.rs' binaries as well as multiples binaries under 'src/bin'. Closes GH-25, fixes GH-23, and adds logic to tackle GH-8.
1 parent e03c895 commit a8f76ed

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

flycheck-rust.el

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
;; URL: https://github.com/flycheck/flycheck-rust
77
;; Keywords: tools, convenience
88
;; Version: 0.1-cvs
9-
;; Package-Requires: ((emacs "24.1") (flycheck "0.20") (dash "2.4.0"))
9+
;; Package-Requires: ((emacs "24.1") (flycheck "0.20") (dash "2.4.0") (seq "2.15"))
1010

1111
;; This file is not part of GNU Emacs.
1212

@@ -44,6 +44,8 @@
4444

4545
(require 'dash)
4646
(require 'flycheck)
47+
(require 'seq)
48+
(require 'json)
4749

4850
(defun flycheck-rust-executable-p (rel-name)
4951
"Whether REL-NAME denotes an executable.
@@ -94,6 +96,30 @@ Return non-nil if PROJECT-ROOT is a binary crate, nil otherwise."
9496
(let ((root-dir (file-name-directory project-root)))
9597
(file-exists-p (expand-file-name "src/main.rs" root-dir))))
9698

99+
(defun flycheck-rust-find-target (file-name)
100+
"Find and return the cargo target associated with the given file.
101+
102+
FILE-NAME is the name of the file that is matched against the
103+
`src_path' value in the list `targets' returned by `cargo
104+
read-manifest'. If there is no match, the first target is
105+
returned by default.
106+
107+
Return a cons cell (TYPE . NAME), where TYPE is the target
108+
type (lib or bin), and NAME the target name (usually, the crate
109+
name)."
110+
(let ((json-array-type 'list))
111+
(let-alist (with-temp-buffer
112+
(call-process "cargo" nil t nil "read-manifest")
113+
(goto-char (point-min))
114+
(json-read))
115+
(let ((targets .targets))
116+
;; If there is a target that matches the file-name exactly, pick that
117+
;; one. Otherwise, just pick the first target.
118+
(let-alist (seq-find (lambda (target)
119+
(let-alist target (string= file-name .src_path)))
120+
targets (car targets))
121+
(cons (car .kind) .name))))))
122+
97123
;;;###autoload
98124
(defun flycheck-rust-setup ()
99125
"Setup Rust in Flycheck.
@@ -103,7 +129,9 @@ Flycheck according to the Cargo project layout."
103129
(interactive)
104130
(when (buffer-file-name)
105131
(-when-let (root (flycheck-rust-project-root))
106-
(let ((rel-name (file-relative-name (buffer-file-name) root)))
132+
(pcase-let ((rel-name (file-relative-name (buffer-file-name) root))
133+
(`(,target-type . ,target-name) (flycheck-rust-find-target
134+
(buffer-file-name))))
107135
;; These are valid crate roots as by Cargo's layout
108136
(if (or (flycheck-rust-executable-p rel-name)
109137
(flycheck-rust-test-p rel-name)
@@ -117,9 +145,15 @@ Flycheck according to the Cargo project layout."
117145
;; Check tests in libraries and integration tests
118146
(setq-local flycheck-rust-check-tests
119147
(not (flycheck-rust-executable-p rel-name)))
148+
;; Set the crate type
120149
(setq-local flycheck-rust-crate-type
121-
(if (flycheck-rust-binary-crate-p root)
122-
"bin" "lib")) ;; Set the crate type
150+
(if (string= target-type "bin")
151+
(progn
152+
;; If it's binary target, we need to pass the binary
153+
;; name
154+
(setq-local flycheck-rust-binary-name target-name)
155+
"bin")
156+
"lib"))
123157
;; Find build libraries
124158
(setq-local flycheck-rust-library-path
125159
(list (expand-file-name "target/debug" root)

0 commit comments

Comments
 (0)