about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-19 22:36:08 +0000
committerbors <bors@rust-lang.org>2022-07-19 22:36:08 +0000
commit30c4db10ab8033176af0ffd179348c90a2bab6df (patch)
tree08cad251e28f97b7aa802b3f391fe93b1974025d
parent7d20ff3ffbd30a89b7baa7cd996d4d60f0da6c55 (diff)
parentffb6b23c75add6192a133b15be946cc2199ed971 (diff)
downloadrust-30c4db10ab8033176af0ffd179348c90a2bab6df.tar.gz
rust-30c4db10ab8033176af0ffd179348c90a2bab6df.zip
Auto merge of #12789 - DorianListens:dscheidt/unused-param-overlapping, r=DorianListens
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
-rw-r--r--crates/ide-assists/src/handlers/remove_unused_param.rs41
1 files changed, 37 insertions, 4 deletions
diff --git a/crates/ide-assists/src/handlers/remove_unused_param.rs b/crates/ide-assists/src/handlers/remove_unused_param.rs
index 80e2ca918b9..928a5a386eb 100644
--- a/crates/ide-assists/src/handlers/remove_unused_param.rs
+++ b/crates/ide-assists/src/handlers/remove_unused_param.rs
@@ -96,12 +96,20 @@ fn process_usages(
 ) {
     let source_file = ctx.sema.parse(file_id);
     builder.edit_file(file_id);
-    for usage in references {
-        if let Some(text_range) = process_usage(&source_file, usage, arg_to_remove, is_self_present)
-        {
-            builder.delete(text_range);
+    let possible_ranges = references
+        .into_iter()
+        .filter_map(|usage| process_usage(&source_file, usage, arg_to_remove, is_self_present));
+
+    let mut ranges_to_delete: Vec<TextRange> = vec![];
+    for range in possible_ranges {
+        if !ranges_to_delete.iter().any(|it| it.contains_range(range)) {
+            ranges_to_delete.push(range)
         }
     }
+
+    for range in ranges_to_delete {
+        builder.delete(range)
+    }
 }
 
 fn process_usage(
@@ -373,4 +381,29 @@ fn main() {
 "#,
         )
     }
+
+    #[test]
+    fn nested_call() {
+        check_assist(
+            remove_unused_param,
+            r#"
+fn foo(x: i32, $0y: i32) -> i32 {
+    x
+}
+
+fn bar() {
+    foo(1, foo(2, 3));
+}
+"#,
+            r#"
+fn foo(x: i32) -> i32 {
+    x
+}
+
+fn bar() {
+    foo(1);
+}
+"#,
+        )
+    }
 }