9677: fix: Correctly classify Rename Names r=Veykril a=Veykril

bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-07-23 00:15:43 +00:00 committed by GitHub
commit 1dd1814100
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 25 deletions

View File

@ -3780,4 +3780,63 @@ fn hover_attr_path_qualifier() {
"#]],
)
}
#[test]
fn hover_rename() {
check(
r#"
use self as foo$0;
"#,
expect![[r#"
*foo*
```rust
extern crate test
```
"#]],
);
check(
r#"
mod bar {}
use bar::{self as foo$0};
"#,
expect![[r#"
*foo*
```rust
test
```
```rust
mod bar
```
"#]],
);
check(
r#"
mod bar {
use super as foo$0;
}
"#,
expect![[r#"
*foo*
```rust
extern crate test
```
"#]],
);
check(
r#"
use crate as foo$0;
"#,
expect![[r#"
*foo*
```rust
extern crate test
```
"#]],
);
}
}

View File

@ -10,8 +10,8 @@
PathResolution, Semantics, Visibility,
};
use syntax::{
ast::{self, AstNode, PathSegmentKind},
match_ast, SyntaxKind, SyntaxNode,
ast::{self, AstNode},
match_ast, SyntaxKind,
};
use crate::RootDatabase;
@ -134,29 +134,23 @@ pub fn classify(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Name
if let Some(use_tree) = it.syntax().parent().and_then(ast::UseTree::cast) {
let path = use_tree.path()?;
let path_segment = path.segment()?;
let name_ref_class = path_segment
.kind()
.and_then(|kind| {
match kind {
// The rename might be from a `self` token, so fallback to the name higher
// in the use tree.
PathSegmentKind::SelfKw => {
let use_tree = use_tree
.syntax()
.parent()
.as_ref()
// Skip over UseTreeList
.and_then(SyntaxNode::parent)
.and_then(ast::UseTree::cast)?;
let path = use_tree.path()?;
let path_segment = path.segment()?;
path_segment.name_ref()
},
PathSegmentKind::Name(name_ref) => Some(name_ref),
_ => None,
}
})
.and_then(|name_ref| NameRefClass::classify(sema, &name_ref))?;
let name_ref = path_segment.name_ref()?;
let name_ref = if name_ref.self_token().is_some() {
use_tree
.syntax()
.parent()
.as_ref()
// Skip over UseTreeList
.and_then(|it| {
let use_tree = it.parent().and_then(ast::UseTree::cast)?;
let path = use_tree.path()?;
let path_segment = path.segment()?;
path_segment.name_ref()
}).unwrap_or(name_ref)
} else {
name_ref
};
let name_ref_class = NameRefClass::classify(sema, &name_ref)?;
Some(NameClass::Definition(match name_ref_class {
NameRefClass::Definition(def) => def,