Commit graph

346 commits

Author SHA1 Message Date
Chayim Refael Friedman
6a910f637e Add cov_marks to test #17927 2024-08-22 20:52:51 +03:00
Chayim Refael Friedman
d89bdd9b83 Speed up search for short associated functions, especially very common identifiers such as new
The search is used by IDE features such as rename and find all references.

The search is slow because we need to verify each candidate, and that requires analyzing it; the key to speeding it up is to avoid the analysis where possible.

I did that with a bunch of tricks that exploits knowledge about the language and its possibilities. The first key insight is that associated methods may only be referenced in the form `ContainerName::func_name` (parentheses are not necessary!) (Rust doesn't include a way to `use Container::func_name`, and even if it will in the future most usages are likely to stay in that form.

Searching for `::` will help only a bit, but searching for `Container` can help considerably, since it is very rare that there will be two identical instances of both a container and a method of it.

However, things are not as simple as they sound. In Rust a container can be aliased in multiple ways, and even aliased from different files/modules. If we will try to resolve the alias, we will lose any gain from the textual search (although very common method names such as `new` will still benefit, most will suffer because there are more instances of a container name than its associated item).

This is where the key trick enters the picture. The key insight is that there is still a textual property: a container namer cannot be aliased, unless its name is mentioned in the alias declaration, or a name of alias of it is mentioned in the alias declaration.

This becomes a fixpoint algorithm: we expand our list of aliases as we collect more and more (possible) aliases, until we eventually reach a fixpoint. A fixpoint is not guaranteed (and we do have guards for the rare cases where it does not happen), but it is almost so: most types have very few aliases, if at all.

We do use some semantic information while analyzing aliases. It's a balance: too much semantic analysis, and the search will become slow. But too few of it, and we will bring many incorrect aliases to our list, and risk it expands and expands and never reach a fixpoint. At the end, based on benchmarks, it seems worth to do a lot to avoid adding an alias (but not too much), while it is worth to do a lot to avoid the need to semantically analyze func_name matches (but again, not too much).

After we collected our list of aliases, we filter matches based on this list. Only if a match can be real, we do semantic analysis for it.

The results are promising: searching for all references on `new()` in `base-db` in the rust-analyzer repository, which previously took around 60 seconds, now takes as least as two seconds and a half (roughly), while searching for `Vec::new()`, almost an upper bound to how much a symbol can be used, that used to take 7-9 minutes(!) now completes in 100-120 seconds, and with less than half of non-verified results (aka. false positives).

This is the less strictly correct (but faster) of this patch; it can miss some (rare) cases (there is a test for that - `goto_ref_on_short_associated_function_complicated_type_magic_can_confuse_our_logic()`). There is another branch that have no false negatives but is slower to search (`Vec::new()` never reaches a fixpoint in aliases collection there). I believe it is possible to create a strategy that will have the best of both worlds, but it will involve significant complexity and I didn't bother, especially considering that in the vast majority of the searches the other branch will be more than enough. But all in all, I decided to bring this branch (of course if the maintainers will agree), since our search is already not 100% accurate (it misses macros), and I believe there is value in the additional perf.
2024-08-22 20:52:51 +03:00
Lukas Wirth
64064907ce Fully remove old macro descension API 2024-08-22 16:18:01 +02:00
Lukas Wirth
f979667fb5 Remove DescendPreference::SameText 2024-08-22 12:34:20 +02:00
bors
c9ee892263 Auto merge of #17905 - ChayimFriedman2:edition-dependent-raw-keyword, r=Veykril
fix: Properly account for editions in names

This PR touches a lot of parts. But the main changes are changing `hir_expand::Name` to be raw edition-dependently and only when necessary (unrelated to how the user originally wrote the identifier), and changing `is_keyword()` and `is_raw_identifier()` to be edition-aware (this was done in #17896, but the FIXMEs were fixed here).

It is possible that I missed some cases, but most IDE parts should properly escape (or not escape) identifiers now.

The rules of thumb are:

 - If we show the identifier to the user, its rawness should be determined by the edition of the edited crate. This is nice for IDE features, but really important for changes we insert to the source code.
 - For tests, I chose `Edition::CURRENT` (so we only have to (maybe) update tests when an edition becomes stable, to avoid churn).
 - For debugging tools (helper methods and logs), I used `Edition::LATEST`.

Reviewing notes:

This is a really big PR but most of it is mechanical translation. I changed `Name` displayers to require an edition, and followed the compiler errors. Most methods just propagate the edition requirement. The interesting cases are mostly in `ide-assists`, as sometimes the correct crate to fetch the edition from requires awareness (there may be two). `ide-completions` and `ide-diagnostics` were solved pretty easily by introducing an edition field to their context. `ide` contains many features, for most of them it was propagated to the top level function and there the edition was fetched based on the file.

I also fixed all FIXMEs from #17896. Some required introducing an edition parameter (usually not for many methods after the changes to `Name`), some were changed to a new method `is_any_identifier()` because they really want any possible keyword.

Fixes #17895.
Fixes #17774.
2024-08-16 13:49:32 +00:00
Chayim Refael Friedman
9d3368f2c2 Properly account for editions in names
This PR touches a lot of parts. But the main changes are changing
`hir_expand::Name` to be raw edition-dependently and only when necessary
(unrelated to how the user originally wrote the identifier),
and changing `is_keyword()` and `is_raw_identifier()` to be edition-aware
(this was done in #17896, but the FIXMEs were fixed here).

It is possible that I missed some cases, but most IDE parts should properly
escape (or not escape) identifiers now.

The rules of thumb are:

 - If we show the identifier to the user, its rawness should be determined
   by the edition of the edited crate. This is nice for IDE features,
   but really important for changes we insert to the source code.
 - For tests, I chose `Edition::CURRENT` (so we only have to (maybe) update
   tests when an edition becomes stable, to avoid churn).
 - For debugging tools (helper methods and logs), I used `Edition::LATEST`.
2024-08-16 16:46:24 +03:00
bors
28b6838a0e Auto merge of #17908 - ChayimFriedman2:usages-word-boundaries, r=Veykril
Test for word boundary in `FindUsages`

This speeds up short identifiers search significantly, while unlikely to have an effect on long identifiers (the analysis takes much longer than some character comparison).

Tested by finding all references to `eq()` (from `PartialEq`) in the rust-analyzer repo. Total time went down from 100s to 10s (a 10x reduction!).

Feel free to close this if you consider this a non-issue, as most short identifiers are local.
2024-08-16 07:20:23 +00:00
bors
fc36e0ca16 Auto merge of #17907 - ChayimFriedman2:no-once_cell, r=Veykril
internal: Replace once_cell with std's recently stabilized OnceCell/Lock and LazyCell/Lock

This doesn't get rid of the once_cell dependency, unfortunately, since we have dependencies that use it, but it's a nice to do cleanup. And when our deps will eventually get rid of once_cell we will get rid of it for free.
2024-08-16 07:05:59 +00:00
Chayim Refael Friedman
1a31fe299b Test for word boundary in FindUsages
This speeds up short identifiers search significantly, while unlikely to have an effect on long identifiers (the analysis takes much longer than some character comparison).

Tested by finding all references to `eq()` (from `PartialEq`) in the rust-analyzer repo. Total time went down from 100s to 10s (a 10x reduction!).
2024-08-16 10:02:36 +03:00
Chayim Refael Friedman
955e609867 Replace once_cell with std's recently stabilized OnceCell/Lock and LazyCell/Lock
This doesn't get rid of the once_cell dependency, unfortunately, since we have dependencies that use it, but it's a nice to do cleanup. And when our deps will eventually get rid of once_cell we will get rid of it for free.
2024-08-16 09:53:37 +03:00
Lukas Wirth
f90bdfc13d internal: Properly check the edition for edition dependent syntax kinds 2024-08-15 15:57:47 +02:00
mo8it
0b541ebbaa Use crossbeam-channel from the workspace 2024-08-09 23:48:03 +02:00
bors
ee10731c31 Auto merge of #17813 - roife:fix-issue-17803, r=Veykril
fix: tyck for non-ADT types when searching refs for `Self` kw

See e0276dc5dd (r1389848845)

For ADTs, to handle `{error}` in generic args, we should to convert them to ADT for comparisons; for others, we can directly compare the types.
2024-08-07 06:34:46 +00:00
roife
dc104b05cd fix: tyck for non-ADT types when searching refs for Self kw 2024-08-06 21:52:43 +08:00
bors
b23142209e Auto merge of #17745 - regexident:improve-crate-manifests, r=Veykril
Improve crate manifests, adding missing `[package.repository]` and `[package.description]` fields

As [discussed on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/Could.20we.20add.20repository.20url.20to.20.60ra_ap_.60.20crates.20on.20crates.2Eio.3F/near/455095161).

cc `@Veykril` `@lnicola`
2024-08-06 06:28:54 +00:00
Vincent Esche
7dec7e92ea Replace [package.repository] = "…" of published crates with [package.repository.workspace] = true 2024-08-06 00:26:42 +02:00
Vincent Esche
624f2ead7b Unify package descriptions by adding references to "rust-analyzer"
With the lack of a README on the individually published library crates and the somewhat cryptic `ra_ap_` prefix it is hard to figure out where those crates belong to, so mentioning "rust-analyzer" feels like auseful hint there.
2024-08-06 00:25:02 +02:00
Vincent Esche
0a45f6dc24 Fix spelling of "data structure" 2024-08-06 00:25:02 +02:00
Vincent Esche
6f329e6d5b Add repository URL for published crates' missing [package.repository] fields 2024-08-06 00:25:02 +02:00
Vincent Esche
b5b0f4bc5a Replace "TBD" with more helpful desciptions in published crates' [package.description] fields 2024-08-06 00:25:02 +02:00
Shoyu Vanilla
0241116462 fix: Panic in path transform with default type parameters 2024-08-06 04:24:40 +09:00
Lukas Wirth
fcb88832de Simplify FileDelegate 2024-08-05 13:03:03 +02:00
winstxnhdw
e4941c0c73 chore: update codegens 2024-07-23 22:36:46 +01:00
bors
36f58f5fff Auto merge of #17670 - Veykril:mem, r=Veykril
LRU `body_with_source_map` query

This query is being invalidated all the time anyways (we have an extra query on top of it for the body incrementality that is not source dependent), so there is little reason to keep these around all the time when only some IDE features are interested in them.
2024-07-22 14:48:05 +00:00
Lukas Wirth
bd359b32b0 LRU body_with_source_map query 2024-07-22 16:34:59 +02:00
bors
d092f7d78f Auto merge of #17542 - roife:fix-issue-17517, r=Veykril
feat: go-to-def and find-references on control-flow keywords

fix #17517.

This PR implements **go-to-definition** and **find-references** functionalities for control flow keywords, which is similar to the behaviors in the `highlight-related` module. Besides, this PR also fixes some incorrect behaviors in `highlight-related`.

## Changes

1. **Support for go-to-definition on control flow keywords**:
   This PR introduces functionality allowing users to navigate on the definition of control flow keywords (`return`, `break`, `continue`).
   Commit: 2a3244ee147f898dd828c06352645ae1713c260f..7391e7a608634709db002a4cb09229de4d12c056.

2. **Bug fixes and refactoring in highlight-related**:
   - **Handling return/break/continue within try_blocks**:
     This PR adjusted the behavior of these keywords when they occur within `try_blocks`. When encounter these keywords, the program should exit the outer function or loop which containing the `try_blocks`, rather than the `try_blocks` itself; while the `?` will cause the program to exit `try_blocks`.
     Commit: 59d697e807f0197f59814b37dca1563959da4aa1.
   - **Support highlighting keywords in macro expansion for highlight-related**:
     Commit: 88df24f01727c23a667a763ee3ee0cec22d5ad52.
   - Detailed description for the bug fixes
     + The previous implementation of `preorder_expr` incorrectly treated `try_blocks` as new contexts, thereby r-a will not continue to traverse inner `return` and `break/continue` statements. To resolve this, a new function `preorder_expr_with_ctx_checker` has been added, allowing users to specify which expressions to skip.
       * For example, when searching for the `?` in the context, r-a should skip `try_blocks` where the `?` insides just works for `try_blocks`. But when search for the `return` keyword, r-a should collect both the `return` keywords inside and outside the `try_blocks`
     + Thus, this PR added `WalkExpandedExprCtx` (builder pattern). It offers the following improvements: customizable context skipping, maintenance of loop depth (for `break`/`continue`), and handling macro expansion during traversal.

3. **Support for find-references on control flow keywords**:
   This PR enables users to find all references to control flow keywords.
   Commit: 9202a33f81218fb9c2edb5d42e6b4de85b0323a8.
2024-07-22 09:22:13 +00:00
bors
c29bac1cdf Auto merge of #17647 - joshka:jm/rename-commands, r=Veykril
Rename rust-analyzer commands

The commands `editor.action.triggerParameterHints` and
`editor.action.rename` are now renamed to
`rust-analyzer.triggerParameterHints` and `rust-analyzer.rename`

This change helps make it clear that these commands are specific to
rust-analyzer and not part of the default set of commands provided by
VSCode.

Fixes: https://github.com/rust-lang/rust-analyzer/issues/17644

Note: This seems like it will be a breaking change for any RA client that previously reacted to `editor.action.triggerParameterHints` - naive search: https://github.com/search?q=editor.action.triggerParameterHints+AND+%28NOT+is%3Afork%29+rust-analyzer&type=code
2024-07-22 08:10:03 +00:00
Lukas Wirth
0851d21d1e fix: Allow flyimport to import primitive shadowing modules 2024-07-21 13:26:19 +02:00
Josh McKinney
5b1a5a250b
Rename rust-analyzer commands
The commands `editor.action.triggerParameterHints` and
`editor.action.rename` are now renamed to
`rust-analyzer.triggerParameterHints` and `rust-analyzer.rename`

This change helps make it clear that these commands are specific to
rust-analyzer and not part of the default set of commands provided by
VSCode.

Fixes: https://github.com/rust-lang/rust-analyzer/issues/17644
2024-07-20 01:11:14 -07:00
bors
b333f85a9d Auto merge of #17639 - Veykril:salsa-perf, r=Veykril
Some more small salsa memory improvements

This does limit our lru limits to 2^16 but if you want to set them higher than that you might as well not set them at all. Also makes `LRU` opt-in per query now, allowing us to drop all the unnecessary LRU stuff for most queries
2024-07-19 18:45:16 +00:00
roife
1bca00d1bc fix: incorrect highlighting of try blocks with control flow kws 2024-07-20 01:42:51 +08:00
Lukas Wirth
6d4989b3c7 Make LRU opt-in 2024-07-19 18:38:08 +02:00
Lukas Wirth
8e3133f118 Reduce maximum LRU size to 2^16 entries, reducing memory footprint of LRU entries 2024-07-19 17:48:12 +02:00
bors
aa4768f7be Auto merge of #17622 - roife:fix-issue-17602, r=Veykril
fix: handle synonymous imports with different renaming in 'merge imports'

fix #17602
2024-07-19 15:16:02 +00:00
Lukas Wirth
ef462ca88e Update test fixtures 2024-07-18 09:09:31 +02:00
Lukas Wirth
5264f86242 Encode edition within FileId in the hir layer 2024-07-18 08:49:10 +02:00
roife
87a3ab4658 fix: handle synonymous imports in 'merge imports' 2024-07-18 05:01:58 +08:00
Lukas Wirth
7011094685 Add always disabled gen parse support 2024-07-17 10:49:12 +02:00
Lukas Wirth
2346a80ab4 Remove Name::to_smol_str 2024-07-16 12:43:58 +02:00
Lukas Wirth
df5f1777b8 More symbol usage 2024-07-16 12:05:16 +02:00
Lukas Wirth
93024ad411 Switch token trees to use Symbols 2024-07-16 10:11:59 +02:00
bors
f913901399 Auto merge of #17559 - Veykril:tokentree, r=Veykril
Encode ident rawness and literal kind separately in tt::Leaf
2024-07-15 11:25:51 +00:00
Lukas Wirth
e846c04fbe Encode ident rawness and literal kind separately in tt::Leaf 2024-07-15 12:24:40 +02:00
bors
e961b1aece Auto merge of #17587 - joshka:jm/edit-name-after-refactor, r=Veykril
Trigger VSCode to rename after extract variable assist is applied

When the user applies the "Extract Variable" assist, the cursor is
positioned at the newly inserted variable. This commit adds a command
to the assist that triggers the rename action in VSCode. This way, the
user can quickly rename the variable after applying the assist.

Fixes part of: #17579

https://github.com/user-attachments/assets/4cf38740-ab22-4b94-b0f1-eddd51c26c29

I haven't yet looked at the module or function extraction assists yet.
2024-07-15 09:53:39 +00:00
Lukas Wirth
cde0f69cae Fix stable iteration ordering for Map<Name, ...> usages 2024-07-15 11:25:46 +02:00
bors
8efe8a8528
Trigger VSCode to rename after extract variable assist is applied
When the user applies the "Extract Variable" assist, the cursor is
positioned at the newly inserted variable. This commit adds a command
to the assist that triggers the rename action in VSCode. This way, the
user can quickly rename the variable after applying the assist.

Fixes part of: #17579
2024-07-12 19:06:19 -07:00
Lukas Wirth
3fe815b0f3 Use Symbol in Name 2024-07-12 16:06:44 +02:00
Laurențiu Nicola
bd6de0cb57 Merge from rust-lang/rust 2024-07-11 20:06:05 +03:00
bors
a5b21ea0aa Auto merge of #17555 - Veykril:grammar-inline, r=Veykril
internal: Inline generated syntax methods
2024-07-07 09:21:04 +00:00
Lukas Wirth
c08d419fba HasGenericArgs syntax trait 2024-07-07 11:18:28 +02:00