diff options
| author | bors <bors@rust-lang.org> | 2023-03-15 09:32:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-03-15 09:32:34 +0000 |
| commit | 1a318965fe3f9afa153a620d4a261e68c9589c87 (patch) | |
| tree | eb55442e0b20f25538b5925cb8ae3c5215cb3392 | |
| parent | 05f95cbb0cc2c07d3f273838c6023e7dcfd0c0d3 (diff) | |
| parent | 01bf0725b146b0cf71c21ec8452067f9bd3de1d8 (diff) | |
| download | rust-1a318965fe3f9afa153a620d4a261e68c9589c87.tar.gz rust-1a318965fe3f9afa153a620d4a261e68c9589c87.zip | |
Auto merge of #14353 - lowr:fix/inline-call-bad-ast, r=Veykril
fix: don't replace `SyntaxToken` with `SyntaxNode` Fixes #14339 When we inline method calls, we replace the `self` parameter with a local variable `this`. We have been replacing the `self` **tokens** with `NameRef` **nodes**, which makes the AST malformed. This leads to crash when we apply path transformation after the replacement (which only takes place when the method is generic and such scenario was not tested).
| -rw-r--r-- | crates/ide-assists/src/handlers/inline_call.rs | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs index 5ac18727c19..28d815e81b4 100644 --- a/crates/ide-assists/src/handlers/inline_call.rs +++ b/crates/ide-assists/src/handlers/inline_call.rs @@ -363,10 +363,10 @@ fn inline( .collect(); if function.self_param(sema.db).is_some() { - let this = || make::name_ref("this").syntax().clone_for_update(); + let this = || make::name_ref("this").syntax().clone_for_update().first_token().unwrap(); if let Some(self_local) = params[0].2.as_local(sema.db) { usages_for_locals(self_local) - .flat_map(|FileReference { name, range, .. }| match name { + .filter_map(|FileReference { name, range, .. }| match name { ast::NameLike::NameRef(_) => Some(body.syntax().covering_element(range)), _ => None, }) @@ -691,6 +691,42 @@ fn main() { } #[test] + fn generic_method_by_ref() { + check_assist( + inline_call, + r#" +struct Foo(u32); + +impl Foo { + fn add<T>(&self, a: u32) -> Self { + Foo(self.0 + a) + } +} + +fn main() { + let x = Foo(3).add$0::<usize>(2); +} +"#, + r#" +struct Foo(u32); + +impl Foo { + fn add<T>(&self, a: u32) -> Self { + Foo(self.0 + a) + } +} + +fn main() { + let x = { + let ref this = Foo(3); + Foo(this.0 + 2) + }; +} +"#, + ); + } + + #[test] fn method_by_ref_mut() { check_assist( inline_call, |
