My workflow in Visual Studio Code + Rust Analyzer has become:
1. Make a change to Rust source code using all the analysis magic
2. Save the file to trigger `cargo watch`. I have format on save enabled
for all file types so this also runs `rustfmt`
3. Fix any diagnostics that `cargo watch` finds
Unfortunately if the Rust source has any syntax errors the act of saving
will pop up a scary "command has failed" message and will switch to the
"Output" tab to show the `rustfmt` error and exit code.
I did a quick survey of what other Language Servers do in this case.
Both the JSON and TypeScript servers will swallow the error and return
success. This is consistent with how I remember my workflow in those
languages. The syntax error will show up as a diagnostic so it should
be clear why the file isn't formatting.
I checked the `rustfmt` source code and while it does distinguish "parse
errors" from "operational errors" internally they both result in exit
status of 1. However, more catastrophic errors (missing `rustfmt`,
SIGSEGV, etc) will return 127+ error codes which we can distinguish from
a normal failure.
This changes our handler to log an info message and feign success if
`rustfmt` exits with status 1.
Another option I considered was only swallowing the error if the
formatting request came from format-on-save. However, the Language
Server Protocol doesn't seem to distinguish those cases.
1443: cache chalk queries r=flodiebold a=matklad
This gives a significant speedup, because chalk will call these
functions several times even withing a single revision. The only
significant one here is `impl_data`, but I figured it might be good to
cache others just for consistency.
The results I get are:
Before:
from scratch: 16.081457952s
no change: 15.846493ms
trivial change: 352.95592ms
comment change: 361.998408ms
const change: 457.629212ms
After:
from scratch: 14.910610278s
no change: 14.934647ms
trivial change: 85.633023ms
comment change: 96.433023ms
const change: 171.543296ms
Seems like a nice win!
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This gives a significant speedup, because chalk will call these
functions several times even withing a single revision. The only
significant one here is `impl_data`, but I figured it might be good to
cache others just for consistency.
The results I get are:
Before:
from scratch: 16.081457952s
no change: 15.846493ms
trivial change: 352.95592ms
comment change: 361.998408ms
const change: 457.629212ms
After:
from scratch: 14.910610278s
no change: 14.934647ms
trivial change: 85.633023ms
comment change: 96.433023ms
const change: 171.543296ms
Seems like a nice win!
Now, one can use `let _p = ra_prof::cpu_profiler()` to capture profile
of a block of code.
This is not an out of the box experience, as that relies on gperfools
See the docs on https://github.com/AtheMathmo/cpuprofiler for more!
1432: Make fill_match_arm work with trivial arm r=matklad a=ironyman
Addresses this issue https://github.com/rust-analyzer/rust-analyzer/issues/1399
One minor issue I noticed is that complete_postfix creates an arm like this
```
match E::X {
<|>_ => {},
}
```
but fill_match_arms creates arms like this
```
E::X => (),
```
Co-authored-by: ironyman <ironyman@users.noreply.github.com>
Co-authored-by: Changyu Li <changyl@microsoft.com>
1409: The Fall down of failures r=matklad a=mominul
😁
Replaced all the uses of `failure` crate with `std::error::Error`.
Closes#1400
Depends on rust-analyzer/teraron#1
Co-authored-by: Muhammad Mominul Huque <mominul2082@gmail.com>
Can be used like this:
```
$ cargo run --release -p ra_cli -- \
analysis-bench ../chalk/ \
--complete ../chalk/chalk-engine/src/logic.rs:94:0
loading: 225.970093ms
from scratch: 8.492373325s
no change: 445.265µs
trivial change: 95.631242ms
```
Or like this:
```
$ cargo run --release -p ra_cli -- \
analysis-bench ../chalk/ \
--highlight ../chalk/chalk-engine/src/logic.rs
loading: 209.873484ms
from scratch: 9.504916942s
no change: 7.731119ms
trivial change: 124.984039ms
```
"from scratch" includes initial analysis of the relevant bits of the
project
"no change" just asks the same question for the second time. It
measures overhead on assembling the answer outside of salsa.
"trivial change" doesn't do an actual salsa change, it just advances
the revision. This test how fast is salsa at validating things.
1408: Associated type basics & Deref support r=matklad a=flodiebold
This adds the necessary Chalk integration to handle associated types and uses it to implement support for `Deref` in the `*` operator and autoderef; so e.g. dot completions through an `Arc` work now.
It doesn't yet implement resolution of associated types in paths, though. Also, there's a big FIXME about handling variables in the solution we get from Chalk correctly.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
1406: reuse AnalysisHost in batch analysis r=matklad a=matklad
We do some custom setup in `AnalysisHost`, like setting up LRU size. I figure it's a good idea to not duplicate this work in batch analysis, *if* we want to keep batch and non-batch close.
Long-term, I see a value in keeping batch a separate, lighter weight thing. However, because now we use batch to measure performance, keeping them closer makes more sense.
I'd also like to add ability to get completions by using batch analysis, and that will require ra_ide_api as well.
@flodiebold were there some reason why we haven't started with this approach from the start?
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
1404: Fight down failures! r=matklad a=mominul
issue #1400
Now only `ra_tools` crate depends on `failure`, should I also fight those? 😁
Co-authored-by: Muhammad Mominul Huque <mominul2082@gmail.com>
1403: Add alloc -> core dependency r=matklad a=flodiebold
Also a small fix for the ra-emacs-lsp company fix.
Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
The issue was windows specific -- cancellation caused collection of
bracktraces at some point, and that was slow on windows.
The proper fix here is to make sure that we don't collect bracktraces
unnecessary (which we currently do due to failure), but, as a
temporary fix, let's just not force their collection in the first
place!
Note that we can't just remove CheckCanceled trait altogether:
sometimes it's useful to check for cancellation while the query is
running! We do this, for example, in the name resolution fixed-point
loop.
1394: Fix hover for pat that shadows items r=matklad a=sinkuu
```rust
fn x() {}
fn y() {
let x = 0i32;
x; // hover on `x` is expected to be `i32`, but the actual result was `fn x()`
}
```
This was because: if [`res.is_empty()`](656a0fa9f9/crates/ra_ide_api/src/hover.rs (L205)), it fallbacks to "index based approach" and adds `fn x()` to `res`, which makes [`res.extend(type_of)` below](656a0fa9f9/crates/ra_ide_api/src/hover.rs (L260-L266)) not happen.
Co-authored-by: Shotaro Yamada <sinkuu@sinkuu.xyz>
1374: Implement `cargo lint` and fix some clippy errors r=alanhdu a=alanhdu
This creates a `cargo lint` command that runs clippy with certain lints disabled. I've also gone ahead and fixed some of the lint errors, although there are many more still to go.
cc #848
Co-authored-by: Alan Du <alanhdu@gmail.com>
Before this commit, `Parse`s for original file ended up two times in
salsa's db: first, when we parse original file, and second, when we
parse macro or a file.
Given that parse trees are the worst ofenders in terms of memory, it
makes sense to make sure we store them only once.
1368: Store referece instead of full token tree in tokenbuffer r=matklad a=edwin0cheng
This PR try to minimize the memory allocation in converting `SyntaxNode` to `TokenTree` by using reference isnteead of full token tree in `TokenBuffer`.
Note that the final goal is replace `TokenTree` with TokenBuffer such that there is no conversion between them.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
1360: Improve goto definition for MBE r=matklad a=edwin0cheng
This PR improve the macro resolution for goto definition and expression macro invocation by using proper path resolution for external macros.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
We use panics for cancellation, so we could trigger panic while
holding the solver. std::sync::Mutex will be poisoned as a result,
which and all further attempts to use solver (from other threads) will
panic as well.
This commit switches to parking_lot::Mutex which just unlocks on panic.
This small fix should improve rust-analyzer resopnsivness for
real-time operations like onEnter handling.
Turns out, salsa's validation can take hundreds of milliseconds, and,
in case no changes were made, it won't be triggering any queries.
Because we check for cancellation in queries, that means that
validation is not cancellable!
What this PR does is injecting check_canceled checks into validation,
by using salsa's event API, which wasn't meant to be used like this,
but, hey, it works!
Here's the onEnter handling before and after this change:
https://youtu.be/7-ffPzgvH7o
1337: Move syntax errors our of syntax tree r=matklad a=matklad
I am not really sure if it's a good idea, but `SyntaxError` do not really belong to a `SyntaxTree`. So let's just store them on the side?
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>