mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-13 09:11:51 +00:00
fix: Implement default member to resolve IdentPat
This commit is contained in:
parent
d307bc614e
commit
8ab683759e
2 changed files with 102 additions and 8 deletions
|
|
@ -2418,6 +2418,55 @@ pub struct MyStruct;
|
||||||
|
|
||||||
impl other_file_2::Trait for MyStruct {
|
impl other_file_2::Trait for MyStruct {
|
||||||
$0type Iter;
|
$0type Iter;
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_qualify_ident_pat_in_default_members() {
|
||||||
|
check_assist(
|
||||||
|
add_missing_default_members,
|
||||||
|
r#"
|
||||||
|
//- /lib.rs crate:b new_source_root:library
|
||||||
|
pub enum State {
|
||||||
|
Active,
|
||||||
|
Inactive,
|
||||||
|
}
|
||||||
|
|
||||||
|
use State::*;
|
||||||
|
|
||||||
|
pub trait Checker {
|
||||||
|
fn check(&self) -> State;
|
||||||
|
|
||||||
|
fn is_active(&self) -> bool {
|
||||||
|
match self.check() {
|
||||||
|
Active => true,
|
||||||
|
Inactive => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//- /main.rs crate:a deps:b
|
||||||
|
struct MyChecker;
|
||||||
|
|
||||||
|
impl b::Checker for MyChecker {
|
||||||
|
fn check(&self) -> b::State {
|
||||||
|
todo!();
|
||||||
|
}$0
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
struct MyChecker;
|
||||||
|
|
||||||
|
impl b::Checker for MyChecker {
|
||||||
|
fn check(&self) -> b::State {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
$0fn is_active(&self) -> bool {
|
||||||
|
match self.check() {
|
||||||
|
b::State::Active => true,
|
||||||
|
b::State::Inactive => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}"#,
|
}"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use rustc_hash::FxHashMap;
|
||||||
use span::Edition;
|
use span::Edition;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
NodeOrToken, SyntaxNode,
|
NodeOrToken, SyntaxNode,
|
||||||
ast::{self, AstNode, HasGenericArgs, make},
|
ast::{self, AstNode, HasGenericArgs, HasName, make},
|
||||||
syntax_editor::{self, SyntaxEditor},
|
syntax_editor::{self, SyntaxEditor},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -315,32 +315,49 @@ impl Ctx<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_path(&self, path: &SyntaxNode) -> SyntaxNode {
|
fn transform_path(&self, path: &SyntaxNode) -> SyntaxNode {
|
||||||
fn find_child_paths(root_path: &SyntaxNode) -> Vec<ast::Path> {
|
fn find_child_paths_and_ident_pats(
|
||||||
let mut result = Vec::new();
|
root_path: &SyntaxNode,
|
||||||
|
) -> Vec<Either<ast::Path, ast::IdentPat>> {
|
||||||
|
let mut result: Vec<Either<ast::Path, ast::IdentPat>> = Vec::new();
|
||||||
for child in root_path.children() {
|
for child in root_path.children() {
|
||||||
if let Some(child_path) = ast::Path::cast(child.clone()) {
|
if let Some(child_path) = ast::Path::cast(child.clone()) {
|
||||||
result.push(child_path);
|
result.push(either::Left(child_path));
|
||||||
|
} else if let Some(child_ident_pat) = ast::IdentPat::cast(child.clone()) {
|
||||||
|
result.push(either::Right(child_ident_pat));
|
||||||
} else {
|
} else {
|
||||||
result.extend(find_child_paths(&child));
|
result.extend(find_child_paths_and_ident_pats(&child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
let root_path = path.clone_subtree();
|
let root_path = path.clone_subtree();
|
||||||
let result = find_child_paths(&root_path);
|
|
||||||
|
let result = find_child_paths_and_ident_pats(&root_path);
|
||||||
let mut editor = SyntaxEditor::new(root_path.clone());
|
let mut editor = SyntaxEditor::new(root_path.clone());
|
||||||
for sub_path in result {
|
for sub_path in result {
|
||||||
let new = self.transform_path(sub_path.syntax());
|
let new = self.transform_path(sub_path.syntax());
|
||||||
editor.replace(sub_path.syntax(), new);
|
editor.replace(sub_path.syntax(), new);
|
||||||
}
|
}
|
||||||
|
|
||||||
let update_sub_item = editor.finish().new_root().clone().clone_subtree();
|
let update_sub_item = editor.finish().new_root().clone().clone_subtree();
|
||||||
let item = find_child_paths(&update_sub_item);
|
let item = find_child_paths_and_ident_pats(&update_sub_item);
|
||||||
let mut editor = SyntaxEditor::new(update_sub_item);
|
let mut editor = SyntaxEditor::new(update_sub_item);
|
||||||
for sub_path in item {
|
for sub_path in item {
|
||||||
self.transform_path_(&mut editor, &sub_path);
|
self.transform_path_or_ident_pat(&mut editor, &sub_path);
|
||||||
}
|
}
|
||||||
editor.finish().new_root().clone()
|
editor.finish().new_root().clone()
|
||||||
}
|
}
|
||||||
|
fn transform_path_or_ident_pat(
|
||||||
|
&self,
|
||||||
|
editor: &mut SyntaxEditor,
|
||||||
|
item: &Either<ast::Path, ast::IdentPat>,
|
||||||
|
) -> Option<()> {
|
||||||
|
match item {
|
||||||
|
Either::Left(path) => self.transform_path_(editor, path),
|
||||||
|
Either::Right(ident_pat) => self.transform_ident_pat(editor, ident_pat),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn transform_path_(&self, editor: &mut SyntaxEditor, path: &ast::Path) -> Option<()> {
|
fn transform_path_(&self, editor: &mut SyntaxEditor, path: &ast::Path) -> Option<()> {
|
||||||
if path.qualifier().is_some() {
|
if path.qualifier().is_some() {
|
||||||
|
|
@ -515,6 +532,34 @@ impl Ctx<'_> {
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transform_ident_pat(
|
||||||
|
&self,
|
||||||
|
editor: &mut SyntaxEditor,
|
||||||
|
ident_pat: &ast::IdentPat,
|
||||||
|
) -> Option<()> {
|
||||||
|
let name = ident_pat.name()?;
|
||||||
|
|
||||||
|
let temp_path = make::path_from_text(&name.text());
|
||||||
|
|
||||||
|
let resolution = self.source_scope.speculative_resolve(&temp_path)?;
|
||||||
|
|
||||||
|
match resolution {
|
||||||
|
hir::PathResolution::Def(def) if def.as_assoc_item(self.source_scope.db).is_none() => {
|
||||||
|
let cfg = ImportPathConfig {
|
||||||
|
prefer_no_std: false,
|
||||||
|
prefer_prelude: true,
|
||||||
|
prefer_absolute: false,
|
||||||
|
allow_unstable: true,
|
||||||
|
};
|
||||||
|
let found_path = self.target_module.find_path(self.source_scope.db, def, cfg)?;
|
||||||
|
let res = mod_path_to_ast(&found_path, self.target_edition).clone_for_update();
|
||||||
|
editor.replace(ident_pat.syntax(), res.syntax());
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: It would probably be nicer if we could get this via HIR (i.e. get the
|
// FIXME: It would probably be nicer if we could get this via HIR (i.e. get the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue