bors[bot] [Fri, 5 Feb 2021 17:18:02 +0000 (17:18 +0000)]
Merge #7572
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.
bors[bot] [Fri, 5 Feb 2021 16:14:55 +0000 (16:14 +0000)]
Merge #7573
7573: Do not overwrite lock file r=kjeremy a=kjeremy
Use `npm ci` instead of `npm install`. `npm install` will overwrite
the lock file if you have a newer npm version than the one that
generated the package-lock.json
bors[bot] [Fri, 5 Feb 2021 16:04:50 +0000 (16:04 +0000)]
Merge #7574
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.
kjeremy [Fri, 5 Feb 2021 15:57:36 +0000 (10:57 -0500)]
Do not overwrite lock file
Use `npm ci` instead of `npm install`. `npm install` will overwrite
the lock file if you have a newer npm version than the one that
generated the package-lock.json
bors[bot] [Fri, 5 Feb 2021 15:31:25 +0000 (15:31 +0000)]
Merge #7505
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.
bors[bot] [Fri, 5 Feb 2021 15:17:41 +0000 (15:17 +0000)]
Merge #7570 #7571
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!
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.
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!
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
```
bors[bot] [Fri, 5 Feb 2021 02:55:56 +0000 (02:55 +0000)]
Merge #7535
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)
}
```
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.
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
bors[bot] [Thu, 4 Feb 2021 18:33:57 +0000 (18:33 +0000)]
Merge #7557
7557: Intern `TypeRef`s in the containing `ItemTree` r=jonas-schievink a=jonas-schievink
This reduces the memory used by `ItemTreeQuery` by ~20%. As it turns out, `TypeRef` is very heavy, and is used a lot in `ItemTree`:
* Many types are frequently repeated throughout the same file. This is what this PR addresses by storing identical `TypeRef`s only once per `ItemTree`.
* The vast majority of `TypeRef` consist of a plain path with only a single element. "Type anchors" like in `<Ty>::func` are used incredibly rarely, and even multi-segment paths are much rarer than single-segment paths.
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
bors[bot] [Wed, 3 Feb 2021 14:41:13 +0000 (14:41 +0000)]
Merge #7541
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