Skip to content

Conversation

@kngwyu
Copy link
Contributor

@kngwyu kngwyu commented Mar 7, 2018

This commit fixes #1397.
By the recent change of cargo(rust-lang/cargo#4788), flycheck can't detect error files in multi-crate project of Rust.
So I changed to use workspace_root in cargo metadata 's outputs, as working directory.
If the user's cargo is a bit old and there's no 'workspace_root', flycheck-rust-manifest-directory search a directory with Cargo.toml, as ever.

I've seen @fmdkdd's comment in rust-lang/cargo#4998, but I wrote this patch just because I need this, so please feel free to abort this PR if you don't like.

@CLAassistant
Copy link

CLAassistant commented Mar 7, 2018

CLA assistant check
All committers have signed the CLA.

@fmdkdd
Copy link
Member

fmdkdd commented Mar 7, 2018

Thanks for reminding me about this. It looks like we don't have a choice, we have to call cargo metadata after all, as the alternative rust-lang/rust#47939 has been dropped.

And thank you for writing the patch! I'll try to review it soon.

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 7, 2018

I checked this change cause

Suspicious state from syntax checker rust-cargo: Flycheck checker rust-cargo returned non-zero exit code 101, but its output contained no errors: error: no library targets found

in the project like

├── Cargo.toml
├── crate1
│   ├── Cargo.lock
│   ├── Cargo.toml
│   ├── src
│   └── target
├── crate2
│   ├── Cargo.toml
│   └── src
├── rustfmt.toml
├── target

so it needs to be fixed!
I'm sorry for poor testing.

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 7, 2018

This error occurs in a Project which has both bin and lib (and etc..) targets.
In addition, changing working-directory into workspace_root can make compile time much more longer!
Hmm, now I feel this is a bad way....

Is there any good idea to separate the directory where flycheck run command, from working directory?

@fmdkdd
Copy link
Member

fmdkdd commented Mar 7, 2018

Is there any good idea to separate the directory where flycheck run command, from working directory?

The working directory is the directory where flycheck runs the command.

But for fixing #1397, the only thing that we need to change is to expand the names relatively to the workspace root, whereas previously they were relative to the working directory. We don't want to change the working directory.

So the change should probably rather go to :error-filter or :error-parser.

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 7, 2018

@fmdkdd
Thanks for your advice.
I'll try it.

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 7, 2018

I modified to use completely new way.
My idea is very simple:
Absolute Path to workspace root + '/' + Relative Path to error file = Absolute Path to error file

This works well in my test directory, though I'm not sure there are no counter cases.

@fmdkdd
Copy link
Member

fmdkdd commented Mar 8, 2018

@kngwyu Thanks! That's closer to what the fix should be. I agree that we should expand into an absolute path, only if the workspace root is present.

But doing the expansion in flycheck-parse-rustc-diagnostic will break the plain rust checker, which uses the same parser. I think we should rather do the expansion into absolute paths in the :error-filter of rust-cargo, so we don't mess with parsing and the other checker.

I've pushed some changes in that direction on your branch. I've also fixed the tests, and added a new test for the workspace situation. It works with nightly and stable on my end.

Can you check on your end if the patch still works?

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 8, 2018

@fmdkdd Oh, I didn't consider rust checker, sorry, and thanks for your all work!

@fmdkdd
Copy link
Member

fmdkdd commented Mar 10, 2018

@kngwyu No worries, that's what reviews are for.

I've changed alist-get to let-alist as well, since alist-get is not available in Emacs 24. I think we should be good.

@cpitclaudel Can you take a look?

Copy link
Member

@cpitclaudel cpitclaudel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Thanks @kngwyu for this nice PR. I've left a few comments / questions

flycheck.el Outdated
(locate-dominating-file buffer-file-name "Cargo.toml")))

(defun flycheck-rust-cargo-metadata ()
"Exec 'cargo metadata' and return the result as parsed JSON object.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say Run rather than Exec, but that's nitpicking :)

flycheck.el Outdated
(defun flycheck-rust-cargo-metadata ()
"Exec 'cargo metadata' and return the result as parsed JSON object.

Return nil if the command failed or if a parse error occured."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to fail silently for failed calls to cargo metadata and for parse errors? (IIUC this is for backwards compatibility, but I'm afraid it'll create harder-to-debug bugs if things change unexpectedly)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's only because 'cargo' 's bug if parse error occurs, so we can allow error here, but I'm not sure.

flycheck.el Outdated
"Exec 'cargo metadata' and return the result as parsed JSON object.

Return nil if the command failed or if a parse error occured."
(let ((metadata-lines
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-when-let here would remove the need for the and below

flycheck.el Outdated
(process-lines "cargo" "metadata" "--no-deps" "--format-version" "1"))))
(and metadata-lines
(ignore-errors
(json-read-from-string (string-join metadata-lines ""))))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That call to string-join should use \n, not ``, I think (though it might not matter in this particular case?)
Besides, would it read nicer to use call-process and `json-read` instead of `process-lines` + `string-join` + `json-read-from-string`?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, we may just use flycheck-parse-json?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fmdkdd
flycheck-parse-json returns a list of parsed JSON lines, so isn't it too complex for this case, where what we want is only metadata ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be overkill, yes. Using call-process and json-read directly is fine :)

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to bind metadata here, I think ((let-alist (flycheck-rust-cargo-metadata) …))

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 11, 2018

Thanks for review.
I modified a bit, but for flycheck-rust-cargo-metadata I'm not sure how we should handle errors and parse json.

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 12, 2018

I simplified flycheck-rust-cargo-metadata and changed not to use ignore-errors in this function.
The newest option --no-deps in cargo metadata --no-deps --format-version 1 was added 2 years ago, so backwards compatibility is OK.
Thus this function never fail unless cargo doesn't exist or breaking change is done.

Copy link
Member

@fmdkdd fmdkdd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Just a small documentation change.

flycheck.el Outdated
(defun flycheck-rust-cargo-metadata ()
"Run 'cargo metadata' and return the result as parsed JSON object.

Return nil if the command failed or if a parse error occured."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this line can go now that we don't ignore errors anymore.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and it looks like the file is misformatted. Please run make format, which should take care of the issue.

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 13, 2018

Modified.
Thanks for your review!

flycheck.el Outdated
"Run 'cargo metadata' and return the result as parsed JSON object.

Return nil if the command failed or if a parse error occured."
We don't ignore any errors in this function."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to spell out that we don't do any error catching, as that is a detail of implementation. Anyone caring about implementation can see in the code that no error checking is done.

Please remove this line :)

@kngwyu
Copy link
Contributor Author

kngwyu commented Mar 13, 2018

Modified.

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
@fmdkdd fmdkdd merged commit 1e4ec2b into flycheck:master Mar 13, 2018
@fmdkdd
Copy link
Member

fmdkdd commented Mar 13, 2018

Great! Thank you very much for this patch! 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rust-cargo munges paths incorrectly for project with nested crates

4 participants