More natural trait setup

This commit is contained in:
Aleksey Kladov 2020-01-16 16:27:21 +01:00
parent 8691ae8ac0
commit a3d6ddbe69
4 changed files with 49 additions and 27 deletions

View File

@ -140,12 +140,12 @@ fn find_struct_impl(
let struct_ty = {
let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() };
sb.to_def::<hir::Struct, _>(src)?.ty(db)
sb.to_def(src)?.ty(db)
};
let block = module.descendants().filter_map(ast::ImplBlock::cast).find_map(|impl_blk| {
let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() };
let blk = sb.to_def::<hir::ImplBlock, _>(src)?;
let blk = sb.to_def(src)?;
let same_ty = blk.target_ty(db) == struct_ty;
let not_trait_impl = blk.target_trait(db).is_none();

View File

@ -14,8 +14,7 @@
use crate::{
db::{DefDatabase, HirDatabase},
Const, DefWithBody, Enum, Function, ImplBlock, InFile, Local, Module, SourceBinder, Static,
Struct, Trait, TypeAlias, TypeParam,
DefWithBody, InFile, Local, Module, SourceBinder, TypeParam,
};
impl Local {
@ -25,9 +24,9 @@ pub fn from_source(db: &impl HirDatabase, src: InFile<ast::BindPat>) -> Option<S
let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| {
let res = match_ast! {
match it {
ast::ConstDef(value) => { sb.to_def::<Const, _>(InFile { value, file_id})?.into() },
ast::StaticDef(value) => { sb.to_def::<Static, _>(InFile { value, file_id})?.into() },
ast::FnDef(value) => { sb.to_def::<Function, _>(InFile { value, file_id})?.into() },
ast::ConstDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
ast::StaticDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
_ => return None,
}
};
@ -47,12 +46,12 @@ pub fn from_source(db: &impl HirDatabase, src: InFile<ast::TypeParam>) -> Option
let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| {
let res = match_ast! {
match it {
ast::FnDef(value) => { sb.to_def::<Function, _>(InFile { value, file_id})?.id.into() },
ast::StructDef(value) => { sb.to_def::<Struct, _>(InFile { value, file_id})?.id.into() },
ast::EnumDef(value) => { sb.to_def::<Enum, _>(InFile { value, file_id})?.id.into() },
ast::TraitDef(value) => { sb.to_def::<Trait, _>(InFile { value, file_id})?.id.into() },
ast::TypeAliasDef(value) => { sb.to_def::<TypeAlias, _>(InFile { value, file_id})?.id.into() },
ast::ImplBlock(value) => { sb.to_def::<ImplBlock, _>(InFile { value, file_id})?.id.into() },
ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
ast::StructDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
ast::EnumDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
ast::TraitDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
ast::TypeAliasDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
ast::ImplBlock(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
_ => return None,
}
};

View File

@ -52,11 +52,7 @@ pub fn analyze(
SourceAnalyzer::new_for_resolver(resolver, src)
}
pub fn to_def<D, T>(&mut self, src: InFile<T>) -> Option<D>
where
D: From<T::ID>,
T: ToId,
{
pub fn to_def<T: ToDef>(&mut self, src: InFile<T>) -> Option<T::Def> {
let id: T::ID = self.to_id(src)?;
Some(id.into())
}
@ -114,6 +110,39 @@ fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer>
}
}
pub trait ToId: Sized + AstNode + 'static {
type ID: Sized + Copy + 'static;
fn to_id<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>)
-> Option<Self::ID>;
}
pub trait ToDef: ToId {
type Def: From<Self::ID>;
}
macro_rules! to_def_impls {
($(($def:path, $ast:path)),* ,) => {$(
impl ToDef for $ast {
type Def = $def;
}
)*}
}
to_def_impls![
(crate::Struct, ast::StructDef),
(crate::Enum, ast::EnumDef),
(crate::Union, ast::UnionDef),
(crate::Trait, ast::TraitDef),
(crate::ImplBlock, ast::ImplBlock),
(crate::TypeAlias, ast::TypeAliasDef),
(crate::Const, ast::ConstDef),
(crate::Static, ast::StaticDef),
(crate::Function, ast::FnDef),
(crate::StructField, ast::RecordFieldDef),
(crate::EnumVariant, ast::EnumVariant),
(crate::MacroDef, ast::MacroCall), // this one is dubious, not all calls are macros
];
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
enum ChildContainer {
DefWithBodyId(DefWithBodyId),
@ -133,12 +162,6 @@ enum ChildContainer {
VariantId,
}
pub trait ToId: Sized + AstNode + 'static {
type ID: Sized + Copy + 'static;
fn to_id<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>)
-> Option<Self::ID>;
}
pub trait ToIdByKey: Sized + AstNode + 'static {
type ID: Sized + Copy + 'static;
const KEY: Key<Self, Self::ID>;

View File

@ -44,15 +44,15 @@ fn impls_for_def(
let ty = match node {
ast::NominalDef::StructDef(def) => {
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
sb.to_def::<hir::Struct, _>(src)?.ty(sb.db)
sb.to_def(src)?.ty(sb.db)
}
ast::NominalDef::EnumDef(def) => {
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
sb.to_def::<hir::Enum, _>(src)?.ty(sb.db)
sb.to_def(src)?.ty(sb.db)
}
ast::NominalDef::UnionDef(def) => {
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
sb.to_def::<hir::Union, _>(src)?.ty(sb.db)
sb.to_def(src)?.ty(sb.db)
}
};