Although structs and unions have the same syntax and differ only in
the keyword, re-using the single syntax node for both of them leads to
confusion in practice, and propagates further down the hir in an
upleasent way.
Moreover, static and consts also share syntax, but we use different
nodes for them.
2388: Show missing struct fields in the error message r=matklad a=Frizi
This provides the most interesting information about the "missing structure fields" error directly to the user.
Co-authored-by: Frizi <frizi09@gmail.com>
2362: Expand compile_error! r=edwin0cheng a=kjeremy
Does not validate that the input is a string literal. I thought that I could `match_ast!` against the `macro_args` but that did not work. Even if it had I am not sure which error would be appropriate.
Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
2392: Fix panic during the expansion of `column!` r=edwin0cheng a=marcogroppo
Fixes#2379. Well, this isn't the "proper" fix but it doesn't hurt, IMHO.
The problem is that `to_col_number`, called by `column_expand`, receives a position number that isn't included in the text range of the file. My (very limited) understanding is that the text is the one of the original file, while `pos` is relative to something else, probably the text of the macro. Notice that in this case the `column!` expansion seems to be triggered by `assert_eq!`, so we're in the middle of another expansion. This PR simply avoids the panic by checking the length of the text.
r? @edwin0cheng
Co-authored-by: Marco Groppo <marco.groppo@gmail.com>
2396: Switch to variant-granularity field type inference r=flodiebold a=matklad
r? @flodiebold
Previously, we had a `ty` query for each field. This PR switcthes to a query per struct, which returns an `ArenaMap` with `Ty`s.
I don't know which approach is better. What is bugging me about the original approach is that, if we do all queries on the "leaf" defs, in practice we get a ton of queries which repeatedly reach into the parent definition to compute module, resolver, etc. This *seems* wasteful (but I don't think this is really what causes any perf problems for us).
At the same time, I've been looking at Kotlin, and they seem to use the general pattern of analyzing the *parent* definition, and storing info about children into a `BindingContext`.
I don't really which way is preferable. I think I want to try this approach, where query granularity generally mirrors the data granularity. The primary motivation for me here is probably just hope that we can avoid adding a ton of helpers to a `StructField`, and maybe in general avoid the need to switch to a global `StructField`, using `LocalStructFieldId` most of the time internally.
For external API (ie, for `ra_ide_api`), I think we should continue with fine-grained `StructField::ty` approach, which internally fetches the table for the whole struct and indexes into it.
In terms of actual memory savings, the results are as follows:
```
This PR:
142kb FieldTypesQuery (deps)
38kb FieldTypesQuery
Status Quo:
208kb TypeForFieldQuery (deps)
18kb TypeForFieldQuery
```
Note how the table itself occupies more than twice as much space! I don't have an explanation for this: a plausible hypothesis is that single-field structs are very common and for them the table is a pessimisation.
THere's noticiable wallclock time difference.
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2381: Add proc-macro crate type handling r=JasperDeSutter a=JasperDeSutter
Resolves the libproc_macro crate in crates that are the proc-macro type.
This doesn't seem the ideal implementation though, since the compiler still requires you to write `extern crate proc_macro;` (even in 2018 edition).
Co-authored-by: JasperDeSutter <jasper.desutter@gmail.com>
2383: Add alloc to the crate graph r=matklad a=marcogroppo
`alloc` has been added to the crate graph.
Completions work, but they are available even when the user has **not** declared an `extern crate alloc`. Is this the correct approach?
Fixes#2376.
Co-authored-by: Marco Groppo <marco.groppo@gmail.com>
2365: Make expand-macro more flexible r=matklad a=edwin0cheng
Due to lack of implementation or other types of errors, some macros do not expand correctly in the current situation. The PR attempts to make `expand-macro` more flexible in error situations by ignoring internal failed macro expansion.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
2343: implement assist invert_if r=matklad a=bravomikekilo
fix [issue 2219 invert if condition](https://github.com/rust-analyzer/rust-analyzer/issues/2219)
I put the assist cursor range to `if` of the if expression, because both condition and body will be replaced. Is there any way to replace them without cover the cursor position?
@matklad
Co-authored-by: bravomikekilo <bmk1221@126.com>
2348: Add support for stringify! builtin macro r=matklad a=piotr-szpetkowski
Refs #2212
First time ever contributing here, hopefully it's ok.
2352: Move TypeAlias to hir_def r=matklad a=matklad
Co-authored-by: Piotr Szpetkowski <piotr.szpetkowski@pyquest.space>
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
The current system with AstIds has two primaraly drawbacks:
* It is possible to manufacture IDs out of thin air.
For example, it's possible to create IDs for items which are not
considered in CrateDefMap due to cfg. Or it is possible to mixup
structs and unions, because they share ID space.
* Getting the ID of a parent requires a secondary index.
Instead, the plan is to pursue the more traditional approach, where
each items stores the id of the parent declaration. This makes
`FromSource` more awkward, but also more correct: now, to get from an
AST to HIR, we first do this recursively for the parent item, and the
just search the children of the parent for the matching def
This commit implements a general truncation framework for HirFormatter
that keeps track of how much has been output so far. This information
can then be used to perform truncation inside the language server,
instead of relying on the client.
Initial support is implemented for truncating types hints using the
maxInlayHintLength server config option. The existing solution in the
VSCode extension has been removed in favor of letting the server
truncate type hints.
2307: Support hover through macro r=matklad a=kjeremy
Allows hover to work through macros like `match_ast!`.
Co-authored-by: kjeremy <kjeremy@gmail.com>
We need to be more careful now when substituting bound variables (previously, we
didn't have anything that used bound variables except Chalk, so it was not a
problem).
This is obviously quite ad-hoc; Chalk has more infrastructure for handling this
in a principled way, which we maybe should adopt.
2252: Fix parsing of "postfix" range expressions. r=matklad a=goffrie
Right now they are handled in `postfix_dot_expr`, but that doesn't allow it to
correctly handle precedence. Integrate it more tightly with the Pratt parser
instead.
Also includes a drive-by fix for parsing `match .. {}`.
Fixes#2242.
Co-authored-by: Geoffry Song <goffrie@gmail.com>
Right now they are handled in `postfix_dot_expr`, but that doesn't allow it to
correctly handle precedence. Integrate it more tightly with the Pratt parser
instead.
Also includes a drive-by fix for parsing `match .. {}`.
Fixes#2242.
2165: ra_assists: Add add_new assist r=matklad a=rep-nop
Adds a new assist to autogenerate a new fn based on the selected struct, excluding tuple structs and unions. The fn will inherit the same visibility as the struct and the assist will attempt to reuse any existing impl blocks that exist at the same level of struct.
Not marking this as closing #1644 since there's a part 2 of adding autocompletion for when someone starts typing `[pub ]fn new(...`
Co-authored-by: Wesley Norris <repnop@outlook.com>
2249: Cleanup hover r=matklad a=kjeremy
Take advantage of classify_name to consolidate multiple hover paths. This isn't quite as clean as I want it to be (`no_fallback` bool is wonky). There's a relationship between `HoverResult` being empty and the range that is a little warty.
Also I noticed that HoverResults are always marked as exact and have been for quite a while... maybe that should be removed in another PR.
Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
2217: Implement FromStr for enum Edition r=matklad a=clemarescx
Just did this as I came across the comment in the code asking for implementing `std::str::FromStr` for `input::Edition`.
Not sure what was meant by "proper error handling" though, `panic!` with a descriptive message might not be it 😅
Co-authored-by: Metabaron <metabaron@tuta.io>
2200: Add variables to HIR r=matklad a=matklad
Introduce a `hir::Variable`, which should cover locals, parameters and `self`. Unlike `PatId`, variable knows it's owner so it is self-contained, and should be more convenient to use from `ra_ide_api`.
The goal here is to hide more details about `Body` from hir, which should make it easier to move `Body` into `hir_def`. I don't think that `ra_ide_api` intrracts with bodies directly at the moment anyway, but the glue layer is based basically on `ast::BindPat`, which seems pretty brittle.
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2205: Implement bulitin line! macro r=matklad a=edwin0cheng
This PR implements bulitin macro `line!` and add basic infra-structure for other bulitin macros:
1. Extend `MacroDefId` to support builtin macros
2. Add a `quote!` macro for simple quasi quoting.
Note that for support others builtin macros, eager macro expansion have to be supported first, this PR not try to handle it. :)
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This removes the special casing for the "core" prelude.
Whenever a later dependency also exports a prelude, it will replace
the formerly imported prelude. The utilized prelude then depends
purely on import order.
This adds support for completion and goto definition of
types defined within the "core" crate. The core crate is
added as a dependency to each crate in the project.
The core crate exported it's own prelude. This caused
now all crates to inherit the core crates prelude instead
of the std crates. In order to avoid the problem the
prelude resolution has been changed to overwrite
an already resolved prelude if this was set to a crate
named core - in order to pick a better prelude like std.
Fixes#2199
Adds a new assist to autogenerate a new fn based on the selected struct,
excluding tuple structs and unions. The fn will inherit the same
visibility as the struct and the assist will attempt to reuse any
existing impl blocks that exist at the same level of struct.
2169: MBE: Mapping spans for goto definition r=matklad a=edwin0cheng
Currently, go to definition gives the wrong span in MBE. This PR implement a mapping mechanism to fix it and it could be used for future MBE hygiene implementation.
The basic idea of the mapping is:
1. When expanding the macro, generated 2 `TokenMap` which maps the macro args and macro defs between tokens and input text-ranges.
2. Before converting generated `TokenTree` to `SyntaxNode`, generated a `ExpandedRangeMap` which is a mapping between token and output text-ranges.
3. Using these 3 mappings to construct an `ExpansionInfo` which can map between input text ranges and output text ranges.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
Removes nodrop and extra arrayvec
We have an extra crossbeam-queue and crossbeam-utils left but those should
drop once rayon accepts https://github.com/rayon-rs/rayon/pull/704
2179: Use HirDatabase to compute `is_deprecated` r=matklad a=martskins
This PR fixes#2167 by introducing `attributes_query` and adding `fn attrs(&self, def: crate::AttrDef) -> Option<Arc<[Attr]>>;` to the `DefDatabase` trait.
I'm a little concerned about the two spots in `attributes_query` where code is repeated, but I couldn't figure out a way to avoid that, so.. I welcome suggestions 😄
Co-authored-by: Martin Asquino <martin.asquino@gmail.com>
2173: MBE: Add TokenId shift in macro_rules r=matklad a=edwin0cheng
As discussed in #2169 , for fixing duplication TokenId during expansion :
> What we can do here is to re-number the tokens during expansion. Specifically:
> * when we create macro_rules, we note the highest id of the token we have as shift>
> * when we expand macro rules, if we need to output a token from definition, we just re-use its id
> * if we need to output a token from the argument, we increase its id by shift (so it's guaranteed to not to collide with anything from the definition)
> * finally, when we have a HirFileId of the expansion, we can look up the original value of shift and classify node to the arg/def by comparing it's id with shift.
>
This PR implement first 3 points of above solution.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
2149: Handle IfLet in convert_to_guarded_return. r=matklad a=krk
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/2124
I could not move the cursor position out of `let`:
`le<|>t` vs `let<|>`.
Also, please suggest extra test cases.
Co-authored-by: krk <keremkat@gmail.com>
2160: Set `deprecated` field on `CompletionItem`s r=matklad a=martskins
This PR aims to address #2042 by setting the deprecated field for completion items.
The setting the tags field for LSP 3.15 part still needs fixing, but that one is blocked due to lsp-types not being up to date with 3.15 yet.
Co-authored-by: Martin Asquino <martin.asquino@gmail.com>
2103: Expand signature help r=matklad a=kjeremy
Signature help using call syntax with tuple structs and enum variants
Fixes#2102.
Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
Co-authored-by: kjeremy <kjeremy@gmail.com>
2111: Fix autoimport not choosing the deepest use tree in some situations r=matklad a=flodiebold
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
2097: Be more precise with function signatures r=matklad a=kjeremy
Finds the closest call expr.
Fixes#2093
Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
Whitespace can have special meaning in markdown. For instance
ending a line with three spaces will render a new line.
Note that this behavior diverges from RLS.
Fixes#1997
2099: Fix panic on raw string assist r=matklad a=aee11
Strings that do not contain two quotation marks would cause a slice indexing panic because `find_usual_string_range` would return a range that only contained a single quotation mark.
Panic example:
```
fn main() {
let s = "<|>
}
```
I noticed a lot of panics from the `make_raw_string` assist while working on another issue today.
Co-authored-by: Alexander Elís Ebenesersson <alex2789@gmail.com>
Strings that do not contain two quotation marks
would cause a slice indexing panic because code
was assuming `find_usual_string_range` would return
a string with two quotes, but it would incorrectly
also return text ranges containing only a single quote.
When multiple traits bounds are present, expanded selection
from a single trait bound will include the nearest plus sign
(and whitespace after) before including the whole trait bound.
2006: Improvements around `Arc<[T]>` r=matklad a=sinkuu
First commit tries to avoid cloning `Arc<[T]>` to a temporary `Vec` for mutating it, if there are no other strong references. Second commit utilizes [`FromIterator for Arc<[T]>`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-FromIterator%3CT%3E) instead of `.collect::<Vec<_>>().into()` to avoid allocation in `From<Vec<T>> for Arc<[T]>`.
Co-authored-by: Shotaro Yamada <sinkuu@sinkuu.xyz>
1924: Support inferring&completing `Self` type in enum/struct/union definitions r=ice1000 a=ice1000
Signed-off-by: ice1000 <ice1000kotlin@foxmail.com>
An attempt to fix#1908.
This code works, but I believe the implementation is ugly. Please give me suggestions!
Co-authored-by: ice1000 <ice1000kotlin@foxmail.com>
1951: Lower the precedence of the `as` operator. r=matklad a=goffrie
Previously, the `as` operator was being parsed like a postfix expression, and
therefore being given the highest possible precedence. That caused it to bind
more tightly than prefix operators, which it should not. Instead, parse it
somewhat like a normal binary expression with some special-casing.
Fixes#1851.
Co-authored-by: Geoffry Song <goffrie@gmail.com>
1928: Support `#[cfg(..)]` r=matklad a=oxalica
This PR implement `#[cfg(..)]` conditional compilation. It read default cfg options from `rustc --print cfg` with also hard-coded `test` and `debug_assertion` enabled.
Front-end settings are **not** included in this PR.
There is also a known issue that inner control attributes are totally ignored. I think it is **not** a part of `cfg` and create a separated issue for it. #1949Fixes#1920
Related: #1073
Co-authored-by: uHOOCCOOHu <hooccooh1896@gmail.com>
Co-authored-by: oxalica <oxalicc@pm.me>
Fixes#1807
This assist can transform expressions of the form `!x || !y` into
`!(x && y)`. This also works with `&&`.
This assist will only trigger if the cursor is on the central logical
operator.
The main limitation of this current implementation is that both operands
need to be an explicit negation, either of the form `!x`, or `x != y`.
More operands could be accepted, but this would complicate the implementation
quite a bit.
Forbidding block expressions entirely is too strict; instead, we should only
forbid them in contexts where we are parsing an optional RHS (i.e. the RHS of a
range expression).
Previously, the `as` operator was being parsed like a postfix expression, and
therefore being given the highest possible precedence. That caused it to bind
more tightly than prefix operators, which it should not. Instead, parse it
somewhat like a normal binary expression with some special-casing.
1945: Handle divergence in type inference for blocks r=flodiebold a=lnicola
Fixes#1944.
The `infer_basics` test is failing, not sure what to do about it.
Co-authored-by: Laurențiu Nicola <lnicola@dend.ro>
1815: Support correct `$crate` expansion in macros r=uHOOCCOOHu a=uHOOCCOOHu
This PR makes normal use cases of `$crate` from macros work as expected.
It makes more macros from `std` work. Type inference works well with `panic`, `unimplemented`, `format`, and maybe more.
Sadly that `vec![1, 2, 3]` still not works, but it is not longer an issue about macro.
Screenshot:
![Screenshot_20190927_022136](https://user-images.githubusercontent.com/14816024/65714465-b4568f80-e0cd-11e9-8043-dd44c2ae8040.png)
Co-authored-by: uHOOCCOOHu <hooccooh1896@gmail.com>
1912: add new editing API, suitable for modifying several nodes at once r=viorina a=matklad
r? @viorina
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
1895: Handle associated type shorthand (`T::Item`) (Second attempt) r=flodiebold a=flodiebold
This is only allowed for generic parameters (including `Self` in traits), and
special care needs to be taken to not run into cycles while resolving it,
because we use the where clauses of the generic parameter to find candidates for
the trait containing the associated type, but the where clauses may themselves
contain instances of short-hand associated types.
In some cases this is even fine, e.g. we might have `T: Trait<U::Item>, U:
Iterator`. If there is a cycle, we'll currently panic, which isn't great, but
better than overflowing the stack...
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This is only allowed for generic parameters (including `Self` in traits), and
special care needs to be taken to not run into cycles while resolving it,
because we use the where clauses of the generic parameter to find candidates for
the trait containing the associated type, but the where clauses may themselves
contain instances of short-hand associated types.
In some cases this is even fine, e.g. we might have `T: Trait<U::Item>, U:
Iterator`. If there is a cycle, we'll currently panic, which isn't great, but
better than overflowing the stack...
1853: Introduce FromSource trait r=matklad a=viorina
The idea is to provide an ability to get HIR from AST in a more general way than it's possible using `source_binder`.
It also could help with #1622 fixing.
Co-authored-by: Ekaterina Babshukova <ekaterina.babshukova@yandex.ru>
1862: Assoc item resolution refactoring (again) r=flodiebold a=flodiebold
This is #1849, with the associated type selection code removed for now. Handling cycles there will need some more thought.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
I must confess I don't really understand what this code is trying to
do, but it definitely misreports changes during fixedpoint iteration,
and no tests fail if I remove it, so...
Type-relative paths (`<T>::foo`) also need to work in type context, for example
`<T>::Item` is legal. So rather than returning the type ref from the resolver
function, just check it before.
E.g. `fn foo<T: Iterator>() -> T::Item`. It seems that rustc does this only for
type parameters and only based on their bounds, so we also only consider traits
from bounds.
1848: Parse `..` as a full pattern r=matklad a=ecstatic-morse
Resolves#1479.
This PR implements [RFC 2707](https://github.com/rust-lang/rfcs/pull/2707) in the parser. It introduces a new `DotDotPat` AST node modeled on `PlaceholderPat` and changes the parsing of tuple and slice patterns to conform to the RFC.
Notably, this PR does *not* change the resulting AST when `..` appears in a struct pattern (e.g. `Struct { a, b: c, .. }`). I *think* this is the behavior mandated by RFC 2707, but someone should confirm this.
Co-authored-by: Dylan MacKenzie <ecstaticmorse@gmail.com>
Nameres related types, like `PerNs<Resolution>`, can represent
unreasonable situations, like a local in a type namespace. We should
clean this up, by requiring that call-site specifies the kind of
resolution it expects.
1821: Macro completion tweaks r=matklad a=SomeoneToIgnore
Thanks @uHOOCCOOHu for making the macro completion happen :)
I've added a few tweaks to the current completion to make it a bit more convenient:
* Automatically add braces and put the editor cursor inside of them:
<img width="159" alt="image" src="https://user-images.githubusercontent.com/2690773/64737220-022b9f00-d4f5-11e9-8088-76d4678921ab.png">
Currently I have to add the braces manually which is a bit cumbersome.
One further improvement can be to detect if macro accepts no parameters and place the cursor differently for this case.
* Add an exclamation mark to the macro completion label
This helps to distinguish macros from other completion items and also allows to show only macros in completion if you type `!`:
<img width="722" alt="image" src="https://user-images.githubusercontent.com/2690773/64736987-8b8ea180-d4f4-11e9-8355-2ce4f83b7aa8.png">
<img width="732" alt="image" src="https://user-images.githubusercontent.com/2690773/64737214-ffc94500-d4f4-11e9-946e-1ba2db1c7fb1.png">
Additionally, automatic formatting hooks had adjusted two `help.rs` files, I've added them as a last commit to the PR even though they are not really related.
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Parser has the invariant that `{}` are balanced.
Previous code tried (unsucesfuly) maintain the same invariant for
`$()` as well, but it was done in a rather ad-hoc manner: it's not at
all obvious that it is possible to maintain both invariants!
1795: Make macro scope a real name scope and fix some details r=matklad a=uHOOCCOOHu
This PR make macro's module scope a real name scope in `PerNs`, instead of handling `Either<PerNs, MacroDef>` everywhere.
In `rustc`, the macro scope behave exactly the same as type and value scope.
It is valid that macros, types and values having exact the same name, and a `use` statement will import all of them. This happened to module `alloc::vec` and macro `alloc::vec!`.
So `Either` is not suitable here.
There is a trap that not only does `#[macro_use]` import all `#[macro_export] macro_rules`, but also imports all macros `use`d in the crate root.
In other words, it just _imports all macros in the module scope of crate root_. (Visibility of `use` doesn't matter.)
And it also happened to `libstd` which has `use alloc_crate::vec;` in crate root to re-export `alloc::vec`, which it both a module and a macro.
The current implementation of `#[macro_use] extern crate` doesn't work here, so that is why only macros directly from `libstd` like `dbg!` work, while `vec!` from `liballoc` doesn't.
This PR fixes this.
Another point is that, after some tests, I figure out that _`macro_rules` does NOT define macro in current module scope at all_.
It defines itself in legacy textual scope. And if `#[macro_export]` is given, it also is defined ONLY in module scope of crate root. (Then being `macro_use`d, as mentioned above)
(Well, the nightly [Declarative Macro 2.0](https://github.com/rust-lang/rust/issues/39412) simply always define in current module scope only, just like normal items do. But it is not yet supported by us)
After this PR, in my test, all non-builtin macros are resolved now. (Hover text for documentation is available) So it fixes#1688 . Since compiler builtin macros are marked as `#[rustc_doc_only_macro]` instead of `#[macro_export]`, we can simply tweak the condition to let it resolved, but it may cause expansion error.
Some critical notes are also given in doc-comments.
<img width="447" alt="Screenshot_20190909_223859" src="https://user-images.githubusercontent.com/14816024/64540366-ac1ef600-d352-11e9-804f-566ba7559206.png">
Co-authored-by: uHOOCCOOHu <hooccooh1896@gmail.com>
Some method resolution tests now yield `{unknown}` where they did not
before.
Other tests now succeed, likely because this is helping the solver
steer its efforts.
This is to make debugging rust-analyzer easier.
The idea is that `dbg!(krate.debug(db))` will print the actual, fuzzy
crate name, instead of precise ID. Debug printing infra is a separate
thing, to make sure that the actual hir doesn't have access to global
information.
Do not use `.debug` for `log::` logging: debugging executes queries,
and might introduce unneded dependencies to the crate graph
1793: Fix outer doc-comments of `macro_rules` r=matklad a=uHOOCCOOHu
Document comments of `macro_rules!` is currently parsed outside the `MACRO_CALL` node,
which makes `DocCommentsOwner::doc_comments()` always empty.
For the input:
```rust
/// Some docs
macro_rules! foo {
() => {};
}
```
Current parsing tree is:
```
SOURCE_FILE
COMMENT // <- This should be children of MACRO_CALL
WHITESPACE
MACRO_CALL
PATH
<...omitted...>
```
It should be:
```
SOURCE_FILE
MACRO_CALL
COMMENT
WHITESPACE
PATH
<...omitted...>
```
Co-authored-by: uHOOCCOOHu <hooccooh1896@gmail.com>
1771: Further tweak for macro_use on extern crate r=matklad a=uHOOCCOOHu
Some more tweaks to #1743 to behave more like `rustc`
1. Hoist macros from `#[macro_use] extern crate`, so that they can be used before `extern crate`.
2. Implicit `#[macro_use]` for `prelude` if exists
Co-authored-by: uHOOCCOOHu <hooccooh1896@gmail.com>
1743: Support `#[macro_use]` on `extern crate` r=matklad a=uHOOCCOOHu
Unfortunately, #1688 is still an issue. My guess is wrong :(
Co-authored-by: uHOOCCOOHu <hooccooh1896@gmail.com>
It's a bit complicated because we basically have to 'undo' the desugaring, and
the result is very dependent on the specifics of the desugaring and will
probably produce weird results otherwise.
1734: Strip indents and empty lines in check_apply_diagnostic_fix_from_position r=matklad a=matklad
Co-authored-by: Phil Ellison <phil.j.ellison@gmail.com>
Named structs can have `box` patterns that will bind to their fields.
This is similar to the behavior of the `ref` and `mut` fields, but is at
least a little bit surprising.
1721: Impl/dyn trait r=flodiebold a=flodiebold
This adds support for `impl Trait` and `dyn Trait` types as far as possible without Chalk. So we can represent them in the type system, and handle them in method resolution, but Chalk doesn't know about them yet. There's a small temporary hack here where we bypass Chalk during method resolution, so we can handle simple method calls on them and completion works.
Fixes#1608.
1723: Make sysroot use `RUST_SRC_PATH` if set r=matklad a=bkchr
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
When we have one of these, the `Trait` doesn't need to be in scope to call its
methods. So we need to consider this when looking for method
candidates. (Actually I think the same is true when we have a bound `T:
some::Trait`, but we don't handle that yet).
At the same time, since Chalk doesn't handle these types yet, add a small hack
to skip Chalk in method resolution and just consider `impl Trait: Trait` always
true. This is enough to e.g. get completions for `impl Trait`, but since we
don't do any unification we won't infer the return type of e.g. `impl
Into<i64>::into()`.
- refactor bounds handling in the AST a bit
- add HIR for bounds
- add `Ty::Dyn` and `Ty::Opaque` variants and lower `dyn Trait` / `impl Trait`
syntax to them
This adds three different representations, copied from the Chalk model:
- `Ty::Projection` is an associated type projection written somewhere in the
code, like `<Foo as Trait>::Bar`.
- `Ty::UnselectedProjection` is similar, but we don't know the trait
yet (`Foo::Bar`).
- The above representations are normalized to their actual types during type
inference. When that isn't possible, for example for `T::Item` inside an `fn
foo<T: Iterator>`, the type is normalized to an application type with
`TypeCtor::AssociatedType`.
1661: Parse function parameters attributes r=matklad a=eupn
Fixes#1397. The [RFC-2565](https://github.com/rust-lang/rfcs/blob/master/text/2565-formal-function-parameter-attributes.md) specifies `#[attributes]` to function parameters:
```rust
fn foo(#[attr] a, #[unused] b, #[must_use] ...) {
// ...
}
```
This PR adds those attributes into grammar and to the parser, extending corresponding inline tests.
Co-authored-by: Evgenii P <eupn@protonmail.com>
1652: Improve type hints behavior r=matklad a=SomeoneToIgnore
This PR fixed the following type hints issues:
* Restructures the `InlayKind` enum contents based on the discussion here: https://github.com/rust-analyzer/rust-analyzer/pull/1606#issuecomment-515968055
* Races described in #1639
* Caches the latest decorations received for each file to show them the next time the file is opened (instead of a new server request)
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
1634: Implement .await completion for futures r=flodiebold a=eupn
Closes#1263 with completion for `.await` syntax for types that are implementing `std::future::Future` trait.
r? @flodiebold
Co-authored-by: Evgenii P <eupn@protonmail.com>
1601: Inline snapshots for tests r=matklad a=theotherphil
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/1127.
The "cargo format" commits are required to get the formatting tests to pass. However, they actually mess up the formatting.
Co-authored-by: Phil Ellison <phil.j.ellison@gmail.com>
1606: Add `if let`, `while let` and match arm inlay hints r=matklad a=SomeoneToIgnore
<img width="693" alt="image" src="https://user-images.githubusercontent.com/2690773/62013363-152f1d80-b19a-11e9-90ea-07568757baa2.png">
Add more inline hints support.
Looks like `while let` type inference support is missing currently, so the corresponding hint tests lack the actual results.
I've also could not find a good way to distinguish between `a` and `b` pats in the following expressions:
`if let Some(Test { a: None, b: y }) = &test {};`
In this case we don't need to add a hint for first pat (`a: None`), since it's matched against the particular enum variant and need a hint for `y`, since it's a new variable.
But both `a` and `b` are `BIND_PAT` with similar contents, so looks like there's nothing I can check for to find any differences.
I don't display any hints for such cases now, to avoid confusion, but would be nice to know if there's a way to fix this behavior.
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
1549: Show type lenses for the resolved let bindings r=matklad a=SomeoneToIgnore
Types that are fully unresolved are not displayed:
<img width="279" alt="image" src="https://user-images.githubusercontent.com/2690773/61518122-8e4ba980-aa11-11e9-9249-6d9f9b202e6a.png">
A few concerns that I have about the current implementation:
* I've adjusted the `file_structure` API method to return the information about the `let` bindings.
Although it works fine, I have a feeling that adding a new API method would be the better way.
But this requires some prior discussion, so I've decided to go for an easy way with an MVP.
Would be nice to hear your suggestions.
* There's a hardcoded `{undersolved}` check that I was forced to use, since the method that resolves types returns a `String`.
Is there a better typed API I can use? This will help, for instance, to add an action to the type lenses that will allow us to navigate to the type.
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
1562: Continue support for .await r=matklad a=unrealhoang
- add await expr to ast and HIR Expr
- infer type for `.await`
Co-authored-by: Unreal Hoang <unrealhoang@gmail.com>
* make stuff more type-safe by using `BindPat` instead of just `Pat`
* don't add `mut` into binding hash
* reset shadow counter when we enter a function
1537: Less magic completions r=matklad a=marcogroppo
Restrict `if`, `not` and `while` postfix magic completions to boolean expressions and expressions of an unknown type.
(this may be controversial, marking as draft for this reason)
See the discussion in #1526.
Co-authored-by: Marco Groppo <marco.groppo@gmail.com>
1520: Ignore workspace/didChangeConfiguration notifications. r=matklad a=bolinfest
If the client happens to send a `workspace/didChangeConfiguration`
notification, it is nicer if rust-analyzer can just ignore it rather than
crash with an "unhandled notification" error.
Co-authored-by: Michael Bolin <bolinfest@gmail.com>
This appears to have been introduced ages ago in
be742a5877
but has since been removed.
As it stands, it is problematic if multiple instances of the
rust-analyzer LSP are launched during the same VS Code session because
VS Code complains about multiple LSP servers trying to register the
same command.
Most LSP servers workaround this by parameterizing the command by the
process id. For example, this is where `rls` does this:
ff0b9057c8/rls/src/server/mod.rs (L413-L421)
Though `apply_code_action` does not seems to be used, so it seems better
to delete it than to parameterize it.
1515: Trait environment r=matklad a=flodiebold
This adds the environment, i.e. the set of `where` clauses in scope, when solving trait goals. That means that e.g. in
```rust
fn foo<T: SomeTrait>(t: T) {}
```
, we are able to complete methods of `SomeTrait` on the `t`. This affects the trait APIs quite a bit (since every method that needs to be able to solve for some trait needs to get this environment somehow), so I thought I'd do it rather sooner than later ;)
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
1504: Simplify LSP handlers r=matklad a=kjeremy
Takes advantage of protocol inheritance via composition and simplifies some responses via the `From`/`Into` traits.
Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
1499: processing attribute #[path] of module r=matklad a=andreevlex
support two cases
- simple name file `foo.rs`
- declaration in mod.rs
#1211
Co-authored-by: Alexander Andreev <andreevlex.as@gmail.com>
1491: More clippy r=matklad a=kjeremy
A few more clippy changes.
I'm a little unsure of the second commit. It's the trivially_copy_pass_by_ref lint and there are a number of places in the code we could use it if it makes sense.
Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
This wasn't a right decision in the first place, the feature flag was
broken in the last rustfmt release, and syntax highlighting of imports
is more important anyway
Array members are allow to have attributes such as `#[cfg]`.
This is a bit tricky as we don't know if the first expression is an
initializer or a member until we encounter a `;`. This reuses a trick
from `stmt` where we remember if we saw an attribute and then raise an
error if the first expression ends up being an initializer.
This isn't perfect as the error isn't correctly located on the attribute
or initializer; it ends up immediately after the `;`.
1456: Deduplicate method candidates r=matklad a=flodiebold
With trait method completion + autoderef, we were getting a lot of duplicates, which was really annoying...
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
My workflow in Visual Studio Code + Rust Analyzer has become:
1. Make a change to Rust source code using all the analysis magic
2. Save the file to trigger `cargo watch`. I have format on save enabled
for all file types so this also runs `rustfmt`
3. Fix any diagnostics that `cargo watch` finds
Unfortunately if the Rust source has any syntax errors the act of saving
will pop up a scary "command has failed" message and will switch to the
"Output" tab to show the `rustfmt` error and exit code.
I did a quick survey of what other Language Servers do in this case.
Both the JSON and TypeScript servers will swallow the error and return
success. This is consistent with how I remember my workflow in those
languages. The syntax error will show up as a diagnostic so it should
be clear why the file isn't formatting.
I checked the `rustfmt` source code and while it does distinguish "parse
errors" from "operational errors" internally they both result in exit
status of 1. However, more catastrophic errors (missing `rustfmt`,
SIGSEGV, etc) will return 127+ error codes which we can distinguish from
a normal failure.
This changes our handler to log an info message and feign success if
`rustfmt` exits with status 1.
Another option I considered was only swallowing the error if the
formatting request came from format-on-save. However, the Language
Server Protocol doesn't seem to distinguish those cases.
1443: cache chalk queries r=flodiebold a=matklad
This gives a significant speedup, because chalk will call these
functions several times even withing a single revision. The only
significant one here is `impl_data`, but I figured it might be good to
cache others just for consistency.
The results I get are:
Before:
from scratch: 16.081457952s
no change: 15.846493ms
trivial change: 352.95592ms
comment change: 361.998408ms
const change: 457.629212ms
After:
from scratch: 14.910610278s
no change: 14.934647ms
trivial change: 85.633023ms
comment change: 96.433023ms
const change: 171.543296ms
Seems like a nice win!
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This gives a significant speedup, because chalk will call these
functions several times even withing a single revision. The only
significant one here is `impl_data`, but I figured it might be good to
cache others just for consistency.
The results I get are:
Before:
from scratch: 16.081457952s
no change: 15.846493ms
trivial change: 352.95592ms
comment change: 361.998408ms
const change: 457.629212ms
After:
from scratch: 14.910610278s
no change: 14.934647ms
trivial change: 85.633023ms
comment change: 96.433023ms
const change: 171.543296ms
Seems like a nice win!
Now, one can use `let _p = ra_prof::cpu_profiler()` to capture profile
of a block of code.
This is not an out of the box experience, as that relies on gperfools
See the docs on https://github.com/AtheMathmo/cpuprofiler for more!
1432: Make fill_match_arm work with trivial arm r=matklad a=ironyman
Addresses this issue https://github.com/rust-analyzer/rust-analyzer/issues/1399
One minor issue I noticed is that complete_postfix creates an arm like this
```
match E::X {
<|>_ => {},
}
```
but fill_match_arms creates arms like this
```
E::X => (),
```
Co-authored-by: ironyman <ironyman@users.noreply.github.com>
Co-authored-by: Changyu Li <changyl@microsoft.com>
1409: The Fall down of failures r=matklad a=mominul
😁
Replaced all the uses of `failure` crate with `std::error::Error`.
Closes#1400
Depends on rust-analyzer/teraron#1
Co-authored-by: Muhammad Mominul Huque <mominul2082@gmail.com>
Can be used like this:
```
$ cargo run --release -p ra_cli -- \
analysis-bench ../chalk/ \
--complete ../chalk/chalk-engine/src/logic.rs:94:0
loading: 225.970093ms
from scratch: 8.492373325s
no change: 445.265µs
trivial change: 95.631242ms
```
Or like this:
```
$ cargo run --release -p ra_cli -- \
analysis-bench ../chalk/ \
--highlight ../chalk/chalk-engine/src/logic.rs
loading: 209.873484ms
from scratch: 9.504916942s
no change: 7.731119ms
trivial change: 124.984039ms
```
"from scratch" includes initial analysis of the relevant bits of the
project
"no change" just asks the same question for the second time. It
measures overhead on assembling the answer outside of salsa.
"trivial change" doesn't do an actual salsa change, it just advances
the revision. This test how fast is salsa at validating things.
1408: Associated type basics & Deref support r=matklad a=flodiebold
This adds the necessary Chalk integration to handle associated types and uses it to implement support for `Deref` in the `*` operator and autoderef; so e.g. dot completions through an `Arc` work now.
It doesn't yet implement resolution of associated types in paths, though. Also, there's a big FIXME about handling variables in the solution we get from Chalk correctly.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
1406: reuse AnalysisHost in batch analysis r=matklad a=matklad
We do some custom setup in `AnalysisHost`, like setting up LRU size. I figure it's a good idea to not duplicate this work in batch analysis, *if* we want to keep batch and non-batch close.
Long-term, I see a value in keeping batch a separate, lighter weight thing. However, because now we use batch to measure performance, keeping them closer makes more sense.
I'd also like to add ability to get completions by using batch analysis, and that will require ra_ide_api as well.
@flodiebold were there some reason why we haven't started with this approach from the start?
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>