Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'docs/book/src/non_cargo_based_projects.md')
| -rw-r--r-- | docs/book/src/non_cargo_based_projects.md | 128 |
1 files changed, 106 insertions, 22 deletions
diff --git a/docs/book/src/non_cargo_based_projects.md b/docs/book/src/non_cargo_based_projects.md index e7df4a5d76..f1f10ae336 100644 --- a/docs/book/src/non_cargo_based_projects.md +++ b/docs/book/src/non_cargo_based_projects.md @@ -204,23 +204,40 @@ interface Runnable { args: string[]; /// The current working directory of the runnable. cwd: string; - /// Used to decide what code lens to offer. + /// Maps a runnable to a piece of rust-analyzer functionality. /// - /// `testOne`: This runnable will be used when the user clicks the 'Run Test' - /// CodeLens above a test. + /// - `testOne`: This runnable will be used when the user clicks the 'Run Test' + /// CodeLens above a test. + /// - `run`: This runnable will be used when the user clicks the 'Run' CodeLens + /// above a main function or triggers a run command. + /// - `flycheck`: This is run to provide check-on-save diagnostics when the user + /// saves a file. It must emit rustc JSON diagnostics that rust-analyzer can + /// parse. If this runnable is not specified, we may try to use `cargo check -p`. + /// This is only run for a single crate that the user saved a file in. The + /// {label} syntax is replaced with `BuildInfo::label`. + /// Alternatively, you may use `{saved_file}` and figure out which crate + /// to produce diagnostics for based on that. /// /// The args for testOne can contain two template strings: /// `{label}` and `{test_id}`. `{label}` will be replaced - /// with the `Build::label` and `{test_id}` will be replaced + /// with the `BuildInfo::label` and `{test_id}` will be replaced /// with the test name. - kind: 'testOne' | string; + kind: 'testOne' | 'run' | 'flycheck' | string; } ``` This format is provisional and subject to change. Specifically, the `roots` setup will be different eventually. -There are three ways to feed `rust-project.json` to rust-analyzer: +### Providing a JSON project to rust-analyzer + +There are four ways to feed `rust-project.json` to rust-analyzer: + +- Use + [`"rust-analyzer.workspace.discoverConfig": … }`](./configuration.md#workspace.discoverConfig) + to specify a workspace discovery command to generate project descriptions + on-the-fly. Please note that the command output is message-oriented and must + output JSONL [as described in the configuration docs](./configuration.md#workspace.discoverConfig). - Place `rust-project.json` file at the root of the project, and rust-analyzer will discover it. @@ -240,19 +257,86 @@ location or (for inline JSON) relative to `rootUri`. You can set the `RA_LOG` environment variable to `rust_analyzer=info` to inspect how rust-analyzer handles config and project loading. -Note that calls to `cargo check` are disabled when using -`rust-project.json` by default, so compilation errors and warnings will -no longer be sent to your LSP client. To enable these compilation errors -you will need to specify explicitly what command rust-analyzer should -run to perform the checks using the -`rust-analyzer.check.overrideCommand` configuration. As an example, the -following configuration explicitly sets `cargo check` as the `check` -command. - - { "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] } - -`check.overrideCommand` requires the command specified to output json -error messages for rust-analyzer to consume. The `--message-format=json` -flag does this for `cargo check` so whichever command you use must also -output errors in this format. See the [Configuration](#_configuration) -section for more information. +### Flycheck support + +Rust-analyzer has functionality to run an actual build of a crate when the user saves a file, to +fill in diagnostics it does not implement natively. This is known as "flycheck". + +**Flycheck is disabled when using `rust-project.json` unless explicitly configured**, so compilation +errors and warnings will no longer be sent to your LSP client by default. To enable these +compilation errors you will need to specify explicitly what command rust-analyzer should run to +perform the checks. There are two ways to do this: + +- `rust-project.json` may contain a `runnables` field. The `flycheck` runnable may be used to + configure a check command. See above for documentation. + +- Using the [`rust-analyzer.check.overrideCommand`](./configuration.md#check.overrideCommand) + configuration. This will also override anything in `rust-project.json`. As an example, the + following configuration explicitly sets `cargo check` as the `check` command. + + ```json + { "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] } + ``` + + Note also that this works with cargo projects. + +Either option requires the command specified to output JSON error messages for rust-analyzer to +consume. The `--message-format=json` flag does this for `cargo check` so whichever command you use +must also output errors in this format. + +Either option also supports two syntaxes within each argument: + +- `{label}` will be replaced with the `BuildInfo::label` of the crate + containing a saved file, if `BuildInfo` is provided. In the case of `check.overrideCommand` being + used in a Cargo project, this will be the cargo package ID, which can be used with `cargo check -p`. +- `{saved_file}` will be replaced with an absolute path to the saved file. This can be queried against a + build system to find targets that include the file. + +For example: + +```json +{ "rust-analyzer.check.overrideCommand": ["custom_crate_checker", "{label}"] } +``` + +If you do use `{label}` or `{saved_file}`, the command will not be run unless the relevant value can +be substituted. + + +#### Flycheck considerations + +##### Diagnostic output on error + +A flycheck command using a complex build orchestrator like `"bazel", "build", "{label}"`, even with +a tweak to return JSON messages, is often insufficient. Such a command will typically succeed if +there are warnings, but if there are errors, it might "fail to compile" the diagnostics and not +produce any output. You must build a package in such a way that the build succeeds even if `rustc` +exits with an error, and prints the JSON build messages in every case. + +##### Diagnostics for upstream crates + +`cargo check -p` re-prints any errors and warnings in crates higher up in the dependency graph +than the one requested. We do clear all diagnostics when flychecking, so if you manage to +replicate this behaviour, diagnostics for crates other than the one being checked will show up in +the editor. If you do not, then users may be confused that diagnostics are "stuck" or disappear +entirely when there is a build error in an upstream crate. + +##### Compiler options + +`cargo check` invokes rustc differently from `cargo build`. It turns off codegen (with `rustc +--emit=metadata`), which results in lower latency to get to diagnostics. If your build system can +configure this, it is recommended. + +If your build tool can configure rustc for incremental compiles, this is also recommended. + +##### Locking and pre-emption + +In any good build system, including Cargo, build commands sometimes block each other. Running a +flycheck will (by default) frequently block you from running other build commands. Generally this is +undesirable. Users will have to (unintuitively) press save again in the editor to cancel a +flycheck, so that some other command may proceed. + +If your build system has the ability to isolate any rust-analyzer-driven flychecks and prevent lock +contention, for example a separate build output directory and/or daemon instance, this is +recommended. Alternatively, consider using a feature if available that can set the priority of +various build invocations and automatically cancel lower-priority ones when needed. Flychecks should +be set to a lower priority than general direct build invocations. |