From 566c8e321e89e5ff8996daa615cc47aea0012881 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 24 Jan 2019 18:56:38 +0300 Subject: migrate enums to new id --- crates/ra_hir/src/adt.rs | 54 ++++++++++------- crates/ra_hir/src/code_model_api.rs | 53 +++++++++-------- crates/ra_hir/src/code_model_impl/module.rs | 42 ++++++-------- crates/ra_hir/src/db.rs | 6 +- crates/ra_hir/src/generics.rs | 38 ++++++------ crates/ra_hir/src/ids.rs | 29 ++++------ crates/ra_hir/src/nameres/lower.rs | 15 +++-- crates/ra_hir/src/ty.rs | 90 +++++++++++++++++++---------- crates/ra_syntax/src/ast.rs | 7 +++ 9 files changed, 191 insertions(+), 143 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index 3caf60ee6..baf853a3a 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs @@ -13,7 +13,7 @@ use crate::{ HirDatabase, DefKind, SourceItemId, type_ref::TypeRef, - ids::{StructLoc}, + ids::{StructLoc, EnumLoc}, }; impl Struct { @@ -33,6 +33,19 @@ impl Struct { } } +impl Enum { + pub(crate) fn from_ast( + db: &impl HirDatabase, + module: Module, + file_id: HirFileId, + ast: &ast::EnumDef, + ) -> Enum { + let loc: EnumLoc = EnumLoc::from_ast(db, module, file_id, ast); + let id = loc.id(db); + Enum { id } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructData { pub(crate) name: Option, @@ -55,20 +68,20 @@ impl StructData { fn get_def_id( db: &impl HirDatabase, - same_file_loc: &DefLoc, + module: Module, + file_id: HirFileId, node: &SyntaxNode, expected_kind: DefKind, ) -> DefId { - let file_id = same_file_loc.source_item_id.file_id; let file_items = db.file_items(file_id); let item_id = file_items.id_of(file_id, node); let source_item_id = SourceItemId { + file_id, item_id: Some(item_id), - ..same_file_loc.source_item_id }; let loc = DefLoc { - module: same_file_loc.module, + module, kind: expected_kind, source_item_id, }; @@ -87,19 +100,22 @@ impl EnumData { EnumData { name, variants } } - pub(crate) fn enum_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc { - let def_loc = def_id.loc(db); - assert!(def_loc.kind == DefKind::Enum); - let syntax = db.file_item(def_loc.source_item_id); - let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node"); + pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc { + let (file_id, enum_def) = e.source(db); + let module = e.module(db); let variants = if let Some(vl) = enum_def.variant_list() { vl.variants() .filter_map(|variant_def| { let name = variant_def.name().map(|n| n.as_name()); name.map(|n| { - let def_id = - get_def_id(db, &def_loc, variant_def.syntax(), DefKind::EnumVariant); + let def_id = get_def_id( + db, + module, + file_id, + variant_def.syntax(), + DefKind::EnumVariant, + ); (n, EnumVariant::new(def_id)) }) }) @@ -107,7 +123,7 @@ impl EnumData { } else { Vec::new() }; - Arc::new(EnumData::new(enum_def, variants)) + Arc::new(EnumData::new(&*enum_def, variants)) } } @@ -139,14 +155,10 @@ impl EnumVariantData { let syntax = db.file_item(def_loc.source_item_id); let variant_def = ast::EnumVariant::cast(&syntax) .expect("enum variant def should point to EnumVariant node"); - let enum_node = syntax - .parent() - .expect("enum variant should have enum variant list ancestor") - .parent() - .expect("enum variant list should have enum ancestor"); - let enum_def_id = get_def_id(db, &def_loc, enum_node, DefKind::Enum); - - Arc::new(EnumVariantData::new(variant_def, Enum::new(enum_def_id))) + let enum_def = variant_def.parent_enum(); + let e = Enum::from_ast(db, def_loc.module, def_loc.source_item_id.file_id, enum_def); + + Arc::new(EnumVariantData::new(variant_def, e)) } } diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 948718aa6..0a96d6f6d 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -16,7 +16,7 @@ use crate::{ code_model_impl::def_id_to_ast, docs::{Documentation, Docs, docs_from_ast}, module_tree::ModuleId, - ids::{FunctionId, StructId}, + ids::{FunctionId, StructId, EnumId}, }; /// hir::Crate describes a single crate. It's the main interface with which @@ -69,30 +69,37 @@ pub enum ModuleDef { Module(Module), Function(Function), Struct(Struct), + Enum(Enum), Def(DefId), } +//FIXME: change to from +impl From for ModuleDef { + fn from(it: Module) -> ModuleDef { + ModuleDef::Module(it) + } +} -impl Into for Module { - fn into(self) -> ModuleDef { - ModuleDef::Module(self) +impl From for ModuleDef { + fn from(it: Function) -> ModuleDef { + ModuleDef::Function(it) } } -impl Into for Function { - fn into(self) -> ModuleDef { - ModuleDef::Function(self) +impl From for ModuleDef { + fn from(it: Struct) -> ModuleDef { + ModuleDef::Struct(it) } } -impl Into for Struct { - fn into(self) -> ModuleDef { - ModuleDef::Struct(self) +impl From for ModuleDef { + fn from(it: Enum) -> ModuleDef { + ModuleDef::Enum(it) } } -impl Into for DefId { - fn into(self) -> ModuleDef { - ModuleDef::Def(self) +impl From for ModuleDef { + fn from(it: DefId) -> ModuleDef { + ModuleDef::Def(it) } } @@ -249,34 +256,30 @@ impl Docs for Struct { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Enum { - pub(crate) def_id: DefId, + pub(crate) id: EnumId, } impl Enum { - pub(crate) fn new(def_id: DefId) -> Self { - Enum { def_id } - } - - pub fn def_id(&self) -> DefId { - self.def_id + pub fn module(&self, db: &impl HirDatabase) -> Module { + self.id.loc(db).module } pub fn name(&self, db: &impl HirDatabase) -> Option { - db.enum_data(self.def_id).name.clone() + db.enum_data(*self).name.clone() } pub fn variants(&self, db: &impl HirDatabase) -> Vec<(Name, EnumVariant)> { - db.enum_data(self.def_id).variants.clone() + db.enum_data(*self).variants.clone() } pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc) { - def_id_to_ast(db, self.def_id) + self.id.loc(db).source(db) } pub fn generic_params(&self, db: &impl HirDatabase) -> Arc { - db.generic_params(self.def_id.into()) + db.generic_params((*self).into()) } } diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 42f10e941..4ea649770 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs @@ -3,7 +3,7 @@ use ra_syntax::{ast, SyntaxNode, TreeArc}; use crate::{ Module, ModuleSource, Problem, ModuleDef, - Crate, Name, Path, PathKind, PerNs, Def, + Crate, Name, Path, PathKind, PerNs, module_tree::ModuleId, nameres::{ModuleScope, lower::ImportId}, db::HirDatabase, @@ -135,31 +135,25 @@ impl Module { None => PerNs::none(), } } - ModuleDef::Function(_) | ModuleDef::Struct(_) => PerNs::none(), - ModuleDef::Def(def) => { - match def.resolve(db) { - Def::Enum(e) => { - // enum variant - let matching_variant = e - .variants(db) - .into_iter() - .find(|(n, _variant)| n == &segment.name); - - match matching_variant { - Some((_n, variant)) => { - PerNs::both(variant.def_id().into(), e.def_id().into()) - } - None => PerNs::none(), - } - } - _ => { - // could be an inherent method call in UFCS form - // (`Struct::method`), or some other kind of associated - // item... Which we currently don't handle (TODO) - PerNs::none() - } + ModuleDef::Enum(e) => { + // enum variant + let matching_variant = e + .variants(db) + .into_iter() + .find(|(n, _variant)| n == &segment.name); + + match matching_variant { + Some((_n, variant)) => PerNs::both(variant.def_id().into(), (*e).into()), + None => PerNs::none(), } } + ModuleDef::Function(_) | ModuleDef::Struct(_) => { + // could be an inherent method call in UFCS form + // (`Struct::method`), or some other kind of associated + // item... Which we currently don't handle (TODO) + PerNs::none() + } + ModuleDef::Def(_) => PerNs::none(), }; } curr_per_ns diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 75935c30f..34e41017b 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -8,7 +8,7 @@ use crate::{ SourceFileItems, SourceItemId, Crate, Module, HirInterner, query_definitions, Function, FnSignature, FnScopes, - Struct, + Struct, Enum, macros::MacroExpansion, module_tree::ModuleTree, nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, @@ -30,10 +30,10 @@ pub trait HirDatabase: SyntaxDatabase + AsRef { fn fn_scopes(&self, func: Function) -> Arc; #[salsa::invoke(crate::adt::StructData::struct_data_query)] - fn struct_data(&self, struct_: Struct) -> Arc; + fn struct_data(&self, s: Struct) -> Arc; #[salsa::invoke(crate::adt::EnumData::enum_data_query)] - fn enum_data(&self, def_id: DefId) -> Arc; + fn enum_data(&self, e: Enum) -> Arc; #[salsa::invoke(crate::adt::EnumVariantData::enum_variant_data_query)] fn enum_variant_data(&self, def_id: DefId) -> Arc; diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index e10b85ec9..df23871c7 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner}; -use crate::{db::HirDatabase, DefId, Name, AsName, Function, Struct}; +use crate::{db::HirDatabase, DefId, Name, AsName, Function, Struct, Enum}; /// Data about a generic parameter (to a function, struct, impl, ...). #[derive(Clone, PartialEq, Eq, Debug)] @@ -26,6 +26,7 @@ pub struct GenericParams { pub enum GenericDef { Function(Function), Struct(Struct), + Enum(Enum), Def(DefId), } @@ -36,8 +37,14 @@ impl From for GenericDef { } impl From for GenericDef { - fn from(func: Struct) -> GenericDef { - GenericDef::Struct(func) + fn from(s: Struct) -> GenericDef { + GenericDef::Struct(s) + } +} + +impl From for GenericDef { + fn from(e: Enum) -> GenericDef { + GenericDef::Enum(e) } } @@ -54,22 +61,13 @@ impl GenericParams { ) -> Arc { let mut generics = GenericParams::default(); match def { - GenericDef::Function(func) => { - let (_, fn_def) = func.source(db); - if let Some(type_param_list) = fn_def.type_param_list() { - generics.fill(type_param_list) - } - } - GenericDef::Struct(s) => { - let (_, struct_def) = s.source(db); - if let Some(type_param_list) = struct_def.type_param_list() { - generics.fill(type_param_list) - } - } + GenericDef::Function(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::Def(def_id) => { let (_file_id, node) = def_id.source(db); if let Some(type_param_list) = node.children().find_map(ast::TypeParamList::cast) { - generics.fill(type_param_list) + generics.fill_params(type_param_list) } } } @@ -77,7 +75,13 @@ impl GenericParams { Arc::new(generics) } - fn fill(&mut self, params: &ast::TypeParamList) { + fn fill(&mut self, node: &impl TypeParamsOwner) { + if let Some(params) = node.type_param_list() { + self.fill_params(params) + } + } + + fn fill_params(&mut self, params: &ast::TypeParamList) { for (idx, type_param) in params.type_params().enumerate() { let name = type_param .name() diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 530fdf5cd..332cec9c8 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs @@ -5,7 +5,7 @@ use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; use ra_arena::{Arena, RawId, impl_arena_id}; use crate::{ - HirDatabase, Def, Enum, EnumVariant, Crate, + HirDatabase, Def, EnumVariant, Crate, Module, Trait, Type, Static, Const, }; @@ -247,25 +247,22 @@ pub struct DefLoc { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub(crate) enum DefKind { - Struct, - Enum, EnumVariant, Const, Static, Trait, Type, Item, - - /// 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 - /// are in the types or values namespace: As a type, `Foo` of course refers - /// to the struct `Foo`; as a value, `Foo` is a callable type with signature - /// `(usize) -> Foo`. The cleanest approach to handle this seems to be to - /// have different defs in the two namespaces. - /// - /// rustc does the same; note that it even creates a struct constructor if - /// the struct isn't a tuple struct (see `CtorKind::Fictive` in rustc). - StructCtor, + // /// 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 + // /// are in the types or values namespace: As a type, `Foo` of course refers + // /// to the struct `Foo`; as a value, `Foo` is a callable type with signature + // /// `(usize) -> Foo`. The cleanest approach to handle this seems to be to + // /// have different defs in the two namespaces. + // /// + // /// rustc does the same; note that it even creates a struct constructor if + // /// the struct isn't a tuple struct (see `CtorKind::Fictive` in rustc). + // StructCtor, } impl DefId { @@ -276,8 +273,6 @@ impl DefId { pub fn resolve(self, db: &impl HirDatabase) -> Def { let loc = self.loc(db); match loc.kind { - DefKind::Struct => unreachable!(), - DefKind::Enum => Def::Enum(Enum::new(self)), DefKind::EnumVariant => Def::EnumVariant(EnumVariant::new(self)), DefKind::Const => { let def = Const::new(self); @@ -295,8 +290,6 @@ impl DefId { let def = Type::new(self); Def::Type(def) } - - DefKind::StructCtor => Def::Item, DefKind::Item => Def::Item, } } diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index b0c4aa819..435804e2d 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs @@ -10,7 +10,7 @@ use rustc_hash::FxHashMap; use crate::{ SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, Function, - ModuleDef, Module, Struct, + ModuleDef, Module, Struct, Enum, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -155,7 +155,14 @@ impl LoweredModule { } return; } - ast::ModuleItemKind::EnumDef(it) => it.name(), + ast::ModuleItemKind::EnumDef(it) => { + if let Some(name) = it.name() { + let e = Enum::from_ast(db, module, file_id, it); + let e: ModuleDef = e.into(); + self.declarations.insert(name.as_name(), PerNs::types(e)); + } + return; + } ast::ModuleItemKind::FnDef(it) => { if let Some(name) = it.name() { let func = Function::from_ast(db, module, file_id, it); @@ -233,8 +240,8 @@ impl DefKind { fn for_syntax_kind(kind: SyntaxKind) -> PerNs { match kind { SyntaxKind::FN_DEF => unreachable!(), - SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), - SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), + 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 => PerNs::values(DefKind::Const), diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index fc699a2ae..6a5f4fae6 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -166,27 +166,28 @@ impl Substs { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum AdtDef { Struct(Struct), - Def(DefId), // Enum + Enum(Enum), } impl From for AdtDef { - fn from(struct_: Struct) -> AdtDef { - AdtDef::Struct(struct_) + fn from(s: Struct) -> AdtDef { + AdtDef::Struct(s) } } -impl From for AdtDef { - fn from(def_id: DefId) -> AdtDef { - AdtDef::Def(def_id) +impl From for AdtDef { + fn from(e: Enum) -> AdtDef { + AdtDef::Enum(e) } } impl AdtDef { fn krate(self, db: &impl HirDatabase) -> Option { match self { - AdtDef::Struct(s) => s.module(db).krate(db), - AdtDef::Def(def_id) => def_id.krate(db), + AdtDef::Struct(s) => s.module(db), + AdtDef::Enum(e) => e.module(db), } + .krate(db) } } @@ -408,14 +409,16 @@ impl Ty { } // Resolve in module (in type namespace) - let resolved = match module.resolve_path(db, path).take_types() { - Some(ModuleDef::Def(r)) => r.into(), - Some(ModuleDef::Function(f)) => f.into(), - Some(ModuleDef::Struct(s)) => s.into(), - None | Some(ModuleDef::Module(_)) => return Ty::Unknown, + let typable: TypableDef = match module + .resolve_path(db, path) + .take_types() + .and_then(|it| it.into()) + { + None => return Ty::Unknown, + Some(it) => it, }; - let ty = db.type_for_def(resolved); - let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); + let ty = db.type_for_def(typable); + let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable); ty.apply_substs(substs) } @@ -438,9 +441,8 @@ impl Ty { let (def_generics, segment) = match resolved { TypableDef::Function(func) => (func.generic_params(db), last), TypableDef::Struct(s) => (s.generic_params(db), last), + TypableDef::Enum(e) => (e.generic_params(db), last), TypableDef::Def(def_id) => match def_id.resolve(db) { - Def::Struct(s) => (s.generic_params(db), last), - Def::Enum(e) => (e.generic_params(db), last), Def::Trait(t) => (t.generic_params(db), last), Def::EnumVariant(ev) => { // the generic args for an enum variant may be either specified @@ -680,7 +682,7 @@ fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { let generics = s.generic_params(db); Ty::Adt { - def_id: s.def_id().into(), + def_id: s.into(), name: s.name(db).unwrap_or_else(Name::missing), substs: make_substs(&generics), } @@ -696,6 +698,7 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T pub enum TypableDef { Function(Function), Struct(Struct), + Enum(Enum), Def(DefId), } @@ -706,8 +709,14 @@ impl From for TypableDef { } impl From for TypableDef { - fn from(struct_: Struct) -> TypableDef { - TypableDef::Struct(struct_) + fn from(s: Struct) -> TypableDef { + TypableDef::Struct(s) + } +} + +impl From for TypableDef { + fn from(e: Enum) -> TypableDef { + TypableDef::Enum(e) } } @@ -717,10 +726,24 @@ impl From for TypableDef { } } +impl From for Option { + fn from(def: ModuleDef) -> Option { + let res = match def { + ModuleDef::Def(r) => r.into(), + ModuleDef::Function(f) => f.into(), + ModuleDef::Struct(s) => s.into(), + ModuleDef::Enum(e) => e.into(), + ModuleDef::Module(_) => return None, + }; + Some(res) + } +} + pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { match def { TypableDef::Function(f) => type_for_fn(db, f), TypableDef::Struct(s) => type_for_struct(db, s), + TypableDef::Enum(e) => type_for_enum(db, e), TypableDef::Def(def_id) => match def_id.resolve(db) { Def::Enum(e) => type_for_enum(db, e), Def::EnumVariant(ev) => type_for_enum_variant(db, ev), @@ -1134,12 +1157,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { }; // resolve in module - let typable = match self.module.resolve_path(self.db, &path).take_values()? { - ModuleDef::Def(it) => it.into(), - ModuleDef::Function(func) => func.into(), - ModuleDef::Struct(s) => s.into(), - ModuleDef::Module(_) => return None, - }; + let typable: Option = self + .module + .resolve_path(self.db, &path) + .take_values()? + .into(); + let typable = typable?; let ty = self.db.type_for_def(typable); let ty = self.insert_type_vars(ty); Some(ty) @@ -1150,11 +1173,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Some(path) => path, None => return (Ty::Unknown, None), }; - let def = match self.module.resolve_path(self.db, &path).take_types() { - Some(ModuleDef::Def(def_id)) => def_id.into(), - Some(ModuleDef::Function(func)) => func.into(), - Some(ModuleDef::Struct(s)) => s.into(), - None | Some(ModuleDef::Module(_)) => return (Ty::Unknown, None), + let typable: Option = self + .module + .resolve_path(self.db, &path) + .take_types() + .and_then(|it| it.into()); + let def = match typable { + None => return (Ty::Unknown, None), + Some(it) => it, }; // TODO remove the duplication between here and `Ty::from_path`? // TODO provide generics of function @@ -1182,6 +1208,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let ty = self.insert_type_vars(ty.apply_substs(substs)); (ty, Some(s.into())) } + TypableDef::Enum(_) => (Ty::Unknown, None), } } @@ -1300,6 +1327,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ModuleDef::Def(it) => Some(it.into()), ModuleDef::Function(func) => Some(func.into()), ModuleDef::Struct(s) => Some(s.into()), + ModuleDef::Enum(e) => Some(e.into()), ModuleDef::Module(_) => None, }) .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index bcbd4c60c..fd65264b2 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -430,6 +430,13 @@ impl StructDef { } impl EnumVariant { + pub fn parent_enum(&self) -> &EnumDef { + self.syntax() + .parent() + .and_then(|it| it.parent()) + .and_then(EnumDef::cast) + .expect("EnumVariants are always nested in Enums") + } pub fn flavor(&self) -> StructFlavor { StructFlavor::from_node(self) } -- cgit v1.2.3