mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
Add Container enum to handle both kinds of container (impl/trait)
This commit is contained in:
parent
7650a44640
commit
4497e1d3ea
4 changed files with 58 additions and 17 deletions
|
@ -189,7 +189,7 @@ impl Module {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||
pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
|
||||
let def_map = db.crate_def_map(self.krate);
|
||||
Resolver::default().push_module_scope(def_map, self.module_id)
|
||||
}
|
||||
|
@ -552,16 +552,21 @@ impl Function {
|
|||
db.trait_items_index(self.module(db)).get_parent_trait((*self).into())
|
||||
}
|
||||
|
||||
pub fn container(&self, db: &impl DefDatabase) -> Option<Container> {
|
||||
if let Some(impl_block) = self.impl_block(db) {
|
||||
Some(impl_block.into())
|
||||
} else if let Some(trait_) = self.parent_trait(db) {
|
||||
Some(trait_.into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: move to a more general type for 'body-having' items
|
||||
/// Builds a resolver for code inside this item.
|
||||
pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||
// take the outer scope...
|
||||
// FIXME abstract over containers (trait/impl)
|
||||
let r = self
|
||||
.impl_block(db)
|
||||
.map(|ib| ib.resolver(db))
|
||||
.or_else(|| self.parent_trait(db).map(|tr| tr.resolver(db)))
|
||||
.unwrap_or_else(|| self.module(db).resolver(db));
|
||||
let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db));
|
||||
// ...and add generic params, if present
|
||||
let p = self.generic_params(db);
|
||||
let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
|
||||
|
@ -707,7 +712,7 @@ impl Trait {
|
|||
db.trait_data(self)
|
||||
}
|
||||
|
||||
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||
pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
|
||||
let r = self.module(db).resolver(db);
|
||||
// add generic params, if present
|
||||
let p = self.generic_params(db);
|
||||
|
@ -746,6 +751,21 @@ impl TypeAlias {
|
|||
ImplBlock::containing(module_impls, (*self).into())
|
||||
}
|
||||
|
||||
/// The containing trait, if this is a trait method definition.
|
||||
pub fn parent_trait(&self, db: &impl DefDatabase) -> Option<Trait> {
|
||||
db.trait_items_index(self.module(db)).get_parent_trait((*self).into())
|
||||
}
|
||||
|
||||
pub fn container(&self, db: &impl DefDatabase) -> Option<Container> {
|
||||
if let Some(impl_block) = self.impl_block(db) {
|
||||
Some(impl_block.into())
|
||||
} else if let Some(trait_) = self.parent_trait(db) {
|
||||
Some(trait_.into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> {
|
||||
db.type_alias_ref(self)
|
||||
}
|
||||
|
@ -769,3 +789,18 @@ impl Docs for TypeAlias {
|
|||
docs_from_ast(&*self.source(db).1)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Container {
|
||||
Trait(Trait),
|
||||
ImplBlock(ImplBlock),
|
||||
}
|
||||
impl_froms!(Container: Trait, ImplBlock);
|
||||
|
||||
impl Container {
|
||||
pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
|
||||
match self {
|
||||
Container::Trait(trait_) => trait_.resolver(db),
|
||||
Container::ImplBlock(impl_block) => impl_block.resolver(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use ra_syntax::ast::{self, NameOwner, TypeParamsOwner};
|
|||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock
|
||||
Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container
|
||||
};
|
||||
|
||||
/// Data about a generic parameter (to a function, struct, impl, ...).
|
||||
|
@ -27,6 +27,7 @@ pub struct GenericParams {
|
|||
pub(crate) params: Vec<GenericParam>,
|
||||
}
|
||||
|
||||
// FIXME: consts can have type parameters from their parents (i.e. associated consts of traits)
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum GenericDef {
|
||||
Function(Function),
|
||||
|
@ -45,12 +46,8 @@ impl GenericParams {
|
|||
) -> Arc<GenericParams> {
|
||||
let mut generics = GenericParams::default();
|
||||
let parent = match def {
|
||||
// FIXME abstract over containers (trait/impl)
|
||||
GenericDef::Function(it) => it
|
||||
.impl_block(db)
|
||||
.map(GenericDef::from)
|
||||
.or_else(|| it.parent_trait(db).map(GenericDef::from)),
|
||||
GenericDef::TypeAlias(it) => it.impl_block(db).map(GenericDef::from),
|
||||
GenericDef::Function(it) => it.container(db).map(GenericDef::from),
|
||||
GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
|
||||
GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None,
|
||||
GenericDef::ImplBlock(_) => None,
|
||||
};
|
||||
|
@ -112,3 +109,12 @@ impl GenericParams {
|
|||
vec
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Container> for GenericDef {
|
||||
fn from(c: Container) -> Self {
|
||||
match c {
|
||||
Container::Trait(trait_) => trait_.into(),
|
||||
Container::ImplBlock(impl_block) => impl_block.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ impl ImplBlock {
|
|||
db.generic_params((*self).into())
|
||||
}
|
||||
|
||||
pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||
pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
|
||||
let r = self.module().resolver(db);
|
||||
// add generic params, if present
|
||||
let p = self.generic_params(db);
|
||||
|
|
|
@ -78,5 +78,5 @@ pub use self::code_model_api::{
|
|||
Function, FnSignature,
|
||||
StructField, FieldSource,
|
||||
Static, Const, ConstSignature,
|
||||
Trait, TypeAlias,
|
||||
Trait, TypeAlias, Container,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue