Migrate trait & type to new ids

This commit is contained in:
Aleksey Kladov 2019-01-25 01:31:32 +03:00
parent 00ba70a095
commit 0f2f3a21e7
13 changed files with 104 additions and 186 deletions

View File

@ -13,10 +13,9 @@ use crate::{
ty::{InferenceResult, VariantDef}, ty::{InferenceResult, VariantDef},
adt::VariantData, adt::VariantData,
generics::GenericParams, generics::GenericParams,
code_model_impl::def_id_to_ast,
docs::{Documentation, Docs, docs_from_ast}, docs::{Documentation, Docs, docs_from_ast},
module_tree::ModuleId, module_tree::ModuleId,
ids::{FunctionId, StructId, EnumId, EnumVariantId, AstItemDef, ConstId, StaticId}, ids::{FunctionId, StructId, EnumId, EnumVariantId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
}; };
/// hir::Crate describes a single crate. It's the main interface with which /// hir::Crate describes a single crate. It's the main interface with which
@ -47,8 +46,6 @@ impl Crate {
#[derive(Debug)] #[derive(Debug)]
pub enum Def { pub enum Def {
Trait(Trait),
Type(Type),
Item, Item,
} }
@ -68,6 +65,8 @@ pub enum ModuleDef {
EnumVariant(EnumVariant), EnumVariant(EnumVariant),
Const(Const), Const(Const),
Static(Static), Static(Static),
Trait(Trait),
Type(Type),
// Can't be directly declared, but can be imported. // Can't be directly declared, but can be imported.
Def(DefId), Def(DefId),
} }
@ -78,7 +77,9 @@ impl_froms!(
Enum, Enum,
EnumVariant, EnumVariant,
Const, Const,
Static Static,
Trait,
Type
); );
impl From<DefId> for ModuleDef { impl From<DefId> for ModuleDef {
@ -428,22 +429,18 @@ impl Docs for Static {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Trait { pub struct Trait {
pub(crate) def_id: DefId, pub(crate) id: TraitId,
} }
impl Trait { impl Trait {
pub(crate) fn new(def_id: DefId) -> Trait {
Trait { def_id }
}
pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) { pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) {
def_id_to_ast(db, self.def_id) self.id.source(db)
} }
pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
db.generic_params(self.def_id.into()) db.generic_params((*self).into())
} }
} }
@ -453,22 +450,18 @@ impl Docs for Trait {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Type { pub struct Type {
pub(crate) def_id: DefId, pub(crate) id: TypeId,
} }
impl Type { impl Type {
pub(crate) fn new(def_id: DefId) -> Type {
Type { def_id }
}
pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TypeDef>) { pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TypeDef>) {
def_id_to_ast(db, self.def_id) self.id.source(db)
} }
pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
db.generic_params(self.def_id.into()) db.generic_params((*self).into())
} }
} }

View File

@ -1,18 +1,3 @@
mod krate; // `crate` is invalid ident :( mod krate; // `crate` is invalid ident :(
mod module; mod module;
pub(crate) mod function; pub(crate) mod function;
use ra_syntax::{AstNode, TreeArc};
use crate::{HirDatabase, DefId, HirFileId};
pub(crate) fn def_id_to_ast<N: AstNode>(
db: &impl HirDatabase,
def_id: DefId,
) -> (HirFileId, TreeArc<N>) {
let (file_id, syntax) = def_id.source(db);
let ast = N::cast(&syntax)
.unwrap_or_else(|| panic!("def points to wrong source {:?} {:?}", def_id, syntax))
.to_owned();
(file_id, ast)
}

View File

@ -147,17 +147,12 @@ impl Module {
None => PerNs::none(), None => PerNs::none(),
} }
} }
ModuleDef::Function(_) _ => {
| ModuleDef::Struct(_)
| ModuleDef::Const(_)
| ModuleDef::Static(_)
| ModuleDef::EnumVariant(_) => {
// could be an inherent method call in UFCS form // could be an inherent method call in UFCS form
// (`Struct::method`), or some other kind of associated // (`Struct::method`), or some other kind of associated
// item... Which we currently don't handle (TODO) // item... Which we currently don't handle (TODO)
PerNs::none() PerNs::none()
} }
ModuleDef::Def(_) => PerNs::none(),
}; };
} }
curr_per_ns curr_per_ns

View File

@ -5,9 +5,9 @@
use std::sync::Arc; use std::sync::Arc;
use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner}; use ra_syntax::ast::{self, NameOwner, TypeParamsOwner};
use crate::{db::HirDatabase, DefId, Name, AsName, Function, Struct, Enum}; use crate::{db::HirDatabase, Name, AsName, Function, Struct, Enum, Trait, Type};
/// Data about a generic parameter (to a function, struct, impl, ...). /// Data about a generic parameter (to a function, struct, impl, ...).
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
@ -27,15 +27,10 @@ pub enum GenericDef {
Function(Function), Function(Function),
Struct(Struct), Struct(Struct),
Enum(Enum), Enum(Enum),
Def(DefId), Trait(Trait),
} Type(Type),
impl_froms!(GenericDef: Function, Struct, Enum);
impl From<DefId> for GenericDef {
fn from(def_id: DefId) -> GenericDef {
GenericDef::Def(def_id)
}
} }
impl_froms!(GenericDef: Function, Struct, Enum, Trait, Type);
impl GenericParams { impl GenericParams {
pub(crate) fn generic_params_query( pub(crate) fn generic_params_query(
@ -47,12 +42,8 @@ impl GenericParams {
GenericDef::Function(it) => generics.fill(&*it.source(db).1), GenericDef::Function(it) => generics.fill(&*it.source(db).1),
GenericDef::Struct(it) => generics.fill(&*it.source(db).1), GenericDef::Struct(it) => generics.fill(&*it.source(db).1),
GenericDef::Enum(it) => generics.fill(&*it.source(db).1), GenericDef::Enum(it) => generics.fill(&*it.source(db).1),
GenericDef::Def(def_id) => { GenericDef::Trait(it) => generics.fill(&*it.source(db).1),
let (_file_id, node) = def_id.source(db); GenericDef::Type(it) => generics.fill(&*it.source(db).1),
if let Some(type_param_list) = node.children().find_map(ast::TypeParamList::cast) {
generics.fill_params(type_param_list)
}
}
} }
Arc::new(generics) Arc::new(generics)

View File

@ -9,7 +9,7 @@ use ra_arena::{Arena, RawId, ArenaId, impl_arena_id};
use crate::{ use crate::{
HirDatabase, Def, HirDatabase, Def,
Module, Trait, Type, Module,
}; };
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -22,6 +22,8 @@ pub struct HirInterner {
enum_variants: LocationIntener<ItemLoc<ast::EnumVariant>, EnumVariantId>, enum_variants: LocationIntener<ItemLoc<ast::EnumVariant>, EnumVariantId>,
consts: LocationIntener<ItemLoc<ast::ConstDef>, ConstId>, consts: LocationIntener<ItemLoc<ast::ConstDef>, ConstId>,
statics: LocationIntener<ItemLoc<ast::StaticDef>, StaticId>, statics: LocationIntener<ItemLoc<ast::StaticDef>, StaticId>,
traits: LocationIntener<ItemLoc<ast::TraitDef>, TraitId>,
types: LocationIntener<ItemLoc<ast::TypeDef>, TypeId>,
} }
impl HirInterner { impl HirInterner {
@ -279,6 +281,24 @@ impl AstItemDef<ast::StaticDef> for StaticId {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct TraitId(RawId);
impl_arena_id!(TraitId);
impl AstItemDef<ast::TraitDef> for TraitId {
fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::TraitDef>, Self> {
&interner.traits
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct TypeId(RawId);
impl_arena_id!(TypeId);
impl AstItemDef<ast::TypeDef> for TypeId {
fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::TypeDef>, Self> {
&interner.types
}
}
/// Def's are a core concept of hir. A `Def` is an Item (function, module, etc) /// Def's are a core concept of hir. A `Def` is an Item (function, module, etc)
/// in a specific module. /// in a specific module.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -294,8 +314,6 @@ pub struct DefLoc {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum DefKind { pub(crate) enum DefKind {
Trait,
Type,
Item, Item,
// /// The constructor of a struct. E.g. if we have `struct Foo(usize)`, the // /// The constructor of a struct. E.g. if we have `struct Foo(usize)`, the
// /// name `Foo` needs to resolve to different types depending on whether we // /// name `Foo` needs to resolve to different types depending on whether we
@ -317,23 +335,9 @@ impl DefId {
pub fn resolve(self, db: &impl HirDatabase) -> Def { pub fn resolve(self, db: &impl HirDatabase) -> Def {
let loc = self.loc(db); let loc = self.loc(db);
match loc.kind { match loc.kind {
DefKind::Trait => {
let def = Trait::new(self);
Def::Trait(def)
}
DefKind::Type => {
let def = Type::new(self);
Def::Type(def)
}
DefKind::Item => Def::Item, DefKind::Item => Def::Item,
} }
} }
pub(crate) fn source(self, db: &impl HirDatabase) -> (HirFileId, TreeArc<SyntaxNode>) {
let loc = self.loc(db);
let syntax = db.file_item(loc.source_item_id);
(loc.source_item_id.file_id, syntax)
}
} }
impl DefLoc { impl DefLoc {

View File

@ -1,16 +1,16 @@
use std::sync::Arc; use std::sync::Arc;
use ra_syntax::{ use ra_syntax::{
SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr, AstNode, SourceFile, TreeArc, AstPtr,
ast::{self, ModuleItemOwner, NameOwner}, ast::{self, ModuleItemOwner, NameOwner},
}; };
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::{ use crate::{
SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, SourceItemId, Path, ModuleSource, HirDatabase, Name,
HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, Function, HirFileId, MacroCallLoc, AsName, PerNs, Function,
ModuleDef, Module, Struct, Enum, Const, Static, ModuleDef, Module, Struct, Enum, Const, Static, Trait, Type,
ids::LocationCtx, ids::LocationCtx,
}; };
@ -115,7 +115,7 @@ impl LoweredModule {
for item in items { for item in items {
match item { match item {
ast::ItemOrMacro::Item(it) => { ast::ItemOrMacro::Item(it) => {
self.add_def_id(source_map, db, module, file_id, &file_items, it); self.add_def_id(source_map, db, module, file_id, it);
} }
ast::ItemOrMacro::Macro(macro_call) => { ast::ItemOrMacro::Macro(macro_call) => {
let item_id = file_items.id_of_unchecked(macro_call.syntax()); let item_id = file_items.id_of_unchecked(macro_call.syntax());
@ -128,10 +128,9 @@ impl LoweredModule {
}; };
let id = loc.id(db); let id = loc.id(db);
let file_id = HirFileId::from(id); let file_id = HirFileId::from(id);
let file_items = db.file_items(file_id);
//FIXME: expand recursively //FIXME: expand recursively
for item in db.hir_source_file(file_id).items() { for item in db.hir_source_file(file_id).items() {
self.add_def_id(source_map, db, module, file_id, &file_items, item); self.add_def_id(source_map, db, module, file_id, item);
} }
} }
} }
@ -144,18 +143,16 @@ impl LoweredModule {
db: &impl HirDatabase, db: &impl HirDatabase,
module: Module, module: Module,
file_id: HirFileId, file_id: HirFileId,
file_items: &SourceFileItems,
item: &ast::ModuleItem, item: &ast::ModuleItem,
) { ) {
let ctx = LocationCtx::new(db, module, file_id); let ctx = LocationCtx::new(db, module, file_id);
let name = match item.kind() { match item.kind() {
ast::ModuleItemKind::StructDef(it) => { ast::ModuleItemKind::StructDef(it) => {
if let Some(name) = it.name() { if let Some(name) = it.name() {
let s = Struct { id: ctx.to_def(it) }; let s = Struct { id: ctx.to_def(it) };
let s: ModuleDef = s.into(); let s: ModuleDef = s.into();
self.declarations.insert(name.as_name(), PerNs::both(s, s)); self.declarations.insert(name.as_name(), PerNs::both(s, s));
} }
return;
} }
ast::ModuleItemKind::EnumDef(it) => { ast::ModuleItemKind::EnumDef(it) => {
if let Some(name) = it.name() { if let Some(name) = it.name() {
@ -163,7 +160,6 @@ impl LoweredModule {
let e: ModuleDef = e.into(); let e: ModuleDef = e.into();
self.declarations.insert(name.as_name(), PerNs::types(e)); self.declarations.insert(name.as_name(), PerNs::types(e));
} }
return;
} }
ast::ModuleItemKind::FnDef(it) => { ast::ModuleItemKind::FnDef(it) => {
if let Some(name) = it.name() { if let Some(name) = it.name() {
@ -171,21 +167,29 @@ impl LoweredModule {
self.declarations self.declarations
.insert(name.as_name(), PerNs::values(func.into())); .insert(name.as_name(), PerNs::values(func.into()));
} }
return;
} }
ast::ModuleItemKind::TraitDef(it) => it.name(), ast::ModuleItemKind::TraitDef(it) => {
ast::ModuleItemKind::TypeDef(it) => it.name(), if let Some(name) = it.name() {
let t = Trait { id: ctx.to_def(it) };
self.declarations
.insert(name.as_name(), PerNs::types(t.into()));
}
}
ast::ModuleItemKind::TypeDef(it) => {
if let Some(name) = it.name() {
let t = Type { id: ctx.to_def(it) };
self.declarations
.insert(name.as_name(), PerNs::types(t.into()));
}
}
ast::ModuleItemKind::ImplBlock(_) => { ast::ModuleItemKind::ImplBlock(_) => {
// impls don't define items // impls don't define items
return;
} }
ast::ModuleItemKind::UseItem(it) => { ast::ModuleItemKind::UseItem(it) => {
self.add_use_item(source_map, it); self.add_use_item(source_map, it);
return;
} }
ast::ModuleItemKind::ExternCrateItem(_) => { ast::ModuleItemKind::ExternCrateItem(_) => {
// TODO // TODO
return;
} }
ast::ModuleItemKind::ConstDef(it) => { ast::ModuleItemKind::ConstDef(it) => {
if let Some(name) = it.name() { if let Some(name) = it.name() {
@ -193,7 +197,6 @@ impl LoweredModule {
self.declarations self.declarations
.insert(name.as_name(), PerNs::values(c.into())); .insert(name.as_name(), PerNs::values(c.into()));
} }
return;
} }
ast::ModuleItemKind::StaticDef(it) => { ast::ModuleItemKind::StaticDef(it) => {
if let Some(name) = it.name() { if let Some(name) = it.name() {
@ -201,17 +204,11 @@ impl LoweredModule {
self.declarations self.declarations
.insert(name.as_name(), PerNs::values(s.into())); .insert(name.as_name(), PerNs::values(s.into()));
} }
return;
} }
ast::ModuleItemKind::Module(_) => { ast::ModuleItemKind::Module(_) => {
// modules are handled separately direclty by nameres // modules are handled separately direclty by nameres
return;
} }
}; };
if let Some(name) = name {
let def_id = assign_def_id(db, module, file_id, file_items, item);
self.declarations.insert(name.as_name(), def_id);
}
} }
fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) {
@ -226,43 +223,3 @@ impl LoweredModule {
}) })
} }
} }
fn assign_def_id(
db: &impl HirDatabase,
module: Module,
file_id: HirFileId,
file_items: &SourceFileItems,
item: &ast::ModuleItem,
) -> PerNs<ModuleDef> {
// depending on the item kind, the location can define something in
// the values namespace, the types namespace, or both
let kind = DefKind::for_syntax_kind(item.syntax().kind());
let def_id = kind.map(|k| {
let item_id = file_items.id_of_unchecked(item.syntax());
let def_loc = DefLoc {
kind: k,
module,
source_item_id: SourceItemId {
file_id,
item_id: Some(item_id),
},
};
def_loc.id(db).into()
});
def_id
}
impl DefKind {
fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> {
match kind {
SyntaxKind::FN_DEF => unreachable!(),
SyntaxKind::STRUCT_DEF => unreachable!(),
SyntaxKind::ENUM_DEF => unreachable!(),
SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait),
SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Type),
SyntaxKind::CONST_DEF => unreachable!(),
SyntaxKind::STATIC_DEF => unreachable!(),
_ => PerNs::none(),
}
}
}

View File

@ -145,10 +145,10 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
.iter() .iter()
.filter_map(|(_, it)| it.clone().take_types()) .filter_map(|(_, it)| it.clone().take_types())
.filter_map(|it| match it { .filter_map(|it| match it {
ModuleDef::Def(it) => Some(it), ModuleDef::Trait(it) => Some(it),
_ => None, _ => None,
}) })
.filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id()) .filter_map(|it| it.source(db).0.as_macro_call_id())
{ {
if let Some(exp) = db.expand_macro_invocation(macro_call_id) { if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
let loc = macro_call_id.loc(db); let loc = macro_call_id.loc(db);

View File

@ -696,7 +696,9 @@ impl From<ModuleDef> for Option<TypableDef> {
ModuleDef::Const(_) ModuleDef::Const(_)
| ModuleDef::Static(_) | ModuleDef::Static(_)
| ModuleDef::Def(_) | ModuleDef::Def(_)
| ModuleDef::Module(_) => return None, | ModuleDef::Module(_)
| ModuleDef::Trait(_)
| ModuleDef::Type(_) => return None,
}; };
Some(res) Some(res)
} }

View File

@ -40,12 +40,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
.add_to(acc) .add_to(acc)
}); });
} }
hir::ModuleDef::Function(_) _ => return,
| hir::ModuleDef::Struct(_)
| hir::ModuleDef::Def(_)
| hir::ModuleDef::Const(_)
| hir::ModuleDef::Static(_)
| hir::ModuleDef::EnumVariant(_) => return,
}; };
} }

View File

@ -225,11 +225,9 @@ impl Builder {
hir::ModuleDef::EnumVariant(it) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)), hir::ModuleDef::EnumVariant(it) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)),
hir::ModuleDef::Const(it) => (CompletionItemKind::Const, it.docs(ctx.db)), hir::ModuleDef::Const(it) => (CompletionItemKind::Const, it.docs(ctx.db)),
hir::ModuleDef::Static(it) => (CompletionItemKind::Static, it.docs(ctx.db)), hir::ModuleDef::Static(it) => (CompletionItemKind::Static, it.docs(ctx.db)),
hir::ModuleDef::Def(def_id) => match def_id.resolve(ctx.db) { hir::ModuleDef::Trait(it) => (CompletionItemKind::Trait, it.docs(ctx.db)),
hir::Def::Trait(it) => (CompletionItemKind::Trait, it.docs(ctx.db)), hir::ModuleDef::Type(it) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
hir::Def::Type(it) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), hir::ModuleDef::Def(_) => return self,
_ => return self,
},
}; };
self.kind = Some(kind); self.kind = Some(kind);
self.documentation = docs; self.documentation = docs;

View File

@ -3,7 +3,7 @@ use ra_syntax::{
SyntaxNode, AstNode, SmolStr, TextRange, ast, SyntaxNode, AstNode, SmolStr, TextRange, ast,
SyntaxKind::{self, NAME}, SyntaxKind::{self, NAME},
}; };
use hir::{Def, ModuleSource}; use hir::{ModuleSource};
use crate::{FileSymbol, db::RootDatabase}; use crate::{FileSymbol, db::RootDatabase};
@ -106,63 +106,60 @@ impl NavigationTarget {
db: &RootDatabase, db: &RootDatabase,
module_def: hir::ModuleDef, module_def: hir::ModuleDef,
) -> Option<NavigationTarget> { ) -> Option<NavigationTarget> {
let def = match module_def { match module_def {
hir::ModuleDef::Def(def_id) => def_id.resolve(db), hir::ModuleDef::Def(_) => return None,
hir::ModuleDef::Module(module) => { hir::ModuleDef::Module(module) => Some(NavigationTarget::from_module(db, module)),
return Some(NavigationTarget::from_module(db, module)); hir::ModuleDef::Function(func) => Some(NavigationTarget::from_function(db, func)),
}
hir::ModuleDef::Function(func) => {
return Some(NavigationTarget::from_function(db, func));
}
hir::ModuleDef::Struct(s) => { hir::ModuleDef::Struct(s) => {
let (file_id, node) = s.source(db); let (file_id, node) = s.source(db);
return Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id.original_file(db), file_id.original_file(db),
&*node, &*node,
)); ))
} }
hir::ModuleDef::Const(s) => { hir::ModuleDef::Const(s) => {
let (file_id, node) = s.source(db); let (file_id, node) = s.source(db);
return Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id.original_file(db), file_id.original_file(db),
&*node, &*node,
)); ))
} }
hir::ModuleDef::Static(s) => { hir::ModuleDef::Static(s) => {
let (file_id, node) = s.source(db); let (file_id, node) = s.source(db);
return Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id.original_file(db), file_id.original_file(db),
&*node, &*node,
)); ))
} }
hir::ModuleDef::Enum(e) => { hir::ModuleDef::Enum(e) => {
let (file_id, node) = e.source(db); let (file_id, node) = e.source(db);
return Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id.original_file(db), file_id.original_file(db),
&*node, &*node,
)); ))
} }
hir::ModuleDef::EnumVariant(var) => { hir::ModuleDef::EnumVariant(var) => {
let (file_id, node) = var.source(db); let (file_id, node) = var.source(db);
return Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id.original_file(db), file_id.original_file(db),
&*node, &*node,
)); ))
} }
}; hir::ModuleDef::Trait(e) => {
let (file_id, node) = e.source(db);
let res = match def { Some(NavigationTarget::from_named(
Def::Trait(f) => { file_id.original_file(db),
let (file_id, node) = f.source(db); &*node,
NavigationTarget::from_named(file_id.original_file(db), &*node) ))
} }
Def::Type(f) => { hir::ModuleDef::Type(e) => {
let (file_id, node) = f.source(db); let (file_id, node) = e.source(db);
NavigationTarget::from_named(file_id.original_file(db), &*node) Some(NavigationTarget::from_named(
file_id.original_file(db),
&*node,
))
} }
Def::Item => return None, }
};
Some(res)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -3229,6 +3229,7 @@ impl ast::VisibilityOwner for TraitDef {}
impl ast::NameOwner for TraitDef {} impl ast::NameOwner for TraitDef {}
impl ast::AttrsOwner for TraitDef {} impl ast::AttrsOwner for TraitDef {}
impl ast::DocCommentsOwner for TraitDef {} impl ast::DocCommentsOwner for TraitDef {}
impl ast::TypeParamsOwner for TraitDef {}
impl TraitDef {} impl TraitDef {}
// TrueKw // TrueKw

View File

@ -280,7 +280,7 @@ Grammar(
], options: [["variant_list", "EnumVariantList"]] ), ], options: [["variant_list", "EnumVariantList"]] ),
"EnumVariantList": ( collections: [["variants", "EnumVariant"]] ), "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ),
"EnumVariant": ( traits: ["NameOwner", "DocCommentsOwner"], options: ["Expr"] ), "EnumVariant": ( traits: ["NameOwner", "DocCommentsOwner"], options: ["Expr"] ),
"TraitDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner"] ), "TraitDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner", "TypeParamsOwner"] ),
"Module": ( "Module": (
traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner" ], traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner" ],
options: [ "ItemList" ] options: [ "ItemList" ]
@ -489,7 +489,7 @@ Grammar(
), ),
"RefPat": ( options: [ "Pat" ]), "RefPat": ( options: [ "Pat" ]),
"BindPat": ( "BindPat": (
options: [ "Pat" ], options: [ "Pat" ],
traits: ["NameOwner"] traits: ["NameOwner"]
), ),