As stated by matklad, reading the stderr
should be done alngside with
stdout via select() (or I guess poll()),
there is no such implementation in stdlib,
since it is quite low level and platform-dependent and it
also requires quite a bit of unrelated code we don't use it for now.
As referenced by bjorn3, there is an implementation of the needed read2() function
in rustc compiletest. The better solution will be to extract this function
to a separate crate in future:
https://github.com/rust-analyzer/rust-analyzer/pull/3632#discussion_r395605298
3671: Add identity expansion checking in ill-form expansion r=flodiebold a=edwin0cheng
This PR try to add more checking code in error case in macro expansion. The bug in #3642 is introduced by #3580 , which allow ill-form macro expansion in *all* kind of macro expansions.
In general we should separate hypothetical macro expansion and the actual macro expansion call. However, currently the `Semantic` workflow we are using only support single macro expansion type, we might want to review it and make it works in both ways. (Maybe add a field in `MacroCallLoc` for differentiation)
Fix#3642
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3623: 'Fill match arms' should work with existing match arms r=matklad a=slyngbaek
Addresses #3039
This essentially adds missing match arms. The algorithm for this
can get complicated rather quickly so bail in certain conditions
and rely on a PlaceholderPat.
The algorighm works as such:
- Iterate through the Enum Def Variants
- Attempt to see if the variant already exists as a match arm
- If yes, skip the enum variant. If no, include it.
- If it becomes complicated, rather than exhaustively deal with every
branch, mark it as a "partial match" and simply include the
placeholder.
Conditions for "complication":
- The match arm contains a match guard
- Any kind of nested destrucuring
Order the resulting merged match branches as such:
1. Provided match arms
2. Missing enum variant branch arms
3. End with Placeholder if required
- Add extra tests
Co-authored-by: Steffen Lyngbaek <steffenlyngbaek@gmail.com>
Iterate through TupleStructPat's until a MatchArm if
one exists. Store in a new is_pat_bind_and_path bool
and allow the `complete_scope` to find matches.
Added some tests to ensure it works in simple and nested cases.
Addresses #3039
This essentially adds missing match arms. The algorithm for this
can get complicated rather quickly so bail in certain conditions
and rely on a PlaceholderPat.
The algorighm works as such:
- Iterate through the Enum Def Variants
- Attempt to see if the variant already exists as a match arm
- If yes, skip the enum variant. If no, include it.
- If it becomes complicated, rather than exhaustively deal with every
branch, mark it as a "partial match" and simply include the
placeholder.
Conditions for "complication":
- The match arm contains a match guard
- Any kind of nested destrucuring
Order the resulting merged match branches as such:
1. Provided match arms
2. Missing enum variant branch arms
3. End with Placeholder if required
- Add extra tests
It improves compile time in `--release` mode quite a bit, it doesn't
really slow things down and, conceptually, it seems closer to what we
want the physical architecture to look like (we don't want to
monomorphise EVERYTHING in a single leaf crate).
3573: Check all crates of the workspace r=matklad a=matklad
Previously, if the root of the was was a real crate, only this crate
was checked.
Ideally, we might want some kind of config here (which might be just
overriding the whole command), but `--workspace` is def a nicer
default.
r? @kiljacken
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
3587: Use WorkDoneProgress LSP API for initial load r=matklad a=slyngbaek
Addresses #3283
Rather than using custom UI for showing the loaded state. Rely
on the WorkDoneProgress API in 3.15.0
https://microsoft.github.io/language-server-protocol/specification#workDoneProgress.
No client-side work was necessary. The UI is not exactly what is
described in the issue but afaict that's how VS Code implements the LSP
API.
- The WorkDoneProgressEnd does not appear to display its message
contents (controlled by vscode)
Co-authored-by: Steffen Lyngbaek <steffenlyngbaek@gmail.com>
3591: Support local macro_rules r=matklad a=edwin0cheng
This PR implement local `macro_rules` in function body, by adding following things:
1. While lowering, add a `MacroDefId` in body's `ItemScope` as a textual legacy macro.
2. Make `Expander::enter_expand` search with given `ItemScope`.
3. Make `Resolver::resolve_path_as_macro` search with `LocalItemScope`.
Fix#2181
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
Addresses #3283
Rather than using custom UI for showing the loaded state. Rely
on the WorkDoneProgress API in 3.15.0
https://microsoft.github.io/language-server-protocol/specification#workDoneProgress.
No client-side work was necessary. The UI is not exactly what is
described in the issue but afaict that's how VS Code implements the LSP
API.
- The WorkDoneProgressEnd does not appear to display its message
contents (controlled by vscode)
3561: feat: add debug code lens r=matklad a=hdevalke
Refs #3539
3577: Protect against infinite macro expansion in def collector r=edwin0cheng a=flodiebold
Something I noticed while trying to make macro expansion more resilient against errors.
There was a test for this, but it wasn't actually working because the first recursive expansion failed. (The comma...)
Even with this limit, that test (when fixed) still takes some time to pass because of the exponential growth of the expansions, so I disabled it and added a different one without growth.
CC @edwin0cheng
Co-authored-by: Hannes De Valkeneer <hannes@de-valkeneer.be>
Co-authored-by: hdevalke <2261239+hdevalke@users.noreply.github.com>
Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
There was a test for this, but it wasn't actually working because the first
recursive expansion failed. (The comma...)
Even with this limit, that test (when fixed) still takes some time to pass
because of the exponential growth of the expansions, so I disabled it and added
a different one without growth.
The `ty` function in code_model returned the type with placeholders for type
parameters. That's nice for printing, but not good for completion, because
placeholders won't unify with anything else: So the type we got for `HashMap`
was `HashMap<K, V, T>`, which doesn't unify with `HashMap<?, ?, RandomState>`,
so the `new` method wasn't shown.
Now we instead return `HashMap<{unknown}, {unknown}, {unknown}>`, which does
unify with the impl type. Maybe we should just expose this properly as variables
though, i.e. we'd return something like `exists<type, type, type> HashMap<?0,
?1, ?2>` (in Chalk notation). It'll make the API more complicated, but harder to
misuse. (And it would handle cases like `type TypeAlias<T> = HashMap<T, T>` more
correctly.)
Previously, if the root of the was was a real crate, only this crate
was checked.
Ideally, we might want some kind of config here (which might be just
overriding the whole command), but `--workspace` is def a nicer
default.
3553: Completions do not show for function with same name as mod r=matklad a=JoshMcguigan
fixes#3444
I've added a test case in `crates/ra_ide/src/completion/complete_path.rs` which verifies the described behavior in #3444. Digging in, I found that [the module scope iterator](ba62d8bd1c/crates/ra_ide/src/completion/complete_path.rs (L22)) only provides the module `z`, and does not provide the function `z` (although if I name the function something else then it does show up here).
I thought perhaps the name wasn't being properly resolved, but I added a test in `crates/ra_hir_def/src/nameres/tests.rs` which seems to suggest that it is? I've tried to figure out how to bridge the gap between these two tests (one passing, one failing) to see where the function `z` is being dropped, but to this point I haven't been able to track it down.
Any pointers on where I might look for this?
Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com>
3543: Parameter inlay hint separate from variable type inlay? #2876 r=matklad a=slyngbaek
Add setting to allow enabling either type inlay hints or parameter
inlay hints or both. Group the the max inlay hint length option
into the object.
- Add a new type for the inlayHint options.
- Add tests to ensure the inlays don't happen on the server side
Co-authored-by: Steffen Lyngbaek <steffenlyngbaek@gmail.com>
3559: Implement builtin assert! macro r=matklad a=edwin0cheng
This PR add a dummy implementation for `assert!` macro, which mainly make `hover` and `goto-def` works on arguments inside it.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3564: Better handling of a few kinds of cargo/clippy diagnostics r=matklad a=kiljacken
This was initially supposed to just be a fix for #3433, but I caught a few things that ended up being useful as well.
This PR primarily makes us handle multi-edit fix suggestions properly. Instead of just applying the first fix we apply all the parts of the fix in a single action.
Second up, this PR handles diagnostics with multiple primary spans, f.x. the unused import diagnostic from rustc:
![image](https://user-images.githubusercontent.com/209321/76531793-03269480-6476-11ea-9180-41c0ea705553.png)
The LSP doesn't handle this too well, as it only support a single complete range for each diagnostic, so we get duplicate messages in the problem panel of VSCode:
![image](https://user-images.githubusercontent.com/209321/76531901-29e4cb00-6476-11ea-9746-cd57f8974b85.png)
However, I feel like the improved visual aspect in-editor outweighs the duplication in the problem panel. I'm open to not including the second commit if anybody really doesn't like the idea of duplicate diagnostics in the problem pane.
Fixes#3433Fixes#3257
Co-authored-by: Emil Lauridsen <mine809@gmail.com>
- Instead of a single object type, use several individual nested types
to allow toggling from the settings GUI
- Remove unused struct definitions
- Install and test that the toggles work
3549: Implement env! macro r=matklad a=edwin0cheng
This PR implements `env!` macro by adding following things:
1. Added `additional_outdirs` settings in vscode. (naming to be bikeshed)
2. Added `ExternSourceId` which is a wrapping for SourceRootId but only used in extern sources. It is because `OUT_DIR` is not belonged to any crate and we have to access it behind an `AstDatabase`.
3. This PR does not implement the `OUT_DIR` parsing from `cargo check`. I don't have general design about this, @kiljacken could we reuse some cargo watch code for that ?
~~Block on [#3536]~~
PS: After this PR , we (kind of) completed the `include!(concat!(env!('OUT_DIR'), "foo.rs")` macro call combo. [Exodia Obliterate!](https://www.youtube.com/watch?v=RfqNH3FoGi0)
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3542: Renames work on struct field shorthands r=matklad a=m-n
When renaming either a local or a struct field, struct field shorthands are now renamed correctly.
Happy to refactor this if it doesn't fit the design of the code. Thanks for adding the suggestion of where to start on the issue.
I wasn't sure if I should also look at the behavior of renaming when placing the cursor at the field shorthand; the following describes the behavior with this patch:
```rust
#[test]
fn test_rename_field_shorthand_for_unspecified() {
// when renaming a shorthand, should we have a way to specify
// between renaming the field and the local?
//
// If not is this the correct default?
test_rename(
r#"
struct Foo {
i: i32,
}
impl Foo {
fn new(i: i32) -> Self {
Self { i<|> }
}
}
"#,
"j",
r#"
struct Foo {
i: i32,
}
impl Foo {
fn new(j: i32) -> Self {
Self { i: j }
}
}
"#,
);
}
```
Resolves#3431
Co-authored-by: Matt Niemeir <matt.niemeir@gmail.com>
- Updated naming of config
- Define struct in ra_ide and use remote derive in rust-analyzer/config
- Make inlayConfig type more flexible to support more future types
- Remove constructor only used in tests
Add setting to allow enabling either type inlay hints or parameter
inlay hints or both. Group the the max inlay hint length option
into the object.
- Add a new type for the inlayHint options.
- Add tests to ensure the inlays don't happen on the server side
To test whether the receiver type matches for the impl, we unify the given self
type (in this case `HashSet<{unknown}>`) with the self type of the
impl (`HashSet<?0>`), but if the given self type contains Unknowns, they won't
be unified with the variables in those places. So we got a receiver type that
was different from the expected one, and concluded the impl doesn't match.
The fix is slightly hacky; if after the unification, our variables are still
there, we make them fall back to Unknown. This does make some sense though,
since we don't want to 'leak' the variables.
Fixes#3547.
3536: Add get and set for `Env` r=matklad a=edwin0cheng
This PR add three things :
1. Add `get` and `set` in `Env`.
2. Implement fixture meta for `with_single_file`.
3. Add `env` meta in fixture.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3526: Silence "file out of workspace" errors r=matklad a=matklad
We really should fix this limitation of the VFS, but it's some way off
at the moment, so let's just silence the user-visible error for now.
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
3513: Completion in macros r=matklad a=flodiebold
I experimented a bit with completion in macros. It's kind of working, but there are a lot of rough edges.
- I'm trying to expand the macro call with the inserted fake token. This requires some hacky additions on the HIR level to be able to do "hypothetical" expansions. There should probably be a nicer API for this, if we want to do it this way. I'm not sure whether it's worth it, because we still can't do a lot if the original macro call didn't expand in nearly the same way. E.g. if we have something like `println!("", x<|>)` the expansions will look the same and everything is fine; but in that case we could maybe have achieved the same result in a simpler way. If we have something like `m!(<|>)` where `m!()` doesn't even expand or expands to something very different, we don't really know what to do anyway.
- Relatedly, there are a lot of cases where this doesn't work because either the original call or the hypothetical call doesn't expand. E.g. if we have `m!(x.<|>)` the original token tree doesn't parse as an expression; if we have `m!(match x { <|> })` the hypothetical token tree doesn't parse. It would be nice if we could have better error recovery in these cases.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
3516: Handle visibility in more cases in completion r=matklad a=flodiebold
This means we don't show private items when completing paths or method calls.
We might want to show private items if we can edit their definition and provide a "make public" assist, but I feel like we'd need better sorting of completion items for that, so they can be not shown or sorted to the bottom by default. Until then, they're usually more of a distraction to me.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
3518: Add parse_to_token_tree r=matklad a=edwin0cheng
This PR introduce a function for parsing `&str` to `tt::TokenTree`:
```rust
// Convert a string to a `TokenTree`
pub fn parse_to_token_tree(text: &str) -> Option<(tt::Subtree, TokenMap)> {
````
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
Allow trait autocompletions for unimplemented associated fn's, types,
and consts without using explicit keywords before hand (fn, type,
const).
The sequel to #3108.
3499: Resolve `Self::AssocTy` in impls r=matklad a=flodiebold
To do this we need to carry around the original resolution a bit, because `Self`
gets resolved to the actual type immediately, but you're not allowed to write
the equivalent type in a projection. (I tried just comparing the projection base
type with the impl self type, but that seemed too dirty.) This is basically how
rustc does it as well.
Fixes#3249.
Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
To do this we need to carry around the original resolution a bit, because `Self`
gets resolved to the actual type immediately, but you're not allowed to write
the equivalent type in a projection. (I tried just comparing the projection base
type with the impl self type, but that seemed too dirty.) This is basically how
rustc does it as well.
Fixes#3249.
3494: Implement include macro r=matklad a=edwin0cheng
This PR implement builtin `include` macro.
* It does not support include as expression yet.
* It doesn't consider `env!("OUT_DIR")` yet.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3483: Unfold groups with single assists into plain assists r=matklad a=SomeoneToIgnore
A follow-up of https://github.com/rust-analyzer/rust-analyzer/pull/3120/files#r378788698 , made to show more detailed label when the assist group contains a single element
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
3482: Fix regression from #3451 r=matklad a=edwin0cheng
There is a regression from #3451 such that the following code has failed to parse in raw item collecting phase:
```rust
macro_rules! with_std {
($($i:item)*) => ($(#[cfg(feature = "std")]$i)*)
}
with_std! {
mod macros;
mod others;
}
```
### Rationale
We always assume the last token of an statement will not end with a whitespace, which is true. It is because in parsing phase, we always emit `SyntaxNode` before any whitespace. Such that in various parts of RA code, we solely check the semi-colon by using `SyntaxNode::last_child_token() == ";"` .
However, in #3451, we insert some whitespaces between puncts such that we broke above assumption. This PR fixed this bug by make sure we don't add any whitespace if it is a semicolon.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
Note that `detail` was replced with `function_signature` to avoid
calling `from` on FunctionSignature twice.
I didn't add new tests because the current ones seem enough.
3429: Fix panic on eager expansion r=matklad a=edwin0cheng
When lazy expanding inside an eager macro, its *parent* file of that lazy macro call must be already exists such that a panic is occurred because that parent file is the eager macro we are processing.
This PR fix this bug by store the argument syntax node as another eager macro id for that purpose.
Personally I don't know if it is a good answer for this bug.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3428: Move reference classification to ra_ide_db r=matklad a=matklad
Lost some marks along the way :-(
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
3392: Implement concat eager macro r=matklad a=edwin0cheng
This PR implements the following things:
1. Add basic eager macro infrastructure by introducing `EagerCallId` such that the new `MacroCallId` is defined as :
```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MacroCallId {
LazyMacro(LazyMacroId),
EagerMacro(EagerMacroId),
}
```
2. Add `concat!` builtin macro.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3425: Fix a bug for single dollar sign macro r=matklad a=edwin0cheng
This PR fixed a bug to allow the following valid `macro_rules!` :
```rust
macro_rules! m {
($) => ($)
}
```
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3405: More principled approach for gotodef for field shorhand r=matklad a=matklad
Callers can now decide for themselves if they should prefer field or
local definition. By default, it's the local.
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
3385: Fix#3373 r=matklad a=flodiebold
Basically, we need to allow variables in the caller self type to unify with the
impl's declared self type. That requires some more contortions in the variable
handling. I'm looking forward to (hopefully) handling this in a cleaner way when
we switch to Chalk's types and unification code.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
3387: Type inference for slice patterns r=flodiebold a=JoshMcguigan
Fixes#3043
Notes to reviewer:
1. This only works if `expected` is `Ty::Apply`. I'm not sure of the implications of this.
1. This only works if the slice pattern only has a prefix. I think this means it doesn't work for subslice patterns, which are currently only available behind a feature flag.
Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com>