Skip to content

Commit ddd59b9

Browse files
committed
fix(extract_module): nearby imports deletion causing panic
1 parent 57861bd commit ddd59b9

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

crates/ide-assists/src/handlers/extract_module.rs

+57-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext) -> Option<(
180180
}
181181

182182
for import_path_text_range in import_paths_to_be_removed {
183+
println!("Deleting : {:?}", import_path_text_range);
183184
builder.delete(import_path_text_range);
184185
}
185186

@@ -439,7 +440,28 @@ impl Module {
439440
ctx,
440441
)
441442
{
442-
import_paths_to_be_removed.push(import_path);
443+
if import_paths_to_be_removed.len() > 0 {
444+
// Text ranges recieved here for imports are extended to the
445+
// next/previous comma which can cause intersections among them
446+
// and later deletion of these can cause panics similar
447+
// to reported in #11766. So to mitigate it, we
448+
// check for intersection between all current members
449+
// and if it exists we combine both text ranges into
450+
// one
451+
for i in 0..import_paths_to_be_removed.len() {
452+
if let Some(_) =
453+
import_paths_to_be_removed[i].intersect(import_path)
454+
{
455+
import_paths_to_be_removed[i] =
456+
import_paths_to_be_removed[i]
457+
.cover(import_path);
458+
} else {
459+
import_paths_to_be_removed.push(import_path);
460+
}
461+
}
462+
} else {
463+
import_paths_to_be_removed.push(import_path);
464+
}
443465
}
444466
}
445467
}
@@ -1495,4 +1517,38 @@ mod modname {
14951517
",
14961518
)
14971519
}
1520+
1521+
#[test]
1522+
fn test_issue_11766() {
1523+
//https://github.com/rust-lang/rust-analyzer/issues/11766
1524+
check_assist(
1525+
extract_module,
1526+
r"
1527+
mod x {
1528+
pub struct Foo;
1529+
pub struct Bar;
1530+
}
1531+
1532+
use x::{Bar, Foo};
1533+
1534+
$0type A = (Foo, Bar);$0
1535+
",
1536+
r"
1537+
mod x {
1538+
pub struct Foo;
1539+
pub struct Bar;
1540+
}
1541+
1542+
use x::{};
1543+
1544+
mod modname {
1545+
use super::x::Bar;
1546+
1547+
use super::x::Foo;
1548+
1549+
pub(crate) type A = (Foo, Bar);
1550+
}
1551+
",
1552+
)
1553+
}
14981554
}

0 commit comments

Comments
 (0)