mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 20:09:19 +00:00
Implement basic support for Associated Methods and Constants
This is done in `infer_path_expr`. When `Resolver::resolve_path` returns `PartiallyResolved`, we use the returned `Resolution` together with the given `segment_index` to check if we can find something matching the segment at segment_index in the impls for that particular type.
This commit is contained in:
parent
c84561bb62
commit
816971ebc9
13 changed files with 430 additions and 50 deletions
|
@ -32,6 +32,32 @@ pub(crate) struct ExprScope {
|
|||
scope_id: ScopeId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PathResult {
|
||||
/// Path was fully resolved
|
||||
FullyResolved(PerNs<Resolution>),
|
||||
/// Path was partially resolved, first element contains the resolution
|
||||
/// second contains the index in the Path.segments which we were unable to resolve
|
||||
PartiallyResolved(PerNs<Resolution>, usize),
|
||||
}
|
||||
|
||||
impl PathResult {
|
||||
pub fn segment_index(&self) -> Option<usize> {
|
||||
match self {
|
||||
PathResult::FullyResolved(_) => None,
|
||||
PathResult::PartiallyResolved(_, ref i) => Some(*i),
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes `PathResult` and returns the contained `PerNs<Resolution>`
|
||||
pub fn into_per_ns(self) -> PerNs<Resolution> {
|
||||
match self {
|
||||
PathResult::FullyResolved(def) => def,
|
||||
PathResult::PartiallyResolved(def, _) => def,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum Scope {
|
||||
/// All the items and imported names of a module
|
||||
|
@ -67,18 +93,26 @@ impl Resolver {
|
|||
resolution
|
||||
}
|
||||
|
||||
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> {
|
||||
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PathResult {
|
||||
use self::PathResult::*;
|
||||
if let Some(name) = path.as_ident() {
|
||||
self.resolve_name(db, name)
|
||||
FullyResolved(self.resolve_name(db, name))
|
||||
} else if path.is_self() {
|
||||
self.resolve_name(db, &Name::self_param())
|
||||
FullyResolved(self.resolve_name(db, &Name::self_param()))
|
||||
} else {
|
||||
let (item_map, module) = match self.module() {
|
||||
Some(m) => m,
|
||||
_ => return PerNs::none(),
|
||||
_ => return FullyResolved(PerNs::none()),
|
||||
};
|
||||
let module_res = item_map.resolve_path(db, module, path);
|
||||
module_res.map(Resolution::Def)
|
||||
let (module_res, segment_index) = item_map.resolve_path(db, module, path);
|
||||
|
||||
let def = module_res.map(Resolution::Def);
|
||||
|
||||
if let Some(index) = segment_index {
|
||||
PartiallyResolved(def, index)
|
||||
} else {
|
||||
FullyResolved(def)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue