mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Implement type inference for enum variants
This commit is contained in:
parent
aca14c591f
commit
978de5cf8b
12 changed files with 218 additions and 45 deletions
|
@ -13,6 +13,7 @@ impl Module {
|
|||
pub(crate) fn new(def_id: DefId) -> Self {
|
||||
crate::code_model_api::Module { def_id }
|
||||
}
|
||||
|
||||
pub(crate) fn from_module_id(
|
||||
db: &impl HirDatabase,
|
||||
source_root_id: SourceRootId,
|
||||
|
@ -85,6 +86,7 @@ impl Module {
|
|||
let module_id = loc.module_id.crate_root(&module_tree);
|
||||
Module::from_module_id(db, loc.source_root_id, module_id)
|
||||
}
|
||||
|
||||
/// Finds a child module with the specified name.
|
||||
pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
|
||||
let loc = self.def_id.loc(db);
|
||||
|
@ -92,12 +94,14 @@ impl Module {
|
|||
let child_id = ctry!(loc.module_id.child(&module_tree, name));
|
||||
Module::from_module_id(db, loc.source_root_id, child_id).map(Some)
|
||||
}
|
||||
|
||||
pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
|
||||
let loc = self.def_id.loc(db);
|
||||
let module_tree = db.module_tree(loc.source_root_id)?;
|
||||
let parent_id = ctry!(loc.module_id.parent(&module_tree));
|
||||
Module::from_module_id(db, loc.source_root_id, parent_id).map(Some)
|
||||
}
|
||||
|
||||
/// Returns a `ModuleScope`: a set of items, visible in this module.
|
||||
pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
|
||||
let loc = self.def_id.loc(db);
|
||||
|
@ -105,6 +109,7 @@ impl Module {
|
|||
let res = item_map.per_module[&loc.module_id].clone();
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn resolve_path_impl(
|
||||
&self,
|
||||
db: &impl HirDatabase,
|
||||
|
@ -126,7 +131,7 @@ impl Module {
|
|||
);
|
||||
|
||||
let segments = &path.segments;
|
||||
for name in segments.iter() {
|
||||
for (idx, name) in segments.iter().enumerate() {
|
||||
let curr = if let Some(r) = curr_per_ns.as_ref().take_types() {
|
||||
r
|
||||
} else {
|
||||
|
@ -134,7 +139,35 @@ impl Module {
|
|||
};
|
||||
let module = match curr.resolve(db)? {
|
||||
Def::Module(it) => it,
|
||||
// TODO here would be the place to handle enum variants...
|
||||
Def::Enum(e) => {
|
||||
if segments.len() == idx + 1 {
|
||||
// enum variant
|
||||
let matching_variant = e.variants(db)?.map(|variants| {
|
||||
variants
|
||||
.into_iter()
|
||||
// FIXME: replace by match lol
|
||||
.find(|variant| {
|
||||
variant
|
||||
.name(db)
|
||||
.map(|o| o.map(|ref n| n == name))
|
||||
.unwrap_or(Some(false))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(Some(variant)) = matching_variant {
|
||||
return Ok(PerNs::both(variant.def_id(), e.def_id()));
|
||||
} else {
|
||||
return Ok(PerNs::none());
|
||||
}
|
||||
} else if segments.len() == idx {
|
||||
// enum
|
||||
return Ok(PerNs::types(e.def_id()));
|
||||
} else {
|
||||
// malformed enum?
|
||||
return Ok(PerNs::none());
|
||||
}
|
||||
}
|
||||
_ => return Ok(PerNs::none()),
|
||||
};
|
||||
let scope = module.scope(db)?;
|
||||
|
@ -146,6 +179,7 @@ impl Module {
|
|||
}
|
||||
Ok(curr_per_ns)
|
||||
}
|
||||
|
||||
pub fn problems_impl(
|
||||
&self,
|
||||
db: &impl HirDatabase,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue