Skip to content

Commit 2e0b7b0

Browse files
bors[bot]matklad
andauthored
Merge #4057
4057: Fix panic in split_imports assist r=matklad a=matklad The fix is admittedly quit literally just papering over. Long-term, I see two more principled approaches: * we switch to a fully tree-based impl, without parse . to_string step; with this approach, there shouldn't be any panics. The results might be nonsensical, but so was the original input. * we preserve the invariant that re-parsing constructed node is an identity, and make all the `make_xxx` method return an `Option`. closes #4044 bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 90f8378 + 8a04372 commit 2e0b7b0

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

crates/ra_assists/src/handlers/split_import.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub(crate) fn split_import(ctx: AssistCtx) -> Option<Assist> {
3737

3838
#[cfg(test)]
3939
mod tests {
40-
use crate::helpers::{check_assist, check_assist_target};
40+
use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target};
4141

4242
use super::*;
4343

@@ -63,4 +63,9 @@ mod tests {
6363
fn split_import_target() {
6464
check_assist_target(split_import, "use crate::<|>db::{RootDatabase, FileSymbol}", "::");
6565
}
66+
67+
#[test]
68+
fn issue4044() {
69+
check_assist_not_applicable(split_import, "use crate::<|>:::self;")
70+
}
6671
}

crates/ra_syntax/src/algo.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use ra_text_edit::TextEditBuilder;
1010
use rustc_hash::FxHashMap;
1111

1212
use crate::{
13-
AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken,
14-
TextRange, TextUnit,
13+
AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
14+
SyntaxToken, TextRange, TextUnit,
1515
};
1616

1717
/// Returns ancestors of the node at the offset, sorted by length. This should
@@ -90,6 +90,10 @@ pub fn neighbor<T: AstNode>(me: &T, direction: Direction) -> Option<T> {
9090
me.syntax().siblings(direction).skip(1).find_map(T::cast)
9191
}
9292

93+
pub fn has_errors(node: &SyntaxNode) -> bool {
94+
node.children().any(|it| it.kind() == SyntaxKind::ERROR)
95+
}
96+
9397
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
9498
pub enum InsertPosition<T> {
9599
First,

crates/ra_syntax/src/ast/edit.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,11 @@ impl ast::UseTree {
307307

308308
fn split_path_prefix(prefix: &ast::Path) -> Option<ast::Path> {
309309
let parent = prefix.parent_path()?;
310-
let mut res = make::path_unqualified(parent.segment()?);
310+
let segment = parent.segment()?;
311+
if algo::has_errors(segment.syntax()) {
312+
return None;
313+
}
314+
let mut res = make::path_unqualified(segment);
311315
for p in iter::successors(parent.parent_path(), |it| it.parent_path()) {
312316
res = make::path_qualified(res, p.segment()?);
313317
}

0 commit comments

Comments
 (0)