7572: Add `find_or_create_impl_block` to assist utils r=matklad a=yoshuawuyts
This is another continuation of https://github.com/rust-analyzer/rust-analyzer/pull/7562, introducing a small util to either find an `impl` block, or create a new one if none exists. I copied this code from the `generate_new` assist into https://github.com/rust-analyzer/rust-analyzer/pull/7562, and this unifies both into a helper.
It doesn't feel super polished in its current state, but my hope is that this is enough of a starting point that it can be expanded on later. For example something that would be useful would be a flag which either returns the index of the start of the block, or the end of the block.
Anyway, I hope this is useful. Thanks!
Co-authored-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
7574: Remove various redundant clones r=kjeremy a=yoshuawuyts
I noticed when running clippy through RA that there are a few instances where `clone` is called where it's not actually needed. I figured a small patch to remove these might be welcome here.
Thanks!
Co-authored-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
7505: Widen Highlights root range to covering element r=Veykril a=Veykril
There have been a few issues about/containing spurious syntax highlighting panics, which all seem to come from the `rust_analyzer::handlers::handle_semantic_tokens_range` request, which I believe this to be the cause of as the text range we want to highlight here is currently potentially smaller than that of the covering element, so we might highlight something that is inside the covering element, but outside of the text range we wish to highlight causing the assert to fail.
Unfortunately this isn't really easy to test since I have yet to find a reproducible cause(#7504 doesn't work for me cause I can't seem to checkout the given commit).
See #7504, #7298, #7299 and #7416, all of those contain an assertion failure in syntax highlighting, but only in the range request.
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7570: Add doc gen to the `generate_enum_match_method` assist r=yoshuawuyts a=yoshuawuyts
Implements a small extension to https://github.com/rust-analyzer/rust-analyzer/pull/7562, generating default comments. I wasn't sure if this would fit the goals of Rust-Analyzer, so I chose to split it into a separate PR. This is especially useful when writing code in a codebase which uses `#![warn(missing_docs)]` lint, as many production-grade libraries do.
The comments we're generating here are similar to the ones found on [`Option::is_some`](https://doc.rust-lang.org/std/option/enum.Option.html#method.is_some) and [`Result::is_err`](https://doc.rust-lang.org/std/result/enum.Result.html#method.is_err). I briefly considered only generating these for `pub` types, but they seem small and unobtrusive enough that they're probably useful in the general case. Thanks!
## Example
__input__
```rust
pub(crate) enum Variant {
Undefined,
Minor, // cursor here
Major,
}
```
__output__
```rust
pub(crate) enum Variant {
Undefined,
Minor,
Major,
}
impl Variant {
/// Returns `true` if the variant is [`Minor`].
pub(crate) fn is_minor(&self) -> bool {
matches!(self, Self::Minor)
}
}
```
## Future Directions
This opens up the path to adding an assist for generating these comments on existing `is_` methods. This would make it both easy to document new code, and update existing code with documentation.
7571: Cleanup decl_check r=Veykril a=Veykril
bors r+
Co-authored-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7562: add `generate_enum_match` assist r=matklad a=yoshuawuyts
This adds a `generate_enum_match` assist, which generates `is_` variants for enums (e.g. `Option::{is_none,is_some}` in std). This is my first attempt at contributing to Rust-Analyzer, so I'm not sure if I've gotten everything right. Thanks!
## Example
**Input**
```rust
pub(crate) enum Variant {
Undefined,
Minor, // cursor here
Major,
}
```
**Output**
```rust
pub(crate) enum Variant {
Undefined,
Minor,
Major,
}
impl Variant {
pub(crate) fn is_minor(&self) -> bool {
matches!(self, Self::Minor)
}
}
```
## Future Directions
I made this as a stepping stone for some of the more involved refactors (e.g. #5944). I'm not sure yet how to create, use, and test `window.showQuickPick`-based asssists in RA. But once that's possible, it'd probably be nice to be able to generate match methods in bulk through the quickpick UI rather than one-by-one:
```
[x] Select enum members to generate methods for. (3 selected) [ OK ]
---------------------------------------------------------------------------
[x] Undefined
[x] Minor
[x] Major
```
Co-authored-by: Yoshua Wuyts <yoshuawuyts+github@gmail.com>
Co-authored-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
7568: Fix merging of `segment_index` in path resolution r=jonas-schievink a=jonas-schievink
This caused associated item lookup to fail when modifying `resolver.rs` to handle block expressions with inner items.
bors r+
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
7535: Extract function assist r=cpud36 a=cpud36
This PR adds `extract function/method` assist. closes#5409.
# Supported features
Assist should support extracting from expressions(`1`, `2 + 2`, `loop { }`) and from a series of statements, e.g.:
```rust
foo();
$0bar();
baz();$0
quix();
```
Assist also supports extracting parameters, like:
```rust
fn foo() -> i32 {
let n = 1;
$0n + 1$0
}
// -
fn foo() -> i32 {
let n = 1;
fun_name(n)
}
fn fun_name(n: i32) -> i32 {
n + 1
}
```
Extracting methods also generally works.
Assist allows referencing outer variables, both mutably and immutably, and handles handles access to variables local to extracted function:
```rust
fn foo() {
let mut n = 1;
let mut m = 2;
let mut moved_v = Vec::new();
let mut ref_mut_v = Vec::new();
$0
n += 1;
let k = 1;
moved_v.push(n);
let r = &mut m;
ref_mut_v.push(*r);
let h = 3;
$0
n = ref_mut_v.len() + k;
n -= h + m;
}
// -
fn foo() {
let mut n = 1;
let mut m = 2;
let mut moved_v = Vec::new();
let mut ref_mut_v = Vec::new();
let (k, h) = fun_name(&mut n, moved_v, &mut m, &mut ref_mut_v);
n = ref_mut_v.len() + k;
n -= h + m;
}
fn fun_name(n: &mut i32, mut moved_v: Vec<i32>, m: &mut i32, ref_mut_v: &mut Vec<i32>) -> (i32, i32) {
*n += 1;
let k = 1;
moved_v.push(*n);
let r = m;
ref_mut_v.push(*r);
let h = 3;
(k, h)
}
```
So we handle both input and output paramters
# Showcase
![extract_cursor_in_range_3](https://user-images.githubusercontent.com/4218373/106980190-c9870800-6770-11eb-83d9-3d36b2550ff6.gif)
![fill_match_arms_discard_wildcard](https://user-images.githubusercontent.com/4218373/106980197-cbe96200-6770-11eb-96b0-14c27894fac0.gif)
![ide_db_helpers_handle_kind](https://user-images.githubusercontent.com/4218373/106980201-cdb32580-6770-11eb-9e6e-6ac8155d65ac.gif)
![ide_db_imports_location_local_query](https://user-images.githubusercontent.com/4218373/106980205-cf7ce900-6770-11eb-8516-653c8fcca807.gif)
# Working with non-`Copy` types
Consider the following example:
```rust
fn foo() {
let v = Vec::new();
$0
let n = v.len();
$0
let is_empty = v.is_empty();
}
```
`v` must be a parameter to extracted function.
The question is, what type should it have.
It could be `v: Vec<i32>`, or `v: &Vec<i32>`.
The former is incorrect for `Vec<i32>`, but the later is silly for `i32`.
To resolve this we need to know if the type implements `Copy` trait.
I didn't find any api available from assists to query this.
`hir_ty::method_resolution::implements` seems relevant, but is isn't publicly re-exported from `hir`.
# Star(`*`) token and pointer dereference
If I understand correctly, in order to create expression like `*p`, one should use `ast::make::expr_prefix(T![*], ...)`, which
in turn calls `token(T![*])`.
`token` does not have star in `tokens::SOURCE_FILE`, so this panics.
I had to add `*` to `SOURCE_FILE` to make it work.
Correct me if this is not intended way to do this.
# Lowering access `value -> mut ref -> shared ref`
Consider the following example:
```rust
fn foo() {
let v = Vec::new();
$0 let n = v.len(); $0
}
```
`v` is not used after extracted function body, so both `v: &Vec<i32>` and `v: Vec<i32>` would work.
Currently the later would be chosen.
We can however check the body of extracted function and conclude that `v: &Vec<i32>` is sufficient.
Using `v: &Vec<i32>`(that is a minimal required access level) might be a better default.
I am unsure.
# Cleanup
The assist seems to be reasonably handling most of common cases.
If there are no concerns with code it produces(i.e. with test cases), I will start cleaning up
[edit]
added showcase
Co-authored-by: Vladyslav Katasonov <cpud47@gmail.com>
7541: Use block_def_map in body lowering (third time's the charm) r=jonas-schievink a=jonas-schievink
After https://github.com/rust-analyzer/rust-analyzer/pull/7380 and https://github.com/rust-analyzer/rust-analyzer/pull/7506 both had to be reverted, this should have finally resolved all remaining bugs.
Most importantly, the optimization to skip `block_def_map` computation when the block contains no inner items was fixed (which fortunately was simpler than expected).
I've ran `analysis-stats` on libstd locally, which works fine, and also ran this PR locally for a short while without issues.
Note that this *still* has no (or almost no) user-facing impact, because the rest of r-a still relies on some local item support hacks.
bors r+
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
there are a few currently limitations:
* no modifications of function body
* does not handle mutability and references
* no method support
* may produce incorrect results
I've noticed that there are various suggestions that rust-analyzer seems
to filter out, even if they make sense.
Here's an example of where it seems like there should be a suggestion,
but there isn't:
![https://i.imgur.com/wsjM6iz.png](https://i.imgur.com/wsjM6iz.png)
It turns out that this specific suggestion is not considered
`MachineApplicable`, which are the only suggestions that rust-analyzer
accepts. However if you read the documentation for `MachineApplicable`,
b3897e3d13/compiler/rustc_lint_defs/src/lib.rs (L27-L29)
then you realize that these are specifically only those suggestions that
rust-analyzer could even automatically apply (in some distant future,
behind some setting or so). Other suggestions that may have some
semantic impact do not use `MachineApplicable`. So all other suggestions
are still intended to be suggested to the user, just not automatically
applied without the user being consulted.
b3897e3d13/compiler/rustc_lint_defs/src/lib.rs (L22-L24)
So with that in mind, rust-analyzer should almost definitely not filter
out `MaybeIncorrect` (which honestly is named horribly, it just means
that it's a semantic change, not just a syntactical one).
Then there's `HasPlaceholders` which basically is just another semantic
one, but with placeholders. The user will have to make some adjustments,
but the suggestion still is perfectly valid. rust-analyzer could
probably detect those placeholders and put proper "tab through" markers
there for the IDE, but that's not necessary for now.
Then the last one is `Unspecified` which is so unknown that I don't even
know how to judge it, meaning that the suggestion should probably also
just be suggested to the user and then they can decide.
So with all that in mind, I'm proposing to get rid of the check for
Applicability entirely.
7465: Only hide parameter hints for path, field and methodcall expressions r=SomeoneToIgnore a=Veykril
Doing this check for other expressions makes little sense to me.
Fixes#7458
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7457: Add no-buffering file logging and wait for a debugger option. r=vsrs a=vsrs
Adds two command line flags: `--no-buffering` and `--wait-dbg`.
Not sure if someone else needs this, but personally I found both flags extremely useful trying to figure out why RA does not work with Visual Studio. Or better to say why Visual Studio does not work with RA.
Co-authored-by: vsrs <vit@conrlab.com>
7433: Support Macro v2 in mbe r=jonas-schievink a=edwin0cheng
Added `mbe::MacroDef` for Macro v2.
cc @jonas-schievink
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
7426: Create all `ModuleId`s through a `DefMap` method r=jonas-schievink a=jonas-schievink
`ModuleId` needs to be able to represent blocks, and only the
associated `DefMap` will know how to construct that `ModuleId`
bors r+
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
7399: Make `ModuleId`'s `krate` field private and audit uses r=jonas-schievink a=jonas-schievink
bors r+
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
Detail should be rendered as shtort one line, just dumping fn header
there is not useful, despite the fact that TS does this.
The fact that this is a function should be indicated by the icon, the
same goes for pub/const/async etc qualitfiers
name is already present in the lable (and arg list should be a part of
that, as in idea)
But the return type is the small genuinerlly useful bit of info we can show here
7310: Add assist: add lifetime to type r=matklad a=bnjjj
close#7200
7395: Obtain `ModuleId`'s `DefMap` through a method r=jonas-schievink a=jonas-schievink
Once `ModuleId` can represent modules inside block expressions, this will be required in order to obtain the correct `DefMap`. Otherwise existing code might use a `LocalModuleId` from the wrong `DefMap` and cause a panic.
bors r+
Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
7353: Add LifetimeParam and ConstParam to CompletionItemKind r=matklad a=Veykril
Adds `LifetimeParam` and `ConstParam` to `CompletionItemKind` and maps them both to `TypeParam` in the protocol conversion as there are no equivalents, so nothing really changes there.
`ConstParam` could be mapped to `Const` I guess but I'm split on whether that would be better?
Additions were solely inspired by (the single) test output for const params.
Also sorts the variants of `CompletionItemKind` and its to_proto match.
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7386: Handle box with allocator r=flodiebold a=tweksteen
In 1.49.0, the definition of Box was modified to support an optional
Allocator[1]. Adapt the parsing of the `box` keyword to supply the
expected number of parameters to the constructor.
[1] f288cd2e17Fixes: #6956
Co-authored-by: Thiébaud Weksteen <tweek@google.com>
In 1.49.0, the definition of Box was modified to support an optional
Allocator[1]. Adapt the parsing of the `box` keyword to supply the
expected number of parameters to the constructor.
[1] f288cd2e17
7348: Fix broken link in intra-doc r=edwin0cheng a=sasurau4
Fix#5546
The intra-doc link doesn't work fine for trait associated method.
Co-authored-by: Daiki Ihara <sasurau4@gmail.com>
7387: Refactor build script specific data r=edwin0cheng a=edwin0cheng
It refactors for separating logic for build script specific data.
bors r+
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
7375: Add support for running name resolution in block expressions r=jonas-schievink a=jonas-schievink
This adds a `block_def_map` query that runs the name resolution algorithm on a block expression, and returns a `DefMap` that stores links to the parent `DefMap` (either the containing block or the crate-level `DefMap`). Blocks with no inner items return the parent's `DefMap` as-is, to avoid creating unnecessarily long `DefMap` chains.
Path resolution is updated to recurse into the parent `DefMap` after looking up a path in the original `DefMap`.
I've added a few new tests for this, but outside of those this isn't used yet.
bors r+
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
7359: ItemTree: store a mapping from blocks to inner items r=jonas-schievink a=jonas-schievink
To do name resolution within block expressions, we need to know which inner items are located inside each block expression. This adds such a mapping to `ItemTree`, replacing the previous one, which was seemingly unused other than to access all the inner items.
This also assigns `AstId`s to block expressions, which is needed to store the mapping in salsa.
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
7341: Fix warnings when running `cargo doc --document-private-items` r=Veykril a=jyn514
These were the warnings previously:
<details>
```
warning: could not parse code block as Rust code
--> crates/stdx/src/lib.rs:137:9
|
137 | /// ∀ x in slice[..idx]: pred(x)
| _________^
138 | | /// && ∀ x in slice[idx..]: !pred(x)
| |____^
|
= note: error from rustc: unknown start of token: \u{2200}
warning: 1 warning emitted
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= note: `#[warn(broken_intra_doc_links)]` on by default
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: 2 warnings emitted
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= note: `#[warn(broken_intra_doc_links)]` on by default
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: 2 warnings emitted
```
</details>
This does *not* fix the following warning, because it is actually rust
code and rustdoc is being over eager:
```
warning: Rust code block is empty
--> crates/parser/src/grammar.rs:16:5
|
16 | //! ```
| _____^
17 | | //! // test function_with_zero_parameters
18 | | //! // fn foo() {}
19 | | //! ```
| |_______^
|
help: mark blocks that do not contain Rust code as text
|
16 | //! ```text
| ^^^^^^^
```
https://github.com/rust-lang/rust/pull/79816 should make this
configurable so the warning can be `allow`ed.
Co-authored-by: Joshua Nelson <jyn514@gmail.com>
These were the warnings previously:
```
warning: could not parse code block as Rust code
--> crates/stdx/src/lib.rs:137:9
|
137 | /// ∀ x in slice[..idx]: pred(x)
| _________^
138 | | /// && ∀ x in slice[idx..]: !pred(x)
| |____^
|
= note: error from rustc: unknown start of token: \u{2200}
warning: 1 warning emitted
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= note: `#[warn(broken_intra_doc_links)]` on by default
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: 2 warnings emitted
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= note: `#[warn(broken_intra_doc_links)]` on by default
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: unresolved link to `package`
--> crates/base_db/src/input.rs:181:15
|
181 | /// it's [package].name, can be different for other project types or even
| ^^^^^^^ no item named `package` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
warning: 2 warnings emitted
```
This does *not* fix the following warning, because it is actually rust
code and rustdoc is being over eager:
```
warning: Rust code block is empty
--> crates/parser/src/grammar.rs:16:5
|
16 | //! ```
| _____^
17 | | //! // test function_with_zero_parameters
18 | | //! // fn foo() {}
19 | | //! ```
| |_______^
|
help: mark blocks that do not contain Rust code as text
|
16 | //! ```text
| ^^^^^^^
```
https://github.com/rust-lang/rust/pull/79816 should make this
configurable so the warning can be `allow`ed.
7340: Remove obsolete RangeInfo usage in references r=Veykril a=Veykril
Didn't even realize these were only here for renaming as well!
bors r+
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7336: Rename `CrateDefMap` to `DefMap` r=matklad a=jonas-schievink
I propose handling local items by computing a `DefMap` for every block expression, using the regular (early) name resolution algorithm. The result of that will be a `DefMap` that has a reference to the parent `DefMap`, which is either the one computed for the containing block expression, or the crate's root `DefMap`. Name resolution will fall back to a name in the parent `DefMap` if it cannot be resolved in the inner block.
The `DefMap`s computed for block expressions will go through a separate query that can be garbage-collected much more aggressively, since these `DefMap`s should be cheap to compute and are never part of a crate's public API.
The first step towards that is to make `CrateDefMap` not specific to crates anymore, hence this rename (if this plans sounds reasonable).
cc https://github.com/rust-analyzer/rust-analyzer/issues/7325 and https://github.com/rust-analyzer/rust-analyzer/issues/1165
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
7339: Delete optional arg for inline attr and add doc alias attr completion r=lnicola a=bnjjj
close#7167
Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
7331: shrink_to_fit `TokenMap`'s backing storage r=jonas-schievink a=jonas-schievink
Reduces `HygieneFrameQuery`'s memory usage by like 10 MB or so
bors r+
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
7291: Wrap remaining self/super/crate in Name{Ref} r=matklad a=Veykril
That should be the remaining special casing for `self` 🎉
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
I've noticed a bunch of "main loop too long" warnings in console when
typing in Cargo.toml. Profiling showed that the culprit is `rustc
--print cfg` call.
I moved it to the background project loading phase, where it belongs.
This highlighted a problem: we generally use single `cfg`, while it
really should be per crate.
7276: Remove map module from la-arena public API r=lnicola a=arzg
It’s unlikely that more items will be added to the module, so it’s simpler for users if `ArenaMap` is re-exported and the module made private.
This doesn’t compile for the same reason that #7275 doesn’t:
> This pull request doesn’t compile because dependencies on la-arena go through crates.io, so existing dependencies on the crate are referencing an old version. As such, this PR will only compile once a new la-arena version has been published.
Co-authored-by: Aramis Razzaghipour <aramisnoah@gmail.com>
7211: Fixed expr meta var after path colons in mbe r=matklad a=edwin0cheng
Fixes#7207
Added `L_DOLLAR` in `ITEM_RECOVERY_SET` , but I don't know whether it is a good idea.
r? @matklad
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
7257: vfs documentation r=matklad a=arnaudgolfouse
This documents every item in the `vfs` crate, except for a few private, windows-specific items.
Co-authored-by: Arnaud <arnaud.golfouse@free.fr>
7110: Deduplicate macros when offering completion r=matklad a=AdnoC
Closes https://github.com/rust-analyzer/rust-analyzer/issues/7081
When iterating over the names within the `hir_def::resolver::Scope` for a module, track what macros are in the `hir_def::item_scope::ItemScope::legacy_macros` collection for the module. When iterating over names from the prelude, do not proccess the name if it had been in the `legacy_macros` collection.
This is implemented with a `FxHashSet` in the `Scope::process_names` function that is populated when iterating over `legacy_macros` and checked when iterating over the prelude.
Alternative implementation could instead query the `legacy_macros` `FxHashMap` directly when processing names in the prelude.
Also, I'd like to add a test for this, but I'm not sure where it could be added.
Co-authored-by: AdnoC <adam.r.cutler@gmail.com>
7260: Render Fn* trait objects and impl types as rust does r=matklad a=Veykril
Also fixes raw ptr impl types being rendered ambiguously with multiple predicates.
This moves out the `FamousDefs::Fixture` into its own file as well, cause I figured it is big enough to get its own file at this point + we also get highlighting this way when editing it.
Fixes#3012
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7220: same level folder rename for will_rename_files r=kjeremy a=ShuiRuTian
use tricky way to support folder rename.
Another step after #7009 and for #4471
Co-authored-by: ShuiRuTian <158983297@qq.com>
Co-authored-by: Song Gao <158983297@qq.com>
7051: Check dbg! macro in tidy_test r=matklad a=edwin0cheng
Same as `check_todo` but for dbg! macro
r? @matklad
7219: Refactor rename name checking r=matklad a=Veykril
Improves the user facing error messages a bit and prevents renaming to `_` when the name is referenced as this would change source to not compile anymore since `_` is only a pattern, not a proper identifier.
7245: Encourage gifs r=matklad a=matklad
bors r+
🤖
7246: Unfreeze cargo_metadata r=matklad a=kjeremy
It now pulls in a newer version of semver-parser.
This does add a dependency on `cargo-platform` in the interest of correctness.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
Co-authored-by: kjeremy <kjeremy@gmail.com>
7235: Postfix completions like ifl now works with references r=Veykril a=Maan2003
Closes#7230
Co-authored-by: Manmeet <manmeetmann2003@gmail.com>
Co-authored-by: Manmeet Maan <manmeetmann2003@gmail.com>
7218: Fix typos r=Veykril a=regexident
Apart from the very last commit on this PR (which fixes a public type's name) all changes are non-breaking.
Co-authored-by: Vincent Esche <regexident@gmail.com>
After we started reporting progress when running cargo check during
loading, it is possible to crash the client with two identical progress
tokens.
This points to a deeper issue: we might be running several cargo checks
concurrently, which doesn't make sense.
This commit linearizes all workspace fetches, making sure no updates are
lost.
As an additional touch, it also normalizes progress & result reporting,
to make sure they stand in sync.
6238: Split punctuation semantic highlighting up into more tags r=matklad a=Veykril
Open question would be the name of the delimiter modifiers. I chose them this was as I see them this way but from what I remember people tend to mix the names however they like. So maybe using `delimSquare`, `delimCurly`, `delimRound` would be better. That would also go well with `angle` becoming `delimAngle`?
Closes#6152
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
6980: Implement to support intra-doc link r=matklad a=sasurau4
Helps with #6168
This PR is very limited implementation to support intra-doc. It only support links indicate same file function.
I want someone to feedback me about this implementation. If the approach is good, I will continue this PR to support other symbols like enum and struct.
Co-authored-by: Daiki Ihara <sasurau4@gmail.com>
7224: Remove unnecessary allocation when checking whether to hide argument name hint r=jhpratt a=jhpratt
The case-insensitive prefix/suffix check can be performed
character-by-character. This allows the check to be done without having
to allocate a new string. As a side effect, it's also no longer
necessary to convert the entire string to lowercase, as it's done as
needed. As the only case equality we're handling is ASCII, this
operation can be further optimized by using byte equality, rather than
character equality.
cc @SomeoneToIgnore, as it's an update on my PR from yesterday.
Co-authored-by: Jacob Pratt <jacob@jhpratt.dev>
The case-insensitive prefix/suffix check can be performed
character-by-character. This allows the check to be done without having
to allocate a new string. As a side effect, it's also no longer
necessary to convert the entire string to lowercase, as it's done as
needed. As the only case equality we're handling is ASCII, this
operation can be further optimized by using byte equality, rather than
character equality.
7145: Proper handling $crate Take 2 [DO NOT MERGE] r=edwin0cheng a=edwin0cheng
Similar to previous PR (#7133) , but improved the following things :
1. Instead of storing the whole `ExpansionInfo`, we store a similar but stripped version `HygieneInfo`.
2. Instread of storing the `SyntaxNode` (because every token we are interested are IDENT), we store the `TextRange` only.
3. Because of 2, we now can put it in Salsa.
4. And most important improvement: Instead of computing the whole frames every single time, we compute it recursively through salsa: (Such that in the best scenario, we only need to compute the first layer of frame)
```rust
let def_site = db.hygiene_frame(info.def.file_id);
let call_site = db.hygiene_frame(info.arg.file_id);
HygieneFrame { expansion: Some(info), local_inner, krate, call_site, def_site }
```
The overall speed compared to previous PR is much faster (65s vs 45s) :
```
[WITH old PR]
Database loaded 644.86ms, 284mi
Crates in this dir: 36
Total modules found: 576
Total declarations: 11153
Total functions: 8715
Item Collection: 15.78s, 91562mi
Total expressions: 240721
Expressions of unknown type: 2635 (1%)
Expressions of partially unknown type: 2064 (0%)
Type mismatches: 865
Inference: 49.84s, 250747mi
Total: 65.62s, 342310mi
rust-analyzer -q analysis-stats . 66.72s user 0.57s system 99% cpu 1:07.40 total
[WITH this PR]
Database loaded 665.83ms, 284mi
Crates in this dir: 36
Total modules found: 577
Total declarations: 11188
Total functions: 8743
Item Collection: 15.28s, 84919mi
Total expressions: 241229
Expressions of unknown type: 2637 (1%)
Expressions of partially unknown type: 2064 (0%)
Type mismatches: 868
Inference: 30.15s, 135293mi
Total: 45.43s, 220213mi
rust-analyzer -q analysis-stats . 46.26s user 0.74s system 99% cpu 47.294 total
```
*HOWEVER*, it is still a perf regression (35s vs 45s):
```
[WITHOUT this PR]
Database loaded 657.42ms, 284mi
Crates in this dir: 36
Total modules found: 577
Total declarations: 11177
Total functions: 8735
Item Collection: 12.87s, 72407mi
Total expressions: 239380
Expressions of unknown type: 2643 (1%)
Expressions of partially unknown type: 2064 (0%)
Type mismatches: 868
Inference: 22.88s, 97889mi
Total: 35.74s, 170297mi
rust-analyzer -q analysis-stats . 36.71s user 0.63s system 99% cpu 37.498 total
```
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This leaks a lot of LSP details into ide layer, which we want to avoid:
c9cec381bc/docs/dev (lsp-independence)
Additionally, all what this infra does is providing a toggle for
auto-import completion, but we already have one!
7181: Document project_model::PackageData and project_model::TargetData r=arnaudgolfouse a=arnaudgolfouse
This PR adds some documentation for the `project_model` crate.
Some of the field descriptions were taken directly from their `cargo_metadata` counterpart :
- `PackageData` -> `cargo_metadata::Package`
- `TargetData` -> `cargo_metadata::Target`
Co-authored-by: Arnaud <arnaud.golfouse@free.fr>
Rather than eagerly converting JSON, we losslessly keep it as is, and
change the shape of user-submitted data at the last moment.
This also allows us to remove a bunch of wrong Defaults
7176: Attribute completion r=matklad a=FlowerBOII
Solve #7167.
I removed the optional args for the attributes ```deprecated```, ```must_use``` and ```should_panic```.
I also updated their respective tests.
Please let me know if I missed something.
Co-authored-by: FlowerBOII <42295129+FlowerBOII@users.noreply.github.com>
7140: Store trait associated items in fst r=matklad a=SomeoneToIgnore
Store imported traits' associated function/methods and constants into `ImportMap.fst` and pefrorm the imports search on them.
This is a first step towards trait autoimport during completion functionality, the way I see it, after this PR, only a few major things are left to be done:
* store all traits' assoc items into fst, not only the ones in scope, as we do now. Any code pointers on how to do this are welcome 😄
* adjust a few modules in completions crate (`dot.rs`, `qualified_path.rs` at least) to query the import map, reusing the `import_assets` logic heavily
==
With the current import and autoimport implementations, it looks like for a single query, we're either interested in either associated items lookup or in all other `fst` contents lookup, but never both simultaneously.
I would rather not split `fst` in two but add another `Query` parameter to separate those, but let me know if you have any ideas.
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
7131: Created an assist for inlining a function's body into its caller r=matklad a=Michael-F-Bryan
This introduces an `inline_function` assist which will convert code like this:
```rust
fn add(a: u32, b: u32) -> u32 { a + b }
fn main() {
let x = add<|>(1, 2);
}
```
Into something like this:
```rust
fn add(a: u32, b: u32) -> u32 { a + b }
fn main() {
let x = {
let a = 1;
let b = 2;
a + b
};
}
```
Fixes#6863.
Co-authored-by: Michael-F-Bryan <michaelfbryan@gmail.com>
7162: Introduce queries to avoid problems when performing completion for enums with many variants r=matklad a=danielframpton
This change introduces two new queries to compute:
1) attributes for all variants of an enum, and
2) attributes for all fields of a variant.
The purpose of this change is to avoid the current n^2 behavior when rendering completion for variants (which prevents completion for enums with large numbers of variants).
Co-authored-by: Daniel Frampton <Daniel.Frampton@microsoft.com>
1) the set of attributes for all variants of an enum, and
2) the set of attributes for all fields of a variant.
This avoids the current n^2 behavior when rendering completion for variants, which
prevents completion for enums with large numbers of variants.
7160: Get `hir::Function` return type r=flodiebold a=arnaudgolfouse
Hello !
As said in #7158, I noticed that `hir::Function` has no direct way of getting the return type, so this PR adds this functionality.
Co-authored-by: Arnaud <arnaud.golfouse@free.fr>
7147: ssr: Allow replacing expressions with statements r=davidlattimore a=MarijnS95
Depends on #6587
Until that is merged, the diff is https://github.com/MarijnS95/rust-analyzer/compare/stmt..replace-expr-with-stmt
---
Now that statements can be matched and replaced (#6587) some usecases require expressions to be replaced with statements as well. This happens when something that can ambiguously be an expression or statement like `if` and loop blocks appear in the last position of a block, as trailing expression. In this case a replacement pattern of the form `if foo(){$a();}==>>$a();` will only substitute `if` blocks in the list of statements but not if they (implicitly) end up in the trailing expression, where they are not wrapped by an EXPR_STMT (but the pattern and template are, as parsing only succeeds for the `stmt ==>> stmt` case).
Instead of adding two rules that match an expression - and emit duplicate matching errors - allow the template for expressions to be a statement if it fails to parse as an expression.
---
Another gross change that does not seem to break any tests currently, but perhaps a safeguard should be added to only allow this kind of replacement in blocks by "pushing" the replacement template to the statement list and clearing the trailing expression?
CC @davidlattimore
Co-authored-by: Marijn Suijten <marijn@traverseresearch.nl>
This is done by adding a `ret_type` method to `hir::Function`.
I followed `assoc_fn_params` convention by creating a new `RetType` type,
that contains the actual return type accessible via a `ty` method.
6587: SSR: Support statement matching and replacing r=davidlattimore a=MarijnS95
For #3186
Hi!
This is a smaller initial patchset that came up while working on support for statement lists (and my first time working on RA 😁). It has me stuck on trailing semicolons for which I hope to receive some feedback. Matching (and replacing) `let` bindings with a trailing semicolon works fine, but trying to omit these (to make patterns more ergonomic) turns out more complex than expected.
The "optional trailing semicolon solution" implemented in this PR is ugly because `Matcher::attempt_match_token` should only consume a trailing `;` when parsing `let` bindings to prevent other code from breaking. That at the same time has a nasty side-effect of `;` ending up in the matched code: any replacements on that should include the trailing semicolon as well even if it was not in the pattern. A better example is in the tests:
3ae1649c24/crates/ssr/src/tests.rs (L178-L184)
The end result to achieve is (I guess) allowing replacement of let bindings without trailing semicolon like `let x = $a ==>> let x = 1` (but including them on both sides is still fine), and should make replacement in a macro call (where `foo!(let a = 2;)` for a `$x:stmt` is invalid syntax) possible as well. That should allow to enable/fix these tests:
3ae1649c24/crates/ssr/src/tests.rs (L201-L214)
A possible MVP of this PR might be to drop this optional `;' handling entirely and only allow an SSR pattern/template with semicolons on either side.
Co-authored-by: Marijn Suijten <marijn@traverseresearch.nl>
Now that statements can be matched and replaced (#6587) some usecases
require expressions to be replaced with statements as well. This happens
when something that can ambiguously be an expression or statement like
`if` and loop blocks appear in the last position of a block, as trailing
expression. In this case a replacement pattern of the form `if
foo(){$a();}==>>$a();` will only substitute `if` blocks in the list of
statements but not if they (implicitly) end up in the trailing
expression, where they are not wrapped by an EXPR_STMT (but the pattern
and template are, as parsing only succeeds for the `stmt ==>> stmt`
case).
Instead of adding two rules that match an expression - and emit
duplicate matching errors - allow the template for expressions to be a
statement if it fails to parse as an expression.
7068: Add VSCode command to view the hir of a function body r=theotherphil a=theotherphil
Will fix https://github.com/rust-analyzer/rust-analyzer/issues/7061. Very rough initial version just to work out where I needed to wire everything up.
@matklad would you be happy merging a hir visualiser of some kind? If so, do you have any thoughts on what you'd like it show, and how?
I've spent very little time on this thus far, so I'm fine with throwing away the contents of this PR, but I want to avoid taking the time to make this more polished/interactive/useful only to discover that no-one else has any interest in this functionality.
![image](https://user-images.githubusercontent.com/1974256/103236081-bb58f700-493b-11eb-9d12-55ae1b870f8f.png)
Co-authored-by: Phil Ellison <phil.j.ellison@gmail.com>
7115: Migrate HasSource::source to return Option r=matklad a=nick96
I've made a start on fixing #6913 based on the provided work plan, migrating `HasSource::source` to return an `Option`. The simple cases are migrated but there are a few that I'm unsure exactly how they should be handled:
- Logging the processing of functions in `AnalysisStatsCmd::run`: In verbose mode it includes the path to the module containing the function and the syntax range. I've handled this with an if-let but would it be better to blow up here with `expect`? I'm not 100% on the code paths but if we're processing a function definition then the source should exist.
I've handled `source()` in all code paths as `None` being a valid return value but are there some cases where we should just blow up? Also, all I've done is bubble up the returned `None`s, there may be some places where we can recover and still provide something.
Co-authored-by: Nick Spain <nicholas.spain@stileeducation.com>
Co-authored-by: Nick Spain <nicholas.spain96@gmail.com>
7133: Proper handling $crate and local_inner_macros r=jonas-schievink a=edwin0cheng
This PR introduces `HygineFrames` to store the macro definition/call site hierarchy in hyginee and when resolving `local_inner_macros` and `$crate`, we use the token to look up the corresponding frame and return the correct value.
See also: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#hygiene-and-hierarchies
fixe #6890 and #6788
r? @jonas-schievink
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
7130: Add extract_assignment assist r=Jesse-Bakker a=Jesse-Bakker
Add extract-assignment assist (#7006).
Assist is for now only implemented on if/match-statements where the assigment is the last statement in every block,
as for other cases, one would have to check whether the assignment has effects on the rest of the block and
extract a temporary variable for it in the block.
Co-authored-by: Jesse Bakker <github@jessebakker.com>
The `LifetimeParam` and `Local` variants use `source()` to find their
range. Now that `source()` returns an `Option` we need to handle the
`None` case.
In #6901 some special case handling for proc-macros was introduced to
prevent panicing as they have no AST. Now the new HasSource::source
method is used that returns an option.
Generally this was a pretty trivial change, the only thing of much
interest is that `hir::MacroDef` now implements `TryToNav` not `ToNav`
as this allows us to handle `HasSource::source` now returning an option.
Added the error message to the doc for the UnresolvedProcMacro
diagnostic, explaining that either enabling the procMacro setting
or disabling this diagnostic should make the warnings go away.
7116: Fix deep syntax tree bug generated by proc-macro r=jonas-schievink a=edwin0cheng
This PR fixed a bug from `semver-parser` and `pest_derive` crates which generate a very deep syntax tree such that serde reject to de-serialize. To fix this bug, we disabled recursion limit in `serde` (by calling [`Deserializer::disable_recursion_limit`](https://docs.rs/serde_json/1.0.61/serde_json/struct.Deserializer.html#method.disable_recursion_limit))
I have a feeling that we still need some way to protect against bad proc-macro generating huge syntax node, but I have no idea right now.
r? @jonas-schievink
Fixes#7103
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
7102: Fix completion of Default struct update syntax r=Veykril a=nick96
Previously the inserted text was always `..Default::default()` which ends up as `...Default::default()`
if `.` was typed. Now checks if the current token is `.` and inserts `.Default::default()`
if it is, so `..Default::default()` is correctly completed.
I think there's probably a better way to implement this context aware completion because I've seen it in other parts of rust-analyzer as a user but I'm not sure how to do it.
Fixes#6969
Co-authored-by: Nick Spain <nicholas.spain@stileeducation.com>
7071: Pass --all-targets to "cargo check" when discovering external resources r=matklad a=WasabiFan
There is a repro case and background in the linked issue.
In short, the goal of this MR is to allow rust-analyzer to discover proc-macros which come from your tests (including, most importantly, dev-dependencies).
By default, `cargo check` implies the equivalent of `--lib --bins`, meaning it'll check your libraries and binaries -- but not tests! This means proc-macros (or, I guess, build scripts as well) weren't discovered by rust-analyzer if they came from tests.
One solution would be to manually add `--lib --bins --tests` (i.e., just augment the effective options to include tests). However, in this MR, I threw in `--all-targets`, which [according to the docs](https://doc.rust-lang.org/cargo/commands/cargo-check.html#target-selection) implies `--benches --examples` too. I have absolutely no idea what repercussions that will have on rust-analyzer for other projects, nor do I know if it's a problem that build scripts will now be discovered for tests/examples/benches. But I am not aware of a reason you _wouldn't_ want to discover these things in your examples too.
I think the main drawback of this change is that it will likely slow down the `cargo check`. At a minimum, it'll now be checking your tests _and_ their dependencies. The `cargo check` docs also say that including `--tests` as I have here may cause your lib crate to be built _twice_, once for the normal target and again for unit tests. My reading of that caveat suggests that "building twice" means it's built once for the tests _inside_ your lib, with a test profile, and again for any consumers of your lib, now using a normal release profile or similar. This doesn't seem surprising.
Very minor caveat: `--tests` will not include tests within a binary if it has `test = false` set in `Cargo.toml`. (I discovered this manually by trial-and-error, but hey, it actually says that in the docs!) This is likely not an issue, but _does_ mean that if you are -- for whatever reason -- disabling tests like that and then manually specifying `cargo test --package <...> --bin <...>` to run them, rust-analyzer will remain unaware of proc-macros in your tests.
I have confirmed this fixes the original issue in my sandbox example linked in #7034 and in my own project in which I originally discovered this. I've left it configured as my default RA language server and will report back if I notice any unexpected side-effects.
Fixes#7034
Co-authored-by: Kaelin Laundry <wasabifan@outlook.com>
In an attempt to fix#6052 and #4249 this attempts to detect
if rustfmt is a rustup proxy which isn't installed, and reports
the error message to the user for them to fix.
In theory this ought to be memoised but for now it'll do as-is.
Future work might be to ask the user if they would like us to
trigger the installation (if possible).
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Previously the inserted text was always `..Default::default()` which ends up as `...Default::default()`
if `.` was typed. Now checks if the current token is `.` and inserts `.Default::default()`
if it is, so `..Default::default()` is correctly completed.
Fixes#6969
7083: Refactor mbe parsing code r=edwin0cheng a=edwin0cheng
Inspire by #5426 , this PR refactor out the parsing code such that it only parsed on `mbe::Rule`, but not on invocations.
However, it just improve the overall performance unnoticeablely :(
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
7064: Ignore qualifiers when doing autoimport completions lookup r=lnicola a=SomeoneToIgnore
A follow-up of https://github.com/rust-analyzer/rust-analyzer/pull/6918#issuecomment-748511151 and the PR itself.
Tweaks the `import_map` query api to be more flexible with the ways to match against the import path and now fuzzy imports search in names only.
This had improved the completion speed for me locally in ~5 times for `fuzzy_completion` span time, but please recheck me here.
IMO we're fast and presice enough now, so I've added the modules back to the fuzzy search output.
Also tweaks the the expect tests to display functions explicitly, to avoid confusing "duplicate" results.
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
7075: format-postfix completion takes format instead of fmt r=lnicola a=Veykril
See https://github.com/rust-analyzer/rust-analyzer/issues/6843
this brings it back in line with the documentation
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7050: Ignore third punct when matching for 2-composite punct in mbe r=jonas-schievink a=edwin0cheng
Fixes#6692
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
7047: Add force_show_panics flag for proc-macro bridge r=jonas-schievink a=edwin0cheng
https://github.com/rust-lang/rust/pull/75082 and https://github.com/rust-lang/rust/pull/76292 added a new flag in `proc_macro::Bridge` such that the ABI was changed. These ABI changing are the reason of some weird panics which caused #6880 and maybe related to the panic mentioned in #6820.
These changes are landed on rust stable 1.48 so I think it is okay to apply it now.
fixes#6880
r @jonas-schievink
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
Assist vs UnresolvedAssist split doesn't really pull its weight. This
is especially bad if we want to include `Assist` as a field of
diagnostics, where we'd have to make the thing generic.
7030: Support labels in reference search r=matklad a=Veykril
Implements general navigation for labels, goto def, rename and gives labels their own semantic highlighting class.
Fixes#6966
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
7010: Update ungrammar for const block patterns r=matklad a=Veykril
Fixes#6848
Adds const blocks and const block patterns to the AST and parses them.
Blocked on https://github.com/rust-analyzer/ungrammar/pull/17/, will merge that PR there once this one gets the OK so I can remove the local ungrammar dependency path and fix the Cargo.lock.
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
Avoid mutation of snapshot's config -- that's spooky action at a
distance. Instead, copy it over to a local variable.
This points out a minor architecture problem, which we won't fix right
away.
Various `ide`-level config structs, like `AssistConfig`, are geared
towards one-shot use when calling a specific methods. On the other
hand, the large `Config` struct in `rust-analyzer` is a long-term
config store.
The fact that `Config` stores `AssistConfig` is accidental -- a better
design would probably be to just store `ConfigData` inside `Config`
and create various `Config`s on the fly out of it.
6960: Show enum variant on Self qualified paths r=matklad a=Veykril
Fixes first part of #6549Fixes#6550
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>