Otherwise, fall back to the multi ABI scheme, except in testing, where
it becomes a hard error.
This should make it possible to use a rustup-provided rust-analyzer with
proc macro dylibs compiled by older rustcs, and it'll also catch changes
to the format of `rustc --version` or the `.rustc` section that would
make them impossible to compare for equality.
Add PROC_MACRO_TEST_TOOLCHAIN environment variable
This allows overriding the toolchain used to run `proc-macro-srv` tests.
---
Sample usage.
Testing the current ABI (variable unset/empty):
```shell
amos@tails ~/bearcove/rust-analyzer/crates/proc-macro-srv proc-macro-test-toolchain*
❯ PROC_MACRO_TEST_TOOLCHAIN="" cargo test --quiet
running 16 tests
................
test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
```
Testing an older ABI:
```shell
amos@tails ~/bearcove/rust-analyzer/crates/proc-macro-srv proc-macro-test-toolchain*
❯ PROC_MACRO_TEST_TOOLCHAIN="1.58" cargo test --quiet
running 16 tests
................
test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
```
Testing current nightly ABI:
```shell
❯ rustc +nightly --version
rustc 1.64.0-nightly (f8588549c 2022-07-18)
❯ PROC_MACRO_TEST_TOOLCHAIN="nightly" cargo test --quiet
running 16 tests
................
test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
```
Testing future ABI (`rust-lang/rust` master):
```shell
amos@tails ~/bearcove/rust-analyzer/crates/proc-macro-srv proc-macro-test-toolchain
❯ PROC_MACRO_TEST_TOOLCHAIN="stage1" cargo test --quiet
running 16 tests
..........thread '<unnamed>' panicked at 'range end index 216221164920373249 out of range for slice of length 18', library/core/src/slice/index.rs:73:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
....F.
failures:
---- tests::test_fn_like_macro2 stdout ----
thread 'tests::test_fn_like_macro2' panicked at 'called `Result::unwrap()` on an `Err` value: "range end index 216221164920373249 out of range for slice of length 18"', crates/proc-macro-srv/src/tests/utils.rs:38:83
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::test_fn_like_macro2
test result: FAILED. 15 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass '--lib
```
---
Tagging `@jonas-schievink:` this might be helpful when updating versioned ABIs later on.
Add proc-macro-srv integration test that clones literals
This exercises some of the upcoming proc_macro bridge changes. It should also pass for all supported ABIs, with the older-style bridge.
This changed is tracked in:
* https://github.com/rust-lang/rust-analyzer/issues/12818
Building it in-place fails in rust CI because the source directory
is read-only. This changes `proc-macro-test`'s build script to first
copy `imp` under `OUT_DIR` (which is read-write).
It also prints stdout/stderr for the nested cargo invocation, should
it fail. (I've seen failures in rust CI that I couldn't explain, and
when they take 25 minutes to reproduce, you want to have that info)
Remove `check_merge_commits` test
Due to the way "git subtree" works, the `check_merge_commits` test _will_ find merge commits and fail, so we simply skip it.
This changed is tracked in:
* https://github.com/rust-lang/rust-analyzer/issues/12818
Maintainer impact: none
Rationale: Merge commits will probably end up in
`rust-lang/rust-analyzer` when doing "rust=>ra" syncs anyway.
It could be changed to only check for merge commits in non-sync PRs,
but it's "probably not worth the hassle"
This adds an `in-rust-tree` feature that will be enabled when
rust-analyzer is built from `rust-lang/rust`. Due to the way
"git subtree" works, that test _will_ find merge commits and
fail, so we simply skip it.
fix: Insert `pub(crate)` after doc comments and attribute macros
Fixes#12790
Original behavior was to insert `pub(crate)` at the `first_child_or_token`, which for an item with a comment or attribute macro, would put the visibility marker before the comment or macro, instead of after.
This merge request alters the call to find the node with appropriate `SyntaxKind` in the `children_or_tokens`. It also adds a test case to the module to verify the behavior. Test case verifies function, module, records, enum, impl, trait, and type cases.
fix: Prevent panic in Remove Unused Parameter assist
Instead of calling `builder.delete` for every text range we find with
`process_usage`, we now ensure that the ranges do not overlap before removing
them. If a range is fully contained by a prior one, it is dropped.
fixes#12784
chore: change str_ref_to_string to str_ref_to_owned
`ToString` is implemented by many different types than `&str`, and represents a serialization into string data. The fact that said data is returned as owned, is an implementation detail resulting from the lack of a parameter for a pre-allocated buffer.
If merely copying borrowed string data to owned string data is all that is desired, `ToOwned` is a much better choice, because if the user later refactors the code such that the input is no longer an `&str`, then they will get a compiler error instead of a mysterious runtime-behavioral change.
Instead of calling `builder.delete` for every text range we find with
`process_usage`, we now ensure that the ranges do not overlap before removing
them. If a range is fully contained by a prior one, it is dropped.
fixes#12784
Add simple support for completion item details
Supercedes https://github.com/rust-lang/rust-analyzer/pull/9891
This doesn't yet really implement anything new, it just adds the scaffolding for the protocol conversion
fix: make file watcher config a drop-down (and clarify the options)
Fixes https://github.com/rust-lang/rust-analyzer/issues/12794
Also renames "notify" to "server", since that's clearer ("notify" is still accepted for compatibility).
Fix extract variable assist for subexpression in mutable borrow
This checks if the expression is in a mutable borrow and if so makes the extracted variable `mut`.
Closes#12786
ToString is implemented by many different types than &str, and
represents a serialization into string data. The fact that said data is
returned as owned, is an implementation detail.
If merely copying borrowed string data to owned string data is all that
is desired, ToOwned is a much better choice, because if the user later
refactors the code such that the input is no longer an `&str`, then they
will get a compiler error instead of a mysterious change-in-behavior.
internal: Record all macro definitions in ItemScope
Fixes https://github.com/rust-lang/rust-analyzer/issues/12100
Doesn't resolve the shadowing issues though, fixing those is gonna be really tricky I believe unless we can come up with a nice scheme to "order" item tree items (using syntax ranges and file ids would be a pain and also a bad idea since that'll require us to potentially reparse files in collection).
Automatically instaciate trivially instaciable structs in "Generate new" and "Fill struct fields"
As proposed in #12535 this PR changes the "Generate new" and "Fill struct fields" assist/diagnostic to instanciate structs with no fields and enums with a single empty variant.
For example:
```rust
pub enum Bar {
Bar {},
}
struct Foo<T> {
a: usize,
bar: Bar,
_phantom: std::marker::PhantomData<T>,
}
impl<T> Foo<T> {
/* generate new */
fn random() -> Self {
Self { /* Fill struct fields */ }
}
}
```
was previously:
```rust
impl<T> Foo<T> {
fn new(a: usize, bar: Bar, _phantom: std::marker::PhantomData<T>) -> Self {
Self { a, bar, _phantom }
}
fn random() -> Self {
Self {
a: todo!(),
bar: todo!(),
_phantom: todo!(),
}
}
}
```
and is now:
```rust
impl<T> Foo<T> {
fn new(a: usize) -> Self {
Self {
a,
bar: Bar::Bar {},
_phantom: std::marker::PhantomData
}
}
fn random() -> Self {
Self {
a: todo!(),
bar: Bar::Bar {},
_phantom: std::marker::PhantomData,
}
}
}
```
I'd be happy about any suggestions.
## TODO
- [x] deduplicate `use_trivial_constructor` (unclear how to do as it's used in two separate crates)
- [x] write tests
Closes#12535
- allow appending tokens after a token, not just a node
- allow inserting delimiters (and remove them again)
- fix up `if {}` and `if` without anything following
fix: Support generics in extract_function assist
This change attempts to resolve issue #7636: Extract into Function does not
create a generic function with constraints when extracting generic code.
In `FunctionBody::analyze_container`, we now traverse the `ancestors` in search
of `AnyHasGenericParams`, and attach any `GenericParamList`s and `WhereClause`s
we find to the `ContainerInfo`.
Later, in `format_function`, we collect all the `GenericParam`s and
`WherePred`s from the container, and filter them to keep only types matching
`TypeParam`s used within the newly extracted function body or param list. We
can then include the new `GenericParamList` and `WhereClause` in the new
function definition.
This change only impacts `TypeParam`s. `LifetimeParam`s and `ConstParam`s are
out of scope for this change.
I've never contributed to this project before, but I did try to follow the style guide. I believe that this change represents an improvement over the status quo, but I think it's also fair to argue that it doesn't fully "fix" the linked issue. I'm totally open to merging this as is, or going further to try to make a more complete solution. Also: if there are other unit or integration tests I should add, please let me know where to look!
This change attempts to resolve issue #7636: Extract into Function does not
create a generic function with constraints when extracting generic code.
In `FunctionBody::analyze_container`, we now traverse the `ancestors` in search
of `AnyHasGenericParams`, and attach any `GenericParamList`s and `WhereClause`s
we find to the `ContainerInfo`.
Later, in `format_function`, we collect all the `GenericParam`s and
`WherePred`s from the container, and filter them to keep only types matching
`TypeParam`s used within the newly extracted function body or param list. We
can then include the new `GenericParamList` and `WhereClause` in the new
function definition.
This change only impacts `TypeParam`s. `LifetimeParam`s and `ConstParam`s are
out of scope for this change.
Fix obsolete config keys
The config keys were drastically reorganized by #12010, but the docs don't reflect the updates, causing inconsistency and confusion. I checked for such obsolete configuration keys and updated to the new one. For reproducibility, I attach a small shell script that I used to examine the old keys. Now the script only detects `cargoExtraArgs` and `overrideCargo`, which originates from other type definition in the code but not from the configuration.
<details><summary>script</summary>
```bash
echo "allowMergingIntoGlobImports
exprFillDefault
importEnforceGranularity
importGranularity
importMergeBehavior
importMergeBehaviour
importGroup
importPrefix
warmup
loadOutDirsFromCheck
runBuildScripts
runBuildScriptsCommand
useRustcWrapperForBuildScripts
enableExperimental
procAttrMacros
breakPoints
exitPoints
yieldPoints
linksInHover
linksInHover
gotoTypeDef
chainingHints
closureReturnTypeHints
hideNamedConstructorHints
parameterHints
reborrowHints
typeHints
lruCapacity
cargoExtraArgs
overrideCargo
rustcSource
enableRangeFormatting
assist\.allowMergingIntoGlobImports
assist\.exprFillDefault
assist\.importEnforceGranularity
assist\.importGranularity
assist\.importMergeBehavior
assist\.importMergeBehaviour
assist\.importGroup
assist\.importPrefix
primeCaches\.enable
cache\.warmup
cargo\.loadOutDirsFromCheck
cargo\.runBuildScripts
cargo\.runBuildScriptsCommand
cargo\.useRustcWrapperForBuildScripts
completion\.snippets
diagnostics\.enableExperimental
experimental\.procAttrMacros
highlighting\.strings
highlightRelated\.breakPoints
highlightRelated\.exitPoints
highlightRelated\.yieldPoints
highlightRelated\.references
hover\.documentation
hover\.linksInHover
hoverActions\.linksInHover
hoverActions\.debug
hoverActions\.enable
hoverActions\.gotoTypeDef
hoverActions\.implementations
hoverActions\.references
hoverActions\.run
inlayHints\.chainingHints
inlayHints\.closureReturnTypeHints
inlayHints\.hideNamedConstructorHints
inlayHints\.parameterHints
inlayHints\.reborrowHints
inlayHints\.typeHints
lruCapacity
runnables\.cargoExtraArgs
runnables\.overrideCargo
rustcSource
rustfmt\.enableRangeFormatting
allFeatures
addCallArgumentSnippets
addCallParenthesis
callInfo\.full
cargo\.allFeatures
checkOnSave\.allFeatures
completion\.addCallArgumentSnippets
completion\.addCallParenthesis" | while read -r pattern
do
rg '\b'$pattern'\b([^.]|$)' . -g "!crates/rust-analyzer/src/config/patch_old_style.rs" -g "!editors/code/src/config.ts" -g "!a.sh" --no-heading --color=always --line-number
done
exit
excluded
# debug
# enable
# run
# implementations
# references
# documentation
# references
# snippets
# strings
# full
```
</details>