mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
More natural trait setup
This commit is contained in:
parent
8691ae8ac0
commit
a3d6ddbe69
4 changed files with 49 additions and 27 deletions
|
@ -140,12 +140,12 @@ fn find_struct_impl(
|
||||||
|
|
||||||
let struct_ty = {
|
let struct_ty = {
|
||||||
let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() };
|
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 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 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 same_ty = blk.target_ty(db) == struct_ty;
|
||||||
let not_trait_impl = blk.target_trait(db).is_none();
|
let not_trait_impl = blk.target_trait(db).is_none();
|
||||||
|
|
|
@ -14,8 +14,7 @@ use ra_syntax::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::{DefDatabase, HirDatabase},
|
db::{DefDatabase, HirDatabase},
|
||||||
Const, DefWithBody, Enum, Function, ImplBlock, InFile, Local, Module, SourceBinder, Static,
|
DefWithBody, InFile, Local, Module, SourceBinder, TypeParam,
|
||||||
Struct, Trait, TypeAlias, TypeParam,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Local {
|
impl Local {
|
||||||
|
@ -25,9 +24,9 @@ impl Local {
|
||||||
let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| {
|
let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| {
|
||||||
let res = match_ast! {
|
let res = match_ast! {
|
||||||
match it {
|
match it {
|
||||||
ast::ConstDef(value) => { sb.to_def::<Const, _>(InFile { value, file_id})?.into() },
|
ast::ConstDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
|
||||||
ast::StaticDef(value) => { sb.to_def::<Static, _>(InFile { value, file_id})?.into() },
|
ast::StaticDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
|
||||||
ast::FnDef(value) => { sb.to_def::<Function, _>(InFile { value, file_id})?.into() },
|
ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -47,12 +46,12 @@ impl TypeParam {
|
||||||
let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| {
|
let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| {
|
||||||
let res = match_ast! {
|
let res = match_ast! {
|
||||||
match it {
|
match it {
|
||||||
ast::FnDef(value) => { sb.to_def::<Function, _>(InFile { value, file_id})?.id.into() },
|
ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
||||||
ast::StructDef(value) => { sb.to_def::<Struct, _>(InFile { value, file_id})?.id.into() },
|
ast::StructDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
||||||
ast::EnumDef(value) => { sb.to_def::<Enum, _>(InFile { value, file_id})?.id.into() },
|
ast::EnumDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
||||||
ast::TraitDef(value) => { sb.to_def::<Trait, _>(InFile { value, file_id})?.id.into() },
|
ast::TraitDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
||||||
ast::TypeAliasDef(value) => { sb.to_def::<TypeAlias, _>(InFile { value, file_id})?.id.into() },
|
ast::TypeAliasDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
||||||
ast::ImplBlock(value) => { sb.to_def::<ImplBlock, _>(InFile { value, file_id})?.id.into() },
|
ast::ImplBlock(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,11 +52,7 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
|
||||||
SourceAnalyzer::new_for_resolver(resolver, src)
|
SourceAnalyzer::new_for_resolver(resolver, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_def<D, T>(&mut self, src: InFile<T>) -> Option<D>
|
pub fn to_def<T: ToDef>(&mut self, src: InFile<T>) -> Option<T::Def> {
|
||||||
where
|
|
||||||
D: From<T::ID>,
|
|
||||||
T: ToId,
|
|
||||||
{
|
|
||||||
let id: T::ID = self.to_id(src)?;
|
let id: T::ID = self.to_id(src)?;
|
||||||
Some(id.into())
|
Some(id.into())
|
||||||
}
|
}
|
||||||
|
@ -114,6 +110,39 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
enum ChildContainer {
|
enum ChildContainer {
|
||||||
DefWithBodyId(DefWithBodyId),
|
DefWithBodyId(DefWithBodyId),
|
||||||
|
@ -133,12 +162,6 @@ impl_froms! {
|
||||||
VariantId,
|
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 {
|
pub trait ToIdByKey: Sized + AstNode + 'static {
|
||||||
type ID: Sized + Copy + 'static;
|
type ID: Sized + Copy + 'static;
|
||||||
const KEY: Key<Self, Self::ID>;
|
const KEY: Key<Self, Self::ID>;
|
||||||
|
|
|
@ -44,15 +44,15 @@ fn impls_for_def(
|
||||||
let ty = match node {
|
let ty = match node {
|
||||||
ast::NominalDef::StructDef(def) => {
|
ast::NominalDef::StructDef(def) => {
|
||||||
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
|
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) => {
|
ast::NominalDef::EnumDef(def) => {
|
||||||
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
|
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) => {
|
ast::NominalDef::UnionDef(def) => {
|
||||||
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
|
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)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue