Skip to content

Commit 6e8896b

Browse files
committed
fix: Implement default member to resolve IdentPat
1 parent d307bc6 commit 6e8896b

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,6 +2418,53 @@ pub struct MyStruct;
24182418
24192419
impl other_file_2::Trait for MyStruct {
24202420
$0type Iter;
2421+
}"#,
2422+
);
2423+
}
2424+
2425+
#[test]
2426+
fn test_qualify_ident_pat_in_default_members() {
2427+
check_assist(
2428+
add_missing_default_members,
2429+
r#"
2430+
//- /lib.rs crate:b new_source_root:library
2431+
pub enum State {
2432+
Active,
2433+
Inactive,
2434+
}
2435+
2436+
pub trait Checker {
2437+
fn check(&self) -> State;
2438+
2439+
fn is_active(&self) -> bool {
2440+
match self.check() {
2441+
State::Active => true,
2442+
State::Inactive => false,
2443+
}
2444+
}
2445+
}
2446+
//- /main.rs crate:a deps:b
2447+
struct MyChecker;
2448+
2449+
impl b::Checker for MyChecker {
2450+
fn check(&self) -> lib::State {
2451+
todo!();
2452+
}$0
2453+
}"#,
2454+
r#"
2455+
struct MyChecker;
2456+
2457+
impl b::Checker for MyChecker {
2458+
fn check(&self) -> lib::State {
2459+
todo!();
2460+
}
2461+
2462+
$0fn is_active(&self) -> bool {
2463+
match self.check() {
2464+
b::State::Active => true,
2465+
b::State::Inactive => false,
2466+
}
2467+
}
24212468
}"#,
24222469
);
24232470
}

crates/ide-db/src/path_transform.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_hash::FxHashMap;
1111
use span::Edition;
1212
use syntax::{
1313
NodeOrToken, SyntaxNode,
14-
ast::{self, AstNode, HasGenericArgs, make},
14+
ast::{self, AstNode, HasGenericArgs, HasName, make},
1515
syntax_editor::{self, SyntaxEditor},
1616
};
1717

@@ -326,13 +326,34 @@ impl Ctx<'_> {
326326
}
327327
result
328328
}
329+
fn find_child_ident_pats(root_path: &SyntaxNode) -> Vec<ast::IdentPat> {
330+
let mut result = Vec::new();
331+
for child in root_path.children() {
332+
if let Some(child_ident_pat) = ast::IdentPat::cast(child.clone()) {
333+
result.push(child_ident_pat);
334+
} else {
335+
result.extend(find_child_ident_pats(&child));
336+
}
337+
}
338+
result
339+
}
340+
329341
let root_path = path.clone_subtree();
342+
330343
let result = find_child_paths(&root_path);
331344
let mut editor = SyntaxEditor::new(root_path.clone());
332345
for sub_path in result {
333346
let new = self.transform_path(sub_path.syntax());
334347
editor.replace(sub_path.syntax(), new);
335348
}
349+
350+
let ident_result = find_child_ident_pats(&root_path);
351+
for ident_pat in ident_result {
352+
if let Some(new) = self.transform_ident_pat(&ident_pat) {
353+
editor.replace(ident_pat.syntax(), new.syntax());
354+
}
355+
}
356+
336357
let update_sub_item = editor.finish().new_root().clone().clone_subtree();
337358
let item = find_child_paths(&update_sub_item);
338359
let mut editor = SyntaxEditor::new(update_sub_item);
@@ -515,6 +536,29 @@ impl Ctx<'_> {
515536
}
516537
Some(())
517538
}
539+
540+
fn transform_ident_pat(&self, ident_pat: &ast::IdentPat) -> Option<ast::Path> {
541+
let name = ident_pat.name()?;
542+
543+
let temp_path = make::path_from_text(&name.text());
544+
545+
let resolution = self.source_scope.speculative_resolve(&temp_path)?;
546+
547+
match resolution {
548+
hir::PathResolution::Def(def) if def.as_assoc_item(self.source_scope.db).is_none() => {
549+
let cfg = ImportPathConfig {
550+
prefer_no_std: false,
551+
prefer_prelude: true,
552+
prefer_absolute: false,
553+
allow_unstable: true,
554+
};
555+
let found_path = self.target_module.find_path(self.source_scope.db, def, cfg)?;
556+
let res = mod_path_to_ast(&found_path, self.target_edition).clone_for_update();
557+
Some(res)
558+
}
559+
_ => None,
560+
}
561+
}
518562
}
519563

520564
// FIXME: It would probably be nicer if we could get this via HIR (i.e. get the

0 commit comments

Comments
 (0)