Commit 6a06f6f72 (Deduplicate reference search results, 2022-11-07) deduplicates references
within each definition.
There is an edge case when requesting references of a macro argument. Apparently, our
descend_into_macros() stanza in references.rs produces a cartesian product of
- references inside the macro times
- times references outside the macro.
Since the above deduplication only applies to the references within a single definition, we
return them all, leading to many redundant references.
Work around this by deduplicating definitions as well. Perhaps there is a better fix to not
produce this cartesian product in the first place; but I think at least for definitions the
problem would remain; a macro can contain multiple definitions of the same name, but since the
navigation target will be the unresolved location, it's the same for all of them.
We can't use unique() because we don't want to drop references that don't have a declaration
(though I dont' have an example for this case).
I discovered this working with the "bitflags" macro from the crate of the same name.
Fixes#16357
This mostly works well, and eliminates a couple of delayed bugs.
One annoying thing is that we should really also add an
`ErrorGuaranteed` to `proc_macro::bridge::LitKind::Err`. But that's
difficult because `proc_macro` doesn't have access to `ErrorGuaranteed`,
so we have to fake it.
Add completions to show only traits in trait `impl` statement
This is prerequisite PR for adding the assist mentioned in #12500
P.S: If wanted, I will add the implementation of the assist in this PR as well.
Implement `literal_from_str` for proc macro server
Closes#16233
Todos and unanswered questions:
- [x] Is this the correct approach? Can both the legacy and `rust_analyzer_span` servers depend on the `syntax` crate?
- [ ] How should we handle suffixes for string literals? It doesn't seem like `rust-analyzer` preservers suffix information after parsing.
- [x] Why are the `expect` tests failing? Specifically `test_fn_like_macro_clone_literals`
Substitute $saved_file in custom check commands
If the custom command has a $saved_file placeholder, and we know the file being saved, replace the placeholder and run a check command.
If there's a placeholder and we don't know the saved file, do nothing.
This is a simplified version of #15381, which I hope is easier to review.
feat: Introduce term search to rust-analyzer
# Introduce term search to `rust-analyzer`
_I've marked this as draft as there might be some shortcomings, please point them out so I can fix them. Otherwise I think it is kind of ready as I think I'll rather introduce extra functionality in follow up PRs._
Term search (or I guess expression search for rust) is a technique to generate code by basically making the types match.
Consider the following program
```rust
fn wrap(arg: i32) -> Option<i32> {
todo!();
}
```
From the types of values in scope and constructors of `Option`, we can produce the expected result of wrapping the argument in `Option`
Dependently typed languages such as `Idris2` and `Agda` have similar tools to help with proofs, but this can be also used in everyday development as a "auto-complete".
# Demo videos
https://github.com/rust-lang/rust-analyzer/assets/19900308/7b68a1b7-7dba-4e31-9221-6c7485e77d88https://github.com/rust-lang/rust-analyzer/assets/19900308/0fae530a-aabb-4b28-af71-e19f8d3d64b2
# What does it currently do
- It works well with locals, free functions, type constructors and non-static impl methods that take items by value.
- Works with functions/methods that take shared references, but not with unique references (very conservative).
- Can handle projections to struct fields (eg. `foo.bar.baz`) but this might me more conservative than it has to be to avoid conflicting with borrow checker
- Should create only valid programs (no type / borrow checking errors). Tested with `rust-analyzer analysis-stats /path/to/ripgrep/Cargo.toml --run-term-search --validate-term-search` (basically running `cargo check` on all of the generated programs and only error seems to be due to type inference which is more of issue of testing method.
# Performace / fitness
```txt
ripgrep (latest)
Tail Expr syntactic hits: 130/1692 (7%)
Tail Exprs found: 523/1692 (30%)
Term search avg time: 9ms
Term search: 15.64s, 97ginstr, 8mb
rust-analyzer (on this branch)
Tail Expr syntactic hits: 804/13860 (5%)
Tail Exprs found: 6757/13860 (48%)
Term search avg time: 78ms
Term search: 1088.23s, 6765ginstr, 98mb
```
Highly generic code seems to blow up the search space so currently the amount of generics allowed is functions/methods is limited down to 0 (1 didn't give much improvement and 2 is already like 0.5+s search time)
# Plans for the future (not in this PR)
- ``~~Add impl methods that do not take `self` type (should be quite straight forward)~~ Done
- Be smarter (aka less restrictive) about borrow checking - this seems quite hard but since the current approach is rather naive I think some easy improvement is available.
- ``~~See if it works as a autocomplete while typing~~ Done
_Feel free to ask questions / point of shortcoming either here or on Zulip, I'll be happy to address them. I'm doing this as part of my MSc thesis so I'll be working on it till summer anyway 😄_
If the custom command has a $saved_file placeholder, and we know the
file being saved, replace the placeholder and then run a check command.
If there's a placeholder and we don't know the saved file, do nothing.
feat: ignored and disabled macro expansion
Supersedes #15117, I was having some conflicts after a rebase and since I didn't remember much of it I started clean instead.
The end result is pretty much the same as the linked PR, but instead of proc macro lookups, I marked the expanders that explicitly cannot be expanded and we shouldn't even attempt to do so.
## Unresolved questions
- [ ] I introduced a `DISABLED_ID` next to `DUMMY_ID` in `hir-expand`'s `ProcMacroExpander`, that is effectively exactly the same thing with slightly different semantics, dummy macros are not (yet) expanded probably due to errors, while not expanding disabled macros is part of the usual flow. I'm not sure if it's the right way to handle this, I also thought of just adding a flag instead of replacing the macro ID, so that the disabled macro can still be expanded for any reason if needed.
internal: tool discovery prefers sysroot tools
Fixes https://github.com/rust-lang/rust-analyzer/issues/15927, Fixes https://github.com/rust-lang/rust-analyzer/issues/16523
After this PR we will look for `cargo` and `rustc` in the sysroot if it was succesfully loaded instead of using the current lookup scheme. This should be more correct than the current approach as that relies on the working directory of the server binary or loade workspace, meaning it can behave a bit odd wrt overrides.
Additionally, rust-project.json projects now get the target data layout set so there should be better const eval support now.
Abstract more over ItemTreeLoc-like structs
Allows reducing some code duplication by using functions generic over said structs. The diff isn't negative due to me adding some additional impls for completeness.
Enable some minor lints that we should tackles
This enables these lint rules that are commented as we should tackle at some points.
- non_canonical_clone_impl
- non_canonical_partial_ord_impl
- self_named_constructors
feature: Create `UnindexedProject` notification to be sent to the client
(Note that this branch contains commits from https://github.com/rust-lang/rust-analyzer/pull/15830, which I'll rebase atop of as needed.)
Based on the discussion in https://github.com/rust-lang/rust-analyzer/issues/15837, I've added a notification and off-by-default toggle to send that notification from `handle_did_open_text_document`. I'm happy to rename/tweak this as needed.
I've been using this for a little bit, and it does seem to cause a little bit more indexing/work in rust-analyzer, but it's something that I'll profile as needed, I think.
feat: Add incorrect case diagnostics for traits and their associated items
Updates incorrect case diagnostic to:
- Check traits and their associated items
- Ignore trait implementations except for patterns in associated function bodies
Also cleans up `hir-ty::diagnostics::decl_check` a bit (mostly to make it a bit more DRY and easier to maintain)
Also fixes: #8675 and fixes: #8225
fix: Recover from missing argument in call expressions
Previously, when parsing an argument list with a missing argument (e.g., `(a, , b)` in `foo(a, , b)`), the parser would stop upon an unexpected token (at the second comma in the example), resulting in an incorrect parse tree.
This commit improves error handling in such cases, ensuring a more accurate parse tree is built.
---
Fixes https://github.com/rust-lang/rust-analyzer/issues/15683.
Previously, when parsing an argument list with a missing argument (e.g.,
`(a, , b)` in `foo(a, , b)`), the parser would stop upon an unexpected
token (at the second comma in the example), resulting in an incorrect
parse tree.
This commit improves error handling in such cases, ensuring a more
accurate parse tree is built.
internal: Update rustc_pattern_analysis dependency
Just bumping the dependency, as I've been making API changes over on the rustc side. More API changes incoming in the coming weeks.
One benefit of this: we no longer abort in the `DeconstructedPat: Debug` impl, which means we can use `tracing` to investigate issues.
Swap Subtree::token_trees from Vec to boxed slice
Performs one of the optimizations suggested in #16325, but a little bit more. Boxed slices guarantee `shrink_to_fit` aswell as saving a pointer width as no capacity has to be stored.
Most of the diff is:
- Changing `vec![]` to `Box::new([])`
- Changing initialize -> fill into fill -> into_boxed_slice
- Working around the lack of an owned iterator or automatic iteration over a `Box<[T]>`
I would like to use my own crate, [small-fixed-array](https://lib.rs/small-fixed-array), although I understand if it isn't mature enough for this. If I'm given the go ahead, I can rework this PR to use it instead.
internal: even more `tracing`
As part of profiling completions, I added some additional spans and moved `TyBuilder::subst_for_def` closer to its usage site (the latter had a small impact on completion performance. Thanks for the tip, Lukas!)
internal: `tracing` improvements and followups
Hi folks! Building on https://github.com/rust-lang/rust-analyzer/pull/16394, I've got a few small tweaks:
- Removed the accidental `mod.rs` usage that I introduced.
- Removed a panic in `pat_analysis.rs`.
- Recorded the event kind in `handle_event` to better distinguish what _kind_ of event is being handled.
- Did a small refactor of `hprof` to have somewhat more linear control flow, and more importantly, write the recorded fields to the output.
The end result is the following:
<img width="1530" alt="A screenshot of Visual Studio Code on a Mac. `hprof.rs` is open, with " src="https://github.com/rust-lang/rust-analyzer/assets/2067774/bd11dde5-b2da-4774-bc38-bcb4772d1192">
This commit also adds `tracing` to NotificationDispatcher/RequestDispatcher,
bumps `rust-analyzer-salsa` to 0.17.0-pre.6, `always-assert` to 0.2, and
removes the homegrown `hprof` implementation in favor of a vendored
tracing-span-tree.
feat: "Normalize import" assist and utilities for normalizing use trees
- Add import/use tree normalization utilities
- Add "normalize import" assist
- Update "merge imports" assist to always apply to the covering use item except for nested use tree selections
- Update "merge imports" assist to avoid adding unnecessary braces when merging nested use tree selections
See [this discussion](https://github.com/rust-lang/rust-analyzer/pull/16372#discussion_r1457244321) for the motivation for the new "normalize import" assist and changes to the "merge imports" assist.
feat: Support for GOTO def from *inside* files included with include! macro
close#14937
Try to implement goto def from *inside* files included with include! macro.
This implementation has two limitations:
1. Only **one** file which calls include! will be tracked. (I think multiple file be included is a rare case and we may let it go for now)
2. Mapping token from included file to macro call file (semantics.rs:646~658) works fine but I am not sure is this the correct way to implement.