Skip to content

Commit

Permalink
Fix rust-cargo with Rust 1.26+
Browse files Browse the repository at this point in the history
Due to a recent change to cargo [1], in a workspace setting (multiple
crates) filenames are now relative to the workspace root, whereas
previously they were relative to the crate.

This commit uses `cargo metadata` to figure out the workspace root, if
it exists.  If it doesn't, it fallbacks on the manifest directory.

[1]: rust-lang/cargo#4788
  • Loading branch information
kngwyu authored and aeggenberger committed Mar 14, 2018
1 parent 4f681b0 commit 77e9254
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 10 deletions.
26 changes: 25 additions & 1 deletion flycheck.el
Original file line number Diff line number Diff line change
Expand Up @@ -9528,6 +9528,22 @@ or if the current buffer has no file name."
(and buffer-file-name
(locate-dominating-file buffer-file-name "Cargo.toml")))

(defun flycheck-rust-cargo-metadata ()
"Run 'cargo metadata' and return the result as parsed JSON object."
(with-temp-buffer
(call-process "cargo" nil t nil
"metadata" "--no-deps" "--format-version" "1")
(goto-char (point-min))
(json-read)))

(defun flycheck-rust-cargo-workspace-root ()
"Return the path to the workspace root of a Rust Cargo project.

Return nil if the workspace root does not exist (for Rust
versions inferior to 1.25)."
(let-alist (flycheck-rust-cargo-metadata)
.workspace_root))

(defun flycheck-rust-cargo-has-command-p (command)
"Whether Cargo has COMMAND in its list of commands.

Expand Down Expand Up @@ -9563,7 +9579,15 @@ This syntax checker requires Rust 1.17 or newer. See URL
(eval flycheck-cargo-check-args)
"--message-format=json")
:error-parser flycheck-parse-cargo-rustc
:error-filter flycheck-rust-error-filter
:error-filter (lambda (errors)
;; In Rust 1.25+, filenames are relative to the workspace
;; root.
(let ((root (flycheck-rust-cargo-workspace-root)))
(seq-do (lambda (err)
(setf (flycheck-error-filename err)
(expand-file-name
(flycheck-error-filename err) root)))
(flycheck-rust-error-filter errors))))
:error-explainer flycheck-rust-error-explainer
:modes rust-mode
:predicate flycheck-buffer-saved-p
Expand Down
25 changes: 16 additions & 9 deletions test/flycheck-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -4000,7 +4000,6 @@ The manifest path is relative to
'(3 1 warning "function is never used: `main`" :checker rust-cargo :id "dead_code")
'(3 1 info "#[warn(dead_code)] on by default" :checker rust-cargo :id "dead_code")
'(4 9 warning "unused variable: `x`" :checker rust-cargo :id "unused_variables")
'(4 9 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(4 9 info "to avoid this warning, consider using `_x` instead" :checker rust-cargo :id "unused_variables"))))

(flycheck-ert-def-checker-test rust-cargo rust default-target
Expand All @@ -4013,7 +4012,6 @@ The manifest path is relative to
'(3 1 warning "function is never used: `main`" :checker rust-cargo :id "dead_code")
'(3 1 info "#[warn(dead_code)] on by default" :checker rust-cargo :id "dead_code")
'(4 9 warning "unused variable: `x`" :checker rust-cargo :id "unused_variables")
'(4 9 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(4 9 info "to avoid this warning, consider using `_x` instead" :checker rust-cargo :id "unused_variables"))))

(flycheck-ert-def-checker-test rust-cargo rust lib-main
Expand All @@ -4030,9 +4028,7 @@ The manifest path is relative to
(flycheck-ert-should-syntax-check
"language/rust/cargo-targets/src/lib.rs" 'rust-mode
'(3 1 warning "function is never used: `foo_lib`" :checker rust-cargo :id "dead_code")
'(3 1 info "#[warn(dead_code)] on by default" :checker rust-cargo :id "dead_code")
'(6 17 warning "unused variable: `foo_lib_test`" :checker rust-cargo :id "unused_variables")
'(6 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(6 17 info "to avoid this warning, consider using `_foo_lib_test` instead" :checker rust-cargo :id "unused_variables")))

(let ((flycheck-rust-crate-type "lib"))
Expand All @@ -4054,7 +4050,6 @@ The manifest path is relative to
'(1 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(1 17 info "to avoid this warning, consider using `_foo_main` instead" :checker rust-cargo :id "unused_variables")
'(4 17 warning "unused variable: `foo_main_test`" :checker rust-cargo :id "unused_variables")
'(4 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(4 17 info "to avoid this warning, consider using `_foo_main_test` instead" :checker rust-cargo :id "unused_variables")))

(let ((flycheck-rust-crate-type "bin")
Expand All @@ -4066,7 +4061,6 @@ The manifest path is relative to
'(1 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(1 17 info "to avoid this warning, consider using `_foo_bin_a` instead" :checker rust-cargo :id "unused_variables")
'(4 17 warning "unused variable: `foo_bin_a_test`" :checker rust-cargo :id "unused_variables")
'(4 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(4 17 info "to avoid this warning, consider using `_foo_bin_a_test` instead" :checker rust-cargo :id "unused_variables")))

(let ((flycheck-rust-crate-type "bench")
Expand All @@ -4078,7 +4072,6 @@ The manifest path is relative to
'(1 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(1 17 info "to avoid this warning, consider using `_foo_bench_a` instead" :checker rust-cargo :id "unused_variables")
'(4 17 warning "unused variable: `foo_bench_a_test`" :checker rust-cargo :id "unused_variables")
'(4 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(4 17 info "to avoid this warning, consider using `_foo_bench_a_test` instead" :checker rust-cargo :id "unused_variables")))

(let ((flycheck-rust-crate-type "test")
Expand All @@ -4101,9 +4094,19 @@ The manifest path is relative to
'(1 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(1 17 info "to avoid this warning, consider using `_foo_ex_a` instead" :checker rust-cargo :id "unused_variables")
'(4 17 warning "unused variable: `foo_ex_a_test`" :checker rust-cargo :id "unused_variables")
'(4 17 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(4 17 info "to avoid this warning, consider using `_foo_ex_a_test` instead" :checker rust-cargo :id "unused_variables")))))

(flycheck-ert-def-checker-test rust-cargo rust workspace-subcrate
(let ((flycheck-disabled-checkers '(rust)))
(let ((flycheck-rust-crate-type "lib")
(flycheck-rust-check-tests t))
(flycheck-ert-cargo-clean "language/rust/workspace/crate1/Cargo.toml")
(flycheck-ert-should-syntax-check
"language/rust/workspace/crate1/src/lib.rs" 'rust-mode
'(2 7 warning "unused variable: `a`" :checker rust-cargo :id "unused_variables")
'(2 7 info "#[warn(unused_variables)] on by default" :checker rust-cargo :id "unused_variables")
'(2 7 info "to avoid this warning, consider using `_a` instead" :checker rust-cargo :id "unused_variables")))))

(flycheck-ert-def-checker-test rust-cargo rust dev-dependencies
(let ((flycheck-disabled-checkers '(rust)))
(let ((flycheck-rust-crate-type "lib")
Expand Down Expand Up @@ -4149,7 +4152,11 @@ The manifest path is relative to
(let ((flycheck-disabled-checkers '(rust-cargo)))
(flycheck-ert-should-syntax-check
"language/rust/flycheck-test/src/importing.rs" 'rust-mode
'(1 5 error "unresolved import `super` (There are too many initial `super`s.)" :checker rust :id "E0432"))))
'(1 5 error "failed to resolve. There are too many initial `super`s. (There are too many initial `super`s.)" :checker rust :id "E0433")
'(1 5 warning "unused import: `super::imported`" :checker rust :id "unused_imports")
'(1 5 info "#[warn(unused_imports)] on by default" :checker rust :id "unused_imports")
'(4 24 error "failed to resolve. Use of undeclared type or module `imported` (Use of undeclared type or module `imported`)" :checker rust :id "E0433")
)))

(flycheck-ert-def-checker-test rust rust macro-error
(let ((flycheck-disabled-checkers '(rust-cargo)))
Expand Down
4 changes: 4 additions & 0 deletions test/resources/language/rust/workspace/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions test/resources/language/rust/workspace/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["crate1"]
3 changes: 3 additions & 0 deletions test/resources/language/rust/workspace/crate1/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[package]
name = "crate1"
version = "0.1.0"
3 changes: 3 additions & 0 deletions test/resources/language/rust/workspace/crate1/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
let a = 0;
}

0 comments on commit 77e9254

Please sign in to comment.