This patch makes RA understand `#![recursion_limit = "N"]` annotations.
- `crate_limits` query is moved to `DefDatabase`
- `DefMap` now has `recursion_limit: Option<u32>` field
11145: feat: add config to use reasonable default expression instead of todo! when filling missing fields r=Veykril a=bnjjj
Use `Default::default()` in struct fields when we ask to fill it instead of putting `todo!()` for every fields
before:
```rust
pub enum Other {
One,
Two,
}
pub struct Test {
text: String,
num: usize,
other: Other,
}
fn t_test() {
let test = Test {<|>};
}
```
after:
```rust
pub enum Other {
One,
Two,
}
pub struct Test {
text: String,
num: usize,
other: Other,
}
fn t_test() {
let test = Test {
text: String::new(),
num: 0,
other: todo!(),
};
}
```
Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
Co-authored-by: Coenen Benjamin <benjamin.coenen@hotmail.com>
10877: feat: make hightlighting linear r=matklad a=matklad
In https://youtu.be/qvIZZf5dmTE, we've noticed that AstIdMap does a
linear lookup when going from SyntaxNode to Id. This leads to
accidentally quadratic overall performance. Replace linear lookup with a
O(1) hashmap lookup.
Future work: don't duplicate `SyntaxNodePtr` in `AstIdMap` and switch to
"call site dependency injection" style storage (eg, store a
`HashSet<ErasedFileAstId>`).
See the explanation of the work here on YouTube :-)
As you can see from then benchmark results, this doesn't actually make analysis stats fastre. I am a bit mystified as to why this is happening to be honest.
Baseline
```
Database loaded: 598.40ms, 304minstr, 118mb (metadata 390.57ms, 21minstr, 841kb; build 111.31ms, 8764kinstr, -214kb)
crates: 39, mods: 824, decls: 18647, fns: 13910
Item Collection: 9.70s, 75ginstr, 377mb
exprs: 382426, ??ty: 387 (0%), ?ty: 285 (0%), !ty: 145
Inference: 43.16s, 342ginstr, 641mb
Total: 52.86s, 417ginstr, 1018mb
```
This PR:
```
Database loaded: 626.34ms, 304minstr, 118mb (metadata 416.26ms, 21minstr, 841kb; build 113.67ms, 8750kinstr, -209kb)
crates: 39, mods: 824, decls: 18647, fns: 13910
Item Collection: 10.16s, 75ginstr, 389mb
exprs: 382426, ??ty: 387 (0%), ?ty: 285 (0%), !ty: 145
Inference: 44.51s, 342ginstr, 644mb
Total: 54.67s, 417ginstr, 1034mb
```
I think we probably should merge the first commit here, but not the second.
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
In https://youtu.be/qvIZZf5dmTE, we've noticed that AstIdMap does a
linear lookup when going from SyntaxNode to Id. This leads to
accidentally quadratic overall performance. Replace linear lookup with a
O(1) hashmap lookup.
Future work: don't duplicate `SyntaxNodePtr` in `AstIdMap` and switch to
"call site dependency injection" style storage (eg, store a
`HashSet<ErasedFileAstId>`).
See the explanation of the work here on YouTube
https://youtu.be/wvEgymUm7cY :-)
10704: internal: Short-circuit `descend_into_macros_single` r=Veykril a=Veykril
There is no need to descend everything if all we are interested in is the first mapping.
This bring `descend_into_macros` timing in highlighting in `rust-analyzer/src/config.rs` from `154ms - descend_into_macros (2190 calls)` to `24ms - descend_into_macros (2190 calls)` since we use the single variant there(will regress once we want to highlight multiple namespaces again though).
bors r+
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
10603: fix: Don't resolve attributes to non attribute macros r=Veykril a=Veykril
Also changes `const`s to `static`s for `Limit`s as we have interior mutability in those(though only used with a certain feature flag enabled).
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
10387: Move `IdxRange` into la-arena r=Veykril a=arzg
Currently, `IdxRange` (named `IdRange`) is located in `hir_def::item_tree`, when really it isn’t specific to `hir_def` and could become part of la-arena. The rename from `IdRange` to `IdxRange` is to maintain consistency with the naming convention used throughout la-arena (`Idx` instead of `Id`, `RawIdx` instead of `RawId`). This PR also adds a few new APIs to la-arena on top of `IdxRange` for convenience, namely:
- indexing into an `Arena` by an `IdxRange` and getting a slice of values back
- creating an `IdxRange` from an inclusive range
Currently this PR also exposes a new `Arena::next_idx` method to make constructing inclusive`IdxRange`s using `IdxRange::new` easier; however, it would in my opinion be better to remove this as it allows for easy creation of out-of-bounds `Idx`s, when `IdxRange::new_inclusive` mostly covers the same use-case while being less error-prone.
I decided to bump the la-arena version to 0.3.0 from 0.2.0 because adding a new `Index` impl for `Arena` turned out to be a breaking change: I had to add a type hint in `crates/hir_def/src/body/scope.rs` when one wasn’t necessary before, since rustc couldn’t work out the type of a closure parameter now that there are multiple `Index` impls. I’m not sure whether this is the right decision, though.
Co-authored-by: Aramis Razzaghipour <aramisnoah@gmail.com>
I don't like our macro tests -- they are brittle and don't inspire
confidence. I think the reason for that is that we try to unit-test
them, but that is at odds with reality, where macro expansion
fundamentally depends on name resolution.
Consider these expples
{ 92 }
async { 92 }
'a: { 92 }
#[a] { 92 }
Previously the tree for them were
BLOCK_EXPR
{ ... }
EFFECT_EXPR
async
BLOCK_EXPR
{ ... }
EFFECT_EXPR
'a:
BLOCK_EXPR
{ ... }
BLOCK_EXPR
#[a]
{ ... }
As you see, it gets progressively worse :) The last two items are
especially odd. The last one even violates the balanced curleys
invariant we have (#10357) The new approach is to say that the stuff in
`{}` is stmt_list, and the block is stmt_list + optional modifiers
BLOCK_EXPR
STMT_LIST
{ ... }
BLOCK_EXPR
async
STMT_LIST
{ ... }
BLOCK_EXPR
'a:
STMT_LIST
{ ... }
BLOCK_EXPR
#[a]
STMT_LIST
{ ... }
FragmentKind played two roles:
* entry point to the parser
* syntactic category of a macro call
These are different use-cases, and warrant different types. For example,
macro can't expand to visibility, but we have such fragment today.
This PR introduces `ExpandsTo` enum to separate this two use-cases.
I suspect we might further split `FragmentKind` into `$x:specifier` enum
specific to MBE, and a general parser entry point, but that's for
another PR!
9970: feat: Implement attribute input token mapping, fix attribute item token mapping r=Veykril a=Veykril
![image](https://user-images.githubusercontent.com/3757771/130328577-4c1ad72c-51b1-47c3-8d3d-3242ec44a355.png)
The token mapping for items with attributes got overwritten partially by the attributes non-item input, since attributes have two different inputs, the item and the direct input both.
This PR gives attributes a second TokenMap for its direct input. We now shift all normal input IDs by the item input maximum(we maybe wanna swap this see below) similar to what we do for macro-rules/def. For mapping down we then have to figure out whether we are inside the direct attribute input or its item input to pick the appropriate mapping which can be done with some token range comparisons.
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/9867
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>