-
-
Notifications
You must be signed in to change notification settings - Fork 19
Extract build settings and project layout from Cargo itself #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
For #7, I have a tentative fix that covers sub-crates like docopt_macros and works with the It's not what I'd call "good", but it's definitely better than it was. |
@ane As I said, feel free to open a pull request. It's just that I won't spend any of my time on this anymore until Cargo gets an interface to export its project settings. |
Yeah. Well, that should be hopefully soon, as @winger seems to be working on it. |
Now that |
Well, that was shockingly straightforward. I defined a new flycheck syntax checker and it seems to just work: (flycheck-define-checker cargo-rust
"A Rust syntax checker using cargo rustc.
This syntax checker needs Rust 1.1 or newer.
See URL `http://www.rust-lang.org'."
:command ("cargo" "rustc" "--" "-Z" "no-trans") ;; <---- the big change
:error-patterns
((error line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " error: "
(or
;; Multiline errors
(and (message (minimal-match (one-or-more anything)))
" [" (id "E" (one-or-more digit)) "]")
(message))
line-end)
(warning line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " warning: "
(message) line-end)
(info line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " " (or "note" "help") ": "
(message) line-end))
:modes rust-mode
:predicate (lambda ()
(flycheck-buffer-saved-p))) ;; <--- another important change I think this design only supports the "check on save" model of syntax checking, which is unfortunate, but I think a reasonable tradeoff given that everything else works perfectly, as far as I can tell, with no painful extraction and guessing at library paths and crate roots and the like. I'm unsure if it makes sense to have a separate checker for
|
From
So there's another thing that needs to be configurable, for some projects. |
@tomjakubowski is correct, we just need to call |
@tomjakubowski I'm new to flycheck and emacs in general, do you mean that your change to support |
That's right. Flycheck does on-the-fly checks by periodically saving the buffer to a temporary file (named something like The current Rust checker can check a crate's root file on-the-fly because the name of that file doesn't actually matter, so long as it's passed to Since |
Thanks @tomjakubowski I appreciate the explanation. |
It looks like if you pass the requisite This is probably not a great way to do this, but this works for me™. (defun flycheck-rust-extern-args (lib-paths)
(cond
((null lib-paths) nil)
(t (append (flycheck-rust-extern-arg (car lib-paths))
(flycheck-rust-extern-args (cdr lib-paths))))))
(defun flycheck-rust-extern-arg (lib)
(let ((file (file-name-nondirectory lib)))
(string-match "\\`lib\\([a-z0-9_]+\\)-[a-z0-9]+\.rlib\\'" file)
(list "--extern" (concat (match-string 1 file) "=" lib))))
(defun flycheck-rust-setup ()
"Setup Rust in Flycheck.
If the current file is part of a Cargo project, configure
Flycheck according to the Cargo project layout."
(interactive)
(when (buffer-file-name)
(-when-let (root (flycheck-rust-project-root))
(let ((rel-name (file-relative-name (buffer-file-name) root)))
;; These are valid crate roots as by Cargo's layout
(unless (or (flycheck-rust-executable-p rel-name)
(flycheck-rust-test-p rel-name)
(flycheck-rust-bench-p rel-name)
(flycheck-rust-example-p rel-name)
(string= "src/lib.rs" rel-name))
;; For other files, the library is either the default library or the
;; executable
(setq-local flycheck-rust-crate-root (flycheck-rust-find-crate-root)))
;; Check tests in libraries and integration tests
(setq-local flycheck-rust-check-tests
(not (flycheck-rust-executable-p rel-name)))
;; Set the crate type
(setq-local flycheck-rust-crate-type
(if (flycheck-rust-executable-p rel-name) "bin" "lib"))
;; Find build libraries
(setq-local flycheck-rust-library-path
(list (expand-file-name "target/debug" root)
(expand-file-name "target/debug/deps" root)))
;; specify extern crates
(setq-local flycheck-rust-args
(flycheck-rust-extern-args
(directory-files (expand-file-name "target/debug/deps" root) t "\.rlib\\'"))))))) |
@lunaryorn would you accept a pull request to replace the checker in this package with one that uses |
@tomjakubowski I'll definitely merge any pull request that resolves the current issues, in whatever way. But I do not want to replace this package with something that has edge cases on its own and just breaks in other situations. However, I'm not sufficiently familiar with Cargo and Rust to decide, so it's really your judgement call. If you think that checker would sufficiently improve the current situation please go ahead. But please understand that I naturally reserve the right to revert your changes should they turn out to cause issues for other users. Besides, if it's only a simple checker, please make a pull request against Flycheck itself! There's no need to have it in an extension package. At best we could obsolete and eventually delete this package. Please keep the simple rust checker, though, in case someone doesn't use Cargo. |
Cargo itself is these days such an integral part of Rust that it is very unlikely one would use Rust without it. The default Rust installer now installs it. As I understand this PR would improve the Rust default checker (just the compiler) to work a bit better, e.g., to understand different crate layouts to which the compiler itself is oblivious. The package manager - Cargo - understands these constraints and would therefore be a better checker in every way. Of course, a better goal would just to integrate the Rust checker via Cargo into Flycheck, instead of having a separate checker, as you mentioned. |
Yeah cargo has definitely become very integral to rust, unlike other languages or ecosystems. I personally believe that the cargo checker should be the default for this reason, and yes keeping this checker wouldn't hurt anyone and would definitely help out those (very) rare situations where someone isn't using cargo, but it should be opt-in. Hope you do submit a PR, @tomjakubowski :) |
@tomjakubowski Any news on this? |
FWIW I've been using this modified version of the default Rust Flycheck checker for a few hours now and it seems to be working fine. I'm not sending a PR because it doesn't handle bin files right now. (flycheck-define-checker rust-cargo
"A cargo rustc checker."
:command ("cargo" "rustc" "--lib" "--" "-Z" "no-trans")
:error-patterns
((error line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " error: "
(or
;; Multiline errors
(and (message (minimal-match (one-or-more anything)))
" [" (id "E" (one-or-more digit)) "]")
(message))
line-end)
(warning line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " warning: "
(message) line-end)
(info line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " " (or "note" "help") ": "
(message) line-end))
:modes rust-mode
:predicate (lambda ()
(or (not flycheck-rust-crate-root) (flycheck-buffer-saved-p)))) |
@utkarshkukreti I modified your version with a hack and now it seems to handle binaries and libraries. Multiple binaries are not handled, though (flycheck-define-checker rust-cargo
"A cargo rustc checker."
:command ("cargo" "rustc"
(eval (if (string= flycheck-rust-crate-type "lib") "--lib" nil))
"--" "-Z" "no-trans")
:error-patterns
((error line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " error: "
(or
;; Multiline errors
(and (message (minimal-match (one-or-more anything)))
" [" (id "E" (one-or-more digit)) "]")
(message))
line-end)
(warning line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " warning: "
(message) line-end)
(info line-start (file-name) ":" line ":" column ": "
(one-or-more digit) ":" (one-or-more digit) " " (or "note" "help") ": "
(message) line-end))
:modes rust-mode
:predicate (lambda ()
(or (not flycheck-rust-crate-root) (flycheck-buffer-saved-p)))) |
@utkarshkukreti @mkpankov I'll definitely merge a PR that adds such a syntax checker to Flycheck 😎 👍 🎆 |
@lunaryorn do you want it to be an addition, rather than replacement of the current checker? I could prepare a PR... |
@mkpankov I'd prefer an additional syntax checker that's before the default I think there are still many situations in which one would write Rust outside of a Cargo project—for instance, all those that write their sample code for StackOverflow answers 😉 |
@lunaryorn will take a look at it. That should be a PR against the main |
@mkpankov Yes, a PR for main repo, please. The syntax checker will have no dependencies, so there's no reason to keep it out of Flycheck. |
@lunaryorn I'm not sure it'll have no dependencies. At the very least Or were you talking about something else? |
@mkpankov Flycheck itself defines these variables. flycheck-rust just sets them, but you don't need flycheck-rust for that: You could also set them yourself, i.e. via directory variables. |
It would appear that cargo now provides a metadata command which we could probably make use of. |
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.
Now that we solely use |
Don't guess, use Cargo's own settings. Blocked by rust-lang/cargo#1434
Specifically: Extract the layout, the crate roots, the dependencies, and probably compiler flags as well. Will probably require changes to Flycheck's rust checker, to pass additional flags.
Fixes: #5, #7, probably #11
The text was updated successfully, but these errors were encountered: