mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Merge #316
316: Fix handling of nested self in paths r=matklad a=DJMcNab See https://github.com/rust-analyzer/rust-analyzer/issues/231#issuecomment-442449505. Co-authored-by: DJMcNab <36049421+djmcnab@users.noreply.github.com>
This commit is contained in:
commit
e4d0930d9c
3 changed files with 39 additions and 3 deletions
|
@ -43,6 +43,25 @@ fn item_map_smoke_test() {
|
||||||
assert!(resolution.def_id.is_some());
|
assert!(resolution.def_id.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_self() {
|
||||||
|
let (item_map, module_id) = item_map(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
mod foo;
|
||||||
|
use crate::foo::bar::Baz::{self};
|
||||||
|
<|>
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub mod bar;
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
let name = SmolStr::from("Baz");
|
||||||
|
let resolution = &item_map.per_module[&module_id].items[&name];
|
||||||
|
assert!(resolution.def_id.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn item_map_across_crates() {
|
fn item_map_across_crates() {
|
||||||
let (mut db, sr) = MockDatabase::with_files(
|
let (mut db, sr) = MockDatabase::with_files(
|
||||||
|
|
|
@ -76,17 +76,32 @@ fn expand_use_tree(
|
||||||
) {
|
) {
|
||||||
if let Some(use_tree_list) = tree.use_tree_list() {
|
if let Some(use_tree_list) = tree.use_tree_list() {
|
||||||
let prefix = match tree.path() {
|
let prefix = match tree.path() {
|
||||||
|
// E.g. use something::{{{inner}}};
|
||||||
None => prefix,
|
None => prefix,
|
||||||
|
// E.g. `use something::{inner}` (prefix is `None`, path is `something`)
|
||||||
|
// or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
|
||||||
Some(path) => match convert_path(prefix, path) {
|
Some(path) => match convert_path(prefix, path) {
|
||||||
Some(it) => Some(it),
|
Some(it) => Some(it),
|
||||||
None => return, // TODO: report errors somewhere
|
None => return, // TODO: report errors somewhere
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
for tree in use_tree_list.use_trees() {
|
for child_tree in use_tree_list.use_trees() {
|
||||||
expand_use_tree(prefix.clone(), tree, cb);
|
expand_use_tree(prefix.clone(), child_tree, cb);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Some(ast_path) = tree.path() {
|
if let Some(ast_path) = tree.path() {
|
||||||
|
// Handle self in a path.
|
||||||
|
// E.g. `use something::{self, <...>}`
|
||||||
|
if ast_path.qualifier().is_none() {
|
||||||
|
if let Some(segment) = ast_path.segment() {
|
||||||
|
if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
|
||||||
|
if let Some(prefix) = prefix {
|
||||||
|
cb(prefix, Some(segment.syntax().range()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if let Some(path) = convert_path(prefix, ast_path) {
|
if let Some(path) = convert_path(prefix, ast_path) {
|
||||||
let range = if tree.has_star() {
|
let range = if tree.has_star() {
|
||||||
None
|
None
|
||||||
|
@ -96,6 +111,8 @@ fn expand_use_tree(
|
||||||
};
|
};
|
||||||
cb(path, range)
|
cb(path, range)
|
||||||
}
|
}
|
||||||
|
// TODO: report errors somewhere
|
||||||
|
// We get here if we do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,7 +284,7 @@ impl<'a> IfExpr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum PathSegmentKind<'a> {
|
pub enum PathSegmentKind<'a> {
|
||||||
Name(NameRef<'a>),
|
Name(NameRef<'a>),
|
||||||
SelfKw,
|
SelfKw,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue