about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-15 09:32:34 +0000
committerbors <bors@rust-lang.org>2023-03-15 09:32:34 +0000
commit1a318965fe3f9afa153a620d4a261e68c9589c87 (patch)
treeeb55442e0b20f25538b5925cb8ae3c5215cb3392
parent05f95cbb0cc2c07d3f273838c6023e7dcfd0c0d3 (diff)
parent01bf0725b146b0cf71c21ec8452067f9bd3de1d8 (diff)
downloadrust-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.rs40
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,