mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
fix issue 3444
This commit is contained in:
parent
05b4fc6d79
commit
7208498d54
6 changed files with 108 additions and 11 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -940,6 +940,7 @@ dependencies = [
|
||||||
name = "ra_hir"
|
name = "ra_hir"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
"either",
|
"either",
|
||||||
"itertools",
|
"itertools",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -11,6 +11,7 @@ doctest = false
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
either = "1.5.3"
|
either = "1.5.3"
|
||||||
|
arrayvec = "0.5.1"
|
||||||
|
|
||||||
itertools = "0.8.2"
|
itertools = "0.8.2"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use arrayvec::ArrayVec;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
adt::StructKind,
|
adt::StructKind,
|
||||||
|
@ -226,7 +227,11 @@ impl Module {
|
||||||
Some((name, def))
|
Some((name, def))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|(name, def)| (name.clone(), def.into()))
|
.flat_map(|(name, def)|
|
||||||
|
ScopeDef::all_items(def)
|
||||||
|
.into_iter()
|
||||||
|
.map(move |item| (name.clone(), item))
|
||||||
|
)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1288,15 +1293,38 @@ pub enum ScopeDef {
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PerNs> for ScopeDef {
|
impl ScopeDef {
|
||||||
fn from(def: PerNs) -> Self {
|
pub fn all_items(def: PerNs) -> ArrayVec<[Self; 3]> {
|
||||||
def.take_types()
|
let mut items = ArrayVec::new();
|
||||||
.or_else(|| def.take_values())
|
|
||||||
.map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
|
match (def.take_types(), def.take_values()) {
|
||||||
.or_else(|| {
|
(Some(m1), None) =>
|
||||||
def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
|
items.push(ScopeDef::ModuleDef(m1.into())),
|
||||||
})
|
(None, Some(m2)) =>
|
||||||
.unwrap_or(ScopeDef::Unknown)
|
items.push(ScopeDef::ModuleDef(m2.into())),
|
||||||
|
(Some(m1), Some(m2)) => {
|
||||||
|
// Some items, like unit structs and enum variants, are
|
||||||
|
// returned as both a type and a value. Here we want
|
||||||
|
// to de-duplicate them.
|
||||||
|
if m1 != m2 {
|
||||||
|
items.push(ScopeDef::ModuleDef(m1.into()));
|
||||||
|
items.push(ScopeDef::ModuleDef(m2.into()));
|
||||||
|
} else {
|
||||||
|
items.push(ScopeDef::ModuleDef(m1.into()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(None, None) => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(macro_def_id) = def.take_macros() {
|
||||||
|
items.push(ScopeDef::MacroDef(macro_def_id.into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if items.is_empty() {
|
||||||
|
items.push(ScopeDef::Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -344,7 +344,13 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
|
||||||
|
|
||||||
resolver.process_all_names(self.db, &mut |name, def| {
|
resolver.process_all_names(self.db, &mut |name, def| {
|
||||||
let def = match def {
|
let def = match def {
|
||||||
resolver::ScopeDef::PerNs(it) => it.into(),
|
resolver::ScopeDef::PerNs(it) => {
|
||||||
|
let items = ScopeDef::all_items(it);
|
||||||
|
for item in items {
|
||||||
|
f(name.clone(), item);
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
|
resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
|
||||||
resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
|
resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
|
||||||
resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }),
|
resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }),
|
||||||
|
|
|
@ -101,6 +101,28 @@ fn crate_def_map_super_super() {
|
||||||
"###)
|
"###)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn crate_def_map_fn_mod_same_name() {
|
||||||
|
let map = def_map(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
mod m {
|
||||||
|
pub mod z {}
|
||||||
|
pub fn z() {}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮m: t
|
||||||
|
⋮
|
||||||
|
⋮crate::m
|
||||||
|
⋮z: t v
|
||||||
|
⋮
|
||||||
|
⋮crate::m::z
|
||||||
|
"###)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bogus_paths() {
|
fn bogus_paths() {
|
||||||
covers!(bogus_paths);
|
covers!(bogus_paths);
|
||||||
|
|
|
@ -967,4 +967,43 @@ mod tests {
|
||||||
]
|
]
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_mod_share_name() {
|
||||||
|
assert_debug_snapshot!(
|
||||||
|
do_reference_completion(
|
||||||
|
r"
|
||||||
|
fn foo() {
|
||||||
|
self::m::<|>
|
||||||
|
}
|
||||||
|
|
||||||
|
mod m {
|
||||||
|
pub mod z {}
|
||||||
|
pub fn z() {}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
),
|
||||||
|
@r###"
|
||||||
|
[
|
||||||
|
CompletionItem {
|
||||||
|
label: "z",
|
||||||
|
source_range: [57; 57),
|
||||||
|
delete: [57; 57),
|
||||||
|
insert: "z",
|
||||||
|
kind: Module,
|
||||||
|
},
|
||||||
|
CompletionItem {
|
||||||
|
label: "z()",
|
||||||
|
source_range: [57; 57),
|
||||||
|
delete: [57; 57),
|
||||||
|
insert: "z()$0",
|
||||||
|
kind: Function,
|
||||||
|
lookup: "z",
|
||||||
|
detail: "pub fn z()",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue