aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-24 15:56:38 +0000
committerAleksey Kladov <[email protected]>2019-01-24 15:56:38 +0000
commit566c8e321e89e5ff8996daa615cc47aea0012881 (patch)
tree58c2f4741b9305e840d41eb35eb8f4e7d5761fe2 /crates
parentcefc5cbb4a95d2a473ea656efe603bef979b5c49 (diff)
migrate enums to new id
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/adt.rs54
-rw-r--r--crates/ra_hir/src/code_model_api.rs53
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs42
-rw-r--r--crates/ra_hir/src/db.rs6
-rw-r--r--crates/ra_hir/src/generics.rs38
-rw-r--r--crates/ra_hir/src/ids.rs29
-rw-r--r--crates/ra_hir/src/nameres/lower.rs15
-rw-r--r--crates/ra_hir/src/ty.rs90
-rw-r--r--crates/ra_syntax/src/ast.rs7
9 files changed, 191 insertions, 143 deletions
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::{
13 HirDatabase, DefKind, 13 HirDatabase, DefKind,
14 SourceItemId, 14 SourceItemId,
15 type_ref::TypeRef, 15 type_ref::TypeRef,
16 ids::{StructLoc}, 16 ids::{StructLoc, EnumLoc},
17}; 17};
18 18
19impl Struct { 19impl Struct {
@@ -33,6 +33,19 @@ impl Struct {
33 } 33 }
34} 34}
35 35
36impl Enum {
37 pub(crate) fn from_ast(
38 db: &impl HirDatabase,
39 module: Module,
40 file_id: HirFileId,
41 ast: &ast::EnumDef,
42 ) -> Enum {
43 let loc: EnumLoc = EnumLoc::from_ast(db, module, file_id, ast);
44 let id = loc.id(db);
45 Enum { id }
46 }
47}
48
36#[derive(Debug, Clone, PartialEq, Eq)] 49#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct StructData { 50pub struct StructData {
38 pub(crate) name: Option<Name>, 51 pub(crate) name: Option<Name>,
@@ -55,20 +68,20 @@ impl StructData {
55 68
56fn get_def_id( 69fn get_def_id(
57 db: &impl HirDatabase, 70 db: &impl HirDatabase,
58 same_file_loc: &DefLoc, 71 module: Module,
72 file_id: HirFileId,
59 node: &SyntaxNode, 73 node: &SyntaxNode,
60 expected_kind: DefKind, 74 expected_kind: DefKind,
61) -> DefId { 75) -> DefId {
62 let file_id = same_file_loc.source_item_id.file_id;
63 let file_items = db.file_items(file_id); 76 let file_items = db.file_items(file_id);
64 77
65 let item_id = file_items.id_of(file_id, node); 78 let item_id = file_items.id_of(file_id, node);
66 let source_item_id = SourceItemId { 79 let source_item_id = SourceItemId {
80 file_id,
67 item_id: Some(item_id), 81 item_id: Some(item_id),
68 ..same_file_loc.source_item_id
69 }; 82 };
70 let loc = DefLoc { 83 let loc = DefLoc {
71 module: same_file_loc.module, 84 module,
72 kind: expected_kind, 85 kind: expected_kind,
73 source_item_id, 86 source_item_id,
74 }; 87 };
@@ -87,19 +100,22 @@ impl EnumData {
87 EnumData { name, variants } 100 EnumData { name, variants }
88 } 101 }
89 102
90 pub(crate) fn enum_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc<EnumData> { 103 pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> {
91 let def_loc = def_id.loc(db); 104 let (file_id, enum_def) = e.source(db);
92 assert!(def_loc.kind == DefKind::Enum); 105 let module = e.module(db);
93 let syntax = db.file_item(def_loc.source_item_id);
94 let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
95 let variants = if let Some(vl) = enum_def.variant_list() { 106 let variants = if let Some(vl) = enum_def.variant_list() {
96 vl.variants() 107 vl.variants()
97 .filter_map(|variant_def| { 108 .filter_map(|variant_def| {
98 let name = variant_def.name().map(|n| n.as_name()); 109 let name = variant_def.name().map(|n| n.as_name());
99 110
100 name.map(|n| { 111 name.map(|n| {
101 let def_id = 112 let def_id = get_def_id(
102 get_def_id(db, &def_loc, variant_def.syntax(), DefKind::EnumVariant); 113 db,
114 module,
115 file_id,
116 variant_def.syntax(),
117 DefKind::EnumVariant,
118 );
103 (n, EnumVariant::new(def_id)) 119 (n, EnumVariant::new(def_id))
104 }) 120 })
105 }) 121 })
@@ -107,7 +123,7 @@ impl EnumData {
107 } else { 123 } else {
108 Vec::new() 124 Vec::new()
109 }; 125 };
110 Arc::new(EnumData::new(enum_def, variants)) 126 Arc::new(EnumData::new(&*enum_def, variants))
111 } 127 }
112} 128}
113 129
@@ -139,14 +155,10 @@ impl EnumVariantData {
139 let syntax = db.file_item(def_loc.source_item_id); 155 let syntax = db.file_item(def_loc.source_item_id);
140 let variant_def = ast::EnumVariant::cast(&syntax) 156 let variant_def = ast::EnumVariant::cast(&syntax)
141 .expect("enum variant def should point to EnumVariant node"); 157 .expect("enum variant def should point to EnumVariant node");
142 let enum_node = syntax 158 let enum_def = variant_def.parent_enum();
143 .parent() 159 let e = Enum::from_ast(db, def_loc.module, def_loc.source_item_id.file_id, enum_def);
144 .expect("enum variant should have enum variant list ancestor") 160
145 .parent() 161 Arc::new(EnumVariantData::new(variant_def, e))
146 .expect("enum variant list should have enum ancestor");
147 let enum_def_id = get_def_id(db, &def_loc, enum_node, DefKind::Enum);
148
149 Arc::new(EnumVariantData::new(variant_def, Enum::new(enum_def_id)))
150 } 162 }
151} 163}
152 164
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::{
16 code_model_impl::def_id_to_ast, 16 code_model_impl::def_id_to_ast,
17 docs::{Documentation, Docs, docs_from_ast}, 17 docs::{Documentation, Docs, docs_from_ast},
18 module_tree::ModuleId, 18 module_tree::ModuleId,
19 ids::{FunctionId, StructId}, 19 ids::{FunctionId, StructId, EnumId},
20}; 20};
21 21
22/// hir::Crate describes a single crate. It's the main interface with which 22/// hir::Crate describes a single crate. It's the main interface with which
@@ -69,30 +69,37 @@ pub enum ModuleDef {
69 Module(Module), 69 Module(Module),
70 Function(Function), 70 Function(Function),
71 Struct(Struct), 71 Struct(Struct),
72 Enum(Enum),
72 Def(DefId), 73 Def(DefId),
73} 74}
75//FIXME: change to from
76impl From<Module> for ModuleDef {
77 fn from(it: Module) -> ModuleDef {
78 ModuleDef::Module(it)
79 }
80}
74 81
75impl Into<ModuleDef> for Module { 82impl From<Function> for ModuleDef {
76 fn into(self) -> ModuleDef { 83 fn from(it: Function) -> ModuleDef {
77 ModuleDef::Module(self) 84 ModuleDef::Function(it)
78 } 85 }
79} 86}
80 87
81impl Into<ModuleDef> for Function { 88impl From<Struct> for ModuleDef {
82 fn into(self) -> ModuleDef { 89 fn from(it: Struct) -> ModuleDef {
83 ModuleDef::Function(self) 90 ModuleDef::Struct(it)
84 } 91 }
85} 92}
86 93
87impl Into<ModuleDef> for Struct { 94impl From<Enum> for ModuleDef {
88 fn into(self) -> ModuleDef { 95 fn from(it: Enum) -> ModuleDef {
89 ModuleDef::Struct(self) 96 ModuleDef::Enum(it)
90 } 97 }
91} 98}
92 99
93impl Into<ModuleDef> for DefId { 100impl From<DefId> for ModuleDef {
94 fn into(self) -> ModuleDef { 101 fn from(it: DefId) -> ModuleDef {
95 ModuleDef::Def(self) 102 ModuleDef::Def(it)
96 } 103 }
97} 104}
98 105
@@ -249,34 +256,30 @@ impl Docs for Struct {
249 } 256 }
250} 257}
251 258
252#[derive(Debug, Clone, PartialEq, Eq, Hash)] 259#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
253pub struct Enum { 260pub struct Enum {
254 pub(crate) def_id: DefId, 261 pub(crate) id: EnumId,
255} 262}
256 263
257impl Enum { 264impl Enum {
258 pub(crate) fn new(def_id: DefId) -> Self { 265 pub fn module(&self, db: &impl HirDatabase) -> Module {
259 Enum { def_id } 266 self.id.loc(db).module
260 }
261
262 pub fn def_id(&self) -> DefId {
263 self.def_id
264 } 267 }
265 268
266 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { 269 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
267 db.enum_data(self.def_id).name.clone() 270 db.enum_data(*self).name.clone()
268 } 271 }
269 272
270 pub fn variants(&self, db: &impl HirDatabase) -> Vec<(Name, EnumVariant)> { 273 pub fn variants(&self, db: &impl HirDatabase) -> Vec<(Name, EnumVariant)> {
271 db.enum_data(self.def_id).variants.clone() 274 db.enum_data(*self).variants.clone()
272 } 275 }
273 276
274 pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) { 277 pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
275 def_id_to_ast(db, self.def_id) 278 self.id.loc(db).source(db)
276 } 279 }
277 280
278 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { 281 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
279 db.generic_params(self.def_id.into()) 282 db.generic_params((*self).into())
280 } 283 }
281} 284}
282 285
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};
3 3
4use crate::{ 4use crate::{
5 Module, ModuleSource, Problem, ModuleDef, 5 Module, ModuleSource, Problem, ModuleDef,
6 Crate, Name, Path, PathKind, PerNs, Def, 6 Crate, Name, Path, PathKind, PerNs,
7 module_tree::ModuleId, 7 module_tree::ModuleId,
8 nameres::{ModuleScope, lower::ImportId}, 8 nameres::{ModuleScope, lower::ImportId},
9 db::HirDatabase, 9 db::HirDatabase,
@@ -135,31 +135,25 @@ impl Module {
135 None => PerNs::none(), 135 None => PerNs::none(),
136 } 136 }
137 } 137 }
138 ModuleDef::Function(_) | ModuleDef::Struct(_) => PerNs::none(), 138 ModuleDef::Enum(e) => {
139 ModuleDef::Def(def) => { 139 // enum variant
140 match def.resolve(db) { 140 let matching_variant = e
141 Def::Enum(e) => { 141 .variants(db)
142 // enum variant 142 .into_iter()
143 let matching_variant = e 143 .find(|(n, _variant)| n == &segment.name);
144 .variants(db) 144
145 .into_iter() 145 match matching_variant {
146 .find(|(n, _variant)| n == &segment.name); 146 Some((_n, variant)) => PerNs::both(variant.def_id().into(), (*e).into()),
147 147 None => PerNs::none(),
148 match matching_variant {
149 Some((_n, variant)) => {
150 PerNs::both(variant.def_id().into(), e.def_id().into())
151 }
152 None => PerNs::none(),
153 }
154 }
155 _ => {
156 // could be an inherent method call in UFCS form
157 // (`Struct::method`), or some other kind of associated
158 // item... Which we currently don't handle (TODO)
159 PerNs::none()
160 }
161 } 148 }
162 } 149 }
150 ModuleDef::Function(_) | ModuleDef::Struct(_) => {
151 // could be an inherent method call in UFCS form
152 // (`Struct::method`), or some other kind of associated
153 // item... Which we currently don't handle (TODO)
154 PerNs::none()
155 }
156 ModuleDef::Def(_) => PerNs::none(),
163 }; 157 };
164 } 158 }
165 curr_per_ns 159 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::{
8 SourceFileItems, SourceItemId, Crate, Module, HirInterner, 8 SourceFileItems, SourceItemId, Crate, Module, HirInterner,
9 query_definitions, 9 query_definitions,
10 Function, FnSignature, FnScopes, 10 Function, FnSignature, FnScopes,
11 Struct, 11 Struct, Enum,
12 macros::MacroExpansion, 12 macros::MacroExpansion,
13 module_tree::ModuleTree, 13 module_tree::ModuleTree,
14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, 14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
@@ -30,10 +30,10 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> {
30 fn fn_scopes(&self, func: Function) -> Arc<FnScopes>; 30 fn fn_scopes(&self, func: Function) -> Arc<FnScopes>;
31 31
32 #[salsa::invoke(crate::adt::StructData::struct_data_query)] 32 #[salsa::invoke(crate::adt::StructData::struct_data_query)]
33 fn struct_data(&self, struct_: Struct) -> Arc<StructData>; 33 fn struct_data(&self, s: Struct) -> Arc<StructData>;
34 34
35 #[salsa::invoke(crate::adt::EnumData::enum_data_query)] 35 #[salsa::invoke(crate::adt::EnumData::enum_data_query)]
36 fn enum_data(&self, def_id: DefId) -> Arc<EnumData>; 36 fn enum_data(&self, e: Enum) -> Arc<EnumData>;
37 37
38 #[salsa::invoke(crate::adt::EnumVariantData::enum_variant_data_query)] 38 #[salsa::invoke(crate::adt::EnumVariantData::enum_variant_data_query)]
39 fn enum_variant_data(&self, def_id: DefId) -> Arc<EnumVariantData>; 39 fn enum_variant_data(&self, def_id: DefId) -> Arc<EnumVariantData>;
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;
7 7
8use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner}; 8use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner};
9 9
10use crate::{db::HirDatabase, DefId, Name, AsName, Function, Struct}; 10use crate::{db::HirDatabase, DefId, Name, AsName, Function, Struct, Enum};
11 11
12/// Data about a generic parameter (to a function, struct, impl, ...). 12/// Data about a generic parameter (to a function, struct, impl, ...).
13#[derive(Clone, PartialEq, Eq, Debug)] 13#[derive(Clone, PartialEq, Eq, Debug)]
@@ -26,6 +26,7 @@ pub struct GenericParams {
26pub enum GenericDef { 26pub enum GenericDef {
27 Function(Function), 27 Function(Function),
28 Struct(Struct), 28 Struct(Struct),
29 Enum(Enum),
29 Def(DefId), 30 Def(DefId),
30} 31}
31 32
@@ -36,8 +37,14 @@ impl From<Function> for GenericDef {
36} 37}
37 38
38impl From<Struct> for GenericDef { 39impl From<Struct> for GenericDef {
39 fn from(func: Struct) -> GenericDef { 40 fn from(s: Struct) -> GenericDef {
40 GenericDef::Struct(func) 41 GenericDef::Struct(s)
42 }
43}
44
45impl From<Enum> for GenericDef {
46 fn from(e: Enum) -> GenericDef {
47 GenericDef::Enum(e)
41 } 48 }
42} 49}
43 50
@@ -54,22 +61,13 @@ impl GenericParams {
54 ) -> Arc<GenericParams> { 61 ) -> Arc<GenericParams> {
55 let mut generics = GenericParams::default(); 62 let mut generics = GenericParams::default();
56 match def { 63 match def {
57 GenericDef::Function(func) => { 64 GenericDef::Function(it) => generics.fill(&*it.source(db).1),
58 let (_, fn_def) = func.source(db); 65 GenericDef::Struct(it) => generics.fill(&*it.source(db).1),
59 if let Some(type_param_list) = fn_def.type_param_list() { 66 GenericDef::Enum(it) => generics.fill(&*it.source(db).1),
60 generics.fill(type_param_list)
61 }
62 }
63 GenericDef::Struct(s) => {
64 let (_, struct_def) = s.source(db);
65 if let Some(type_param_list) = struct_def.type_param_list() {
66 generics.fill(type_param_list)
67 }
68 }
69 GenericDef::Def(def_id) => { 67 GenericDef::Def(def_id) => {
70 let (_file_id, node) = def_id.source(db); 68 let (_file_id, node) = def_id.source(db);
71 if let Some(type_param_list) = node.children().find_map(ast::TypeParamList::cast) { 69 if let Some(type_param_list) = node.children().find_map(ast::TypeParamList::cast) {
72 generics.fill(type_param_list) 70 generics.fill_params(type_param_list)
73 } 71 }
74 } 72 }
75 } 73 }
@@ -77,7 +75,13 @@ impl GenericParams {
77 Arc::new(generics) 75 Arc::new(generics)
78 } 76 }
79 77
80 fn fill(&mut self, params: &ast::TypeParamList) { 78 fn fill(&mut self, node: &impl TypeParamsOwner) {
79 if let Some(params) = node.type_param_list() {
80 self.fill_params(params)
81 }
82 }
83
84 fn fill_params(&mut self, params: &ast::TypeParamList) {
81 for (idx, type_param) in params.type_params().enumerate() { 85 for (idx, type_param) in params.type_params().enumerate() {
82 let name = type_param 86 let name = type_param
83 .name() 87 .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};
5use ra_arena::{Arena, RawId, impl_arena_id}; 5use ra_arena::{Arena, RawId, impl_arena_id};
6 6
7use crate::{ 7use crate::{
8 HirDatabase, Def, Enum, EnumVariant, Crate, 8 HirDatabase, Def, EnumVariant, Crate,
9 Module, Trait, Type, Static, Const, 9 Module, Trait, Type, Static, Const,
10}; 10};
11 11
@@ -247,25 +247,22 @@ pub struct DefLoc {
247 247
248#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 248#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
249pub(crate) enum DefKind { 249pub(crate) enum DefKind {
250 Struct,
251 Enum,
252 EnumVariant, 250 EnumVariant,
253 Const, 251 Const,
254 Static, 252 Static,
255 Trait, 253 Trait,
256 Type, 254 Type,
257 Item, 255 Item,
258 256 // /// The constructor of a struct. E.g. if we have `struct Foo(usize)`, the
259 /// The constructor of a struct. E.g. if we have `struct Foo(usize)`, the 257 // /// name `Foo` needs to resolve to different types depending on whether we
260 /// name `Foo` needs to resolve to different types depending on whether we 258 // /// are in the types or values namespace: As a type, `Foo` of course refers
261 /// are in the types or values namespace: As a type, `Foo` of course refers 259 // /// to the struct `Foo`; as a value, `Foo` is a callable type with signature
262 /// to the struct `Foo`; as a value, `Foo` is a callable type with signature 260 // /// `(usize) -> Foo`. The cleanest approach to handle this seems to be to
263 /// `(usize) -> Foo`. The cleanest approach to handle this seems to be to 261 // /// have different defs in the two namespaces.
264 /// have different defs in the two namespaces. 262 // ///
265 /// 263 // /// rustc does the same; note that it even creates a struct constructor if
266 /// rustc does the same; note that it even creates a struct constructor if 264 // /// the struct isn't a tuple struct (see `CtorKind::Fictive` in rustc).
267 /// the struct isn't a tuple struct (see `CtorKind::Fictive` in rustc). 265 // StructCtor,
268 StructCtor,
269} 266}
270 267
271impl DefId { 268impl DefId {
@@ -276,8 +273,6 @@ impl DefId {
276 pub fn resolve(self, db: &impl HirDatabase) -> Def { 273 pub fn resolve(self, db: &impl HirDatabase) -> Def {
277 let loc = self.loc(db); 274 let loc = self.loc(db);
278 match loc.kind { 275 match loc.kind {
279 DefKind::Struct => unreachable!(),
280 DefKind::Enum => Def::Enum(Enum::new(self)),
281 DefKind::EnumVariant => Def::EnumVariant(EnumVariant::new(self)), 276 DefKind::EnumVariant => Def::EnumVariant(EnumVariant::new(self)),
282 DefKind::Const => { 277 DefKind::Const => {
283 let def = Const::new(self); 278 let def = Const::new(self);
@@ -295,8 +290,6 @@ impl DefId {
295 let def = Type::new(self); 290 let def = Type::new(self);
296 Def::Type(def) 291 Def::Type(def)
297 } 292 }
298
299 DefKind::StructCtor => Def::Item,
300 DefKind::Item => Def::Item, 293 DefKind::Item => Def::Item,
301 } 294 }
302 } 295 }
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;
10use crate::{ 10use crate::{
11 SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, 11 SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems,
12 HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, Function, 12 HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, Function,
13 ModuleDef, Module, Struct, 13 ModuleDef, Module, Struct, Enum,
14}; 14};
15 15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -155,7 +155,14 @@ impl LoweredModule {
155 } 155 }
156 return; 156 return;
157 } 157 }
158 ast::ModuleItemKind::EnumDef(it) => it.name(), 158 ast::ModuleItemKind::EnumDef(it) => {
159 if let Some(name) = it.name() {
160 let e = Enum::from_ast(db, module, file_id, it);
161 let e: ModuleDef = e.into();
162 self.declarations.insert(name.as_name(), PerNs::types(e));
163 }
164 return;
165 }
159 ast::ModuleItemKind::FnDef(it) => { 166 ast::ModuleItemKind::FnDef(it) => {
160 if let Some(name) = it.name() { 167 if let Some(name) = it.name() {
161 let func = Function::from_ast(db, module, file_id, it); 168 let func = Function::from_ast(db, module, file_id, it);
@@ -233,8 +240,8 @@ impl DefKind {
233 fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { 240 fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> {
234 match kind { 241 match kind {
235 SyntaxKind::FN_DEF => unreachable!(), 242 SyntaxKind::FN_DEF => unreachable!(),
236 SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), 243 SyntaxKind::STRUCT_DEF => unreachable!(),
237 SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), 244 SyntaxKind::ENUM_DEF => unreachable!(),
238 SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait), 245 SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait),
239 SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Type), 246 SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Type),
240 SyntaxKind::CONST_DEF => PerNs::values(DefKind::Const), 247 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 {
166#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 166#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
167pub enum AdtDef { 167pub enum AdtDef {
168 Struct(Struct), 168 Struct(Struct),
169 Def(DefId), // Enum 169 Enum(Enum),
170} 170}
171 171
172impl From<Struct> for AdtDef { 172impl From<Struct> for AdtDef {
173 fn from(struct_: Struct) -> AdtDef { 173 fn from(s: Struct) -> AdtDef {
174 AdtDef::Struct(struct_) 174 AdtDef::Struct(s)
175 } 175 }
176} 176}
177 177
178impl From<DefId> for AdtDef { 178impl From<Enum> for AdtDef {
179 fn from(def_id: DefId) -> AdtDef { 179 fn from(e: Enum) -> AdtDef {
180 AdtDef::Def(def_id) 180 AdtDef::Enum(e)
181 } 181 }
182} 182}
183 183
184impl AdtDef { 184impl AdtDef {
185 fn krate(self, db: &impl HirDatabase) -> Option<Crate> { 185 fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
186 match self { 186 match self {
187 AdtDef::Struct(s) => s.module(db).krate(db), 187 AdtDef::Struct(s) => s.module(db),
188 AdtDef::Def(def_id) => def_id.krate(db), 188 AdtDef::Enum(e) => e.module(db),
189 } 189 }
190 .krate(db)
190 } 191 }
191} 192}
192 193
@@ -408,14 +409,16 @@ impl Ty {
408 } 409 }
409 410
410 // Resolve in module (in type namespace) 411 // Resolve in module (in type namespace)
411 let resolved = match module.resolve_path(db, path).take_types() { 412 let typable: TypableDef = match module
412 Some(ModuleDef::Def(r)) => r.into(), 413 .resolve_path(db, path)
413 Some(ModuleDef::Function(f)) => f.into(), 414 .take_types()
414 Some(ModuleDef::Struct(s)) => s.into(), 415 .and_then(|it| it.into())
415 None | Some(ModuleDef::Module(_)) => return Ty::Unknown, 416 {
417 None => return Ty::Unknown,
418 Some(it) => it,
416 }; 419 };
417 let ty = db.type_for_def(resolved); 420 let ty = db.type_for_def(typable);
418 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); 421 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable);
419 ty.apply_substs(substs) 422 ty.apply_substs(substs)
420 } 423 }
421 424
@@ -438,9 +441,8 @@ impl Ty {
438 let (def_generics, segment) = match resolved { 441 let (def_generics, segment) = match resolved {
439 TypableDef::Function(func) => (func.generic_params(db), last), 442 TypableDef::Function(func) => (func.generic_params(db), last),
440 TypableDef::Struct(s) => (s.generic_params(db), last), 443 TypableDef::Struct(s) => (s.generic_params(db), last),
444 TypableDef::Enum(e) => (e.generic_params(db), last),
441 TypableDef::Def(def_id) => match def_id.resolve(db) { 445 TypableDef::Def(def_id) => match def_id.resolve(db) {
442 Def::Struct(s) => (s.generic_params(db), last),
443 Def::Enum(e) => (e.generic_params(db), last),
444 Def::Trait(t) => (t.generic_params(db), last), 446 Def::Trait(t) => (t.generic_params(db), last),
445 Def::EnumVariant(ev) => { 447 Def::EnumVariant(ev) => {
446 // the generic args for an enum variant may be either specified 448 // 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 {
680pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { 682pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
681 let generics = s.generic_params(db); 683 let generics = s.generic_params(db);
682 Ty::Adt { 684 Ty::Adt {
683 def_id: s.def_id().into(), 685 def_id: s.into(),
684 name: s.name(db).unwrap_or_else(Name::missing), 686 name: s.name(db).unwrap_or_else(Name::missing),
685 substs: make_substs(&generics), 687 substs: make_substs(&generics),
686 } 688 }
@@ -696,6 +698,7 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T
696pub enum TypableDef { 698pub enum TypableDef {
697 Function(Function), 699 Function(Function),
698 Struct(Struct), 700 Struct(Struct),
701 Enum(Enum),
699 Def(DefId), 702 Def(DefId),
700} 703}
701 704
@@ -706,8 +709,14 @@ impl From<Function> for TypableDef {
706} 709}
707 710
708impl From<Struct> for TypableDef { 711impl From<Struct> for TypableDef {
709 fn from(struct_: Struct) -> TypableDef { 712 fn from(s: Struct) -> TypableDef {
710 TypableDef::Struct(struct_) 713 TypableDef::Struct(s)
714 }
715}
716
717impl From<Enum> for TypableDef {
718 fn from(e: Enum) -> TypableDef {
719 TypableDef::Enum(e)
711 } 720 }
712} 721}
713 722
@@ -717,10 +726,24 @@ impl From<DefId> for TypableDef {
717 } 726 }
718} 727}
719 728
729impl From<ModuleDef> for Option<TypableDef> {
730 fn from(def: ModuleDef) -> Option<TypableDef> {
731 let res = match def {
732 ModuleDef::Def(r) => r.into(),
733 ModuleDef::Function(f) => f.into(),
734 ModuleDef::Struct(s) => s.into(),
735 ModuleDef::Enum(e) => e.into(),
736 ModuleDef::Module(_) => return None,
737 };
738 Some(res)
739 }
740}
741
720pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { 742pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
721 match def { 743 match def {
722 TypableDef::Function(f) => type_for_fn(db, f), 744 TypableDef::Function(f) => type_for_fn(db, f),
723 TypableDef::Struct(s) => type_for_struct(db, s), 745 TypableDef::Struct(s) => type_for_struct(db, s),
746 TypableDef::Enum(e) => type_for_enum(db, e),
724 TypableDef::Def(def_id) => match def_id.resolve(db) { 747 TypableDef::Def(def_id) => match def_id.resolve(db) {
725 Def::Enum(e) => type_for_enum(db, e), 748 Def::Enum(e) => type_for_enum(db, e),
726 Def::EnumVariant(ev) => type_for_enum_variant(db, ev), 749 Def::EnumVariant(ev) => type_for_enum_variant(db, ev),
@@ -1134,12 +1157,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1134 }; 1157 };
1135 1158
1136 // resolve in module 1159 // resolve in module
1137 let typable = match self.module.resolve_path(self.db, &path).take_values()? { 1160 let typable: Option<TypableDef> = self
1138 ModuleDef::Def(it) => it.into(), 1161 .module
1139 ModuleDef::Function(func) => func.into(), 1162 .resolve_path(self.db, &path)
1140 ModuleDef::Struct(s) => s.into(), 1163 .take_values()?
1141 ModuleDef::Module(_) => return None, 1164 .into();
1142 }; 1165 let typable = typable?;
1143 let ty = self.db.type_for_def(typable); 1166 let ty = self.db.type_for_def(typable);
1144 let ty = self.insert_type_vars(ty); 1167 let ty = self.insert_type_vars(ty);
1145 Some(ty) 1168 Some(ty)
@@ -1150,11 +1173,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1150 Some(path) => path, 1173 Some(path) => path,
1151 None => return (Ty::Unknown, None), 1174 None => return (Ty::Unknown, None),
1152 }; 1175 };
1153 let def = match self.module.resolve_path(self.db, &path).take_types() { 1176 let typable: Option<TypableDef> = self
1154 Some(ModuleDef::Def(def_id)) => def_id.into(), 1177 .module
1155 Some(ModuleDef::Function(func)) => func.into(), 1178 .resolve_path(self.db, &path)
1156 Some(ModuleDef::Struct(s)) => s.into(), 1179 .take_types()
1157 None | Some(ModuleDef::Module(_)) => return (Ty::Unknown, None), 1180 .and_then(|it| it.into());
1181 let def = match typable {
1182 None => return (Ty::Unknown, None),
1183 Some(it) => it,
1158 }; 1184 };
1159 // TODO remove the duplication between here and `Ty::from_path`? 1185 // TODO remove the duplication between here and `Ty::from_path`?
1160 // TODO provide generics of function 1186 // TODO provide generics of function
@@ -1182,6 +1208,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1182 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1208 let ty = self.insert_type_vars(ty.apply_substs(substs));
1183 (ty, Some(s.into())) 1209 (ty, Some(s.into()))
1184 } 1210 }
1211 TypableDef::Enum(_) => (Ty::Unknown, None),
1185 } 1212 }
1186 } 1213 }
1187 1214
@@ -1300,6 +1327,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1300 ModuleDef::Def(it) => Some(it.into()), 1327 ModuleDef::Def(it) => Some(it.into()),
1301 ModuleDef::Function(func) => Some(func.into()), 1328 ModuleDef::Function(func) => Some(func.into()),
1302 ModuleDef::Struct(s) => Some(s.into()), 1329 ModuleDef::Struct(s) => Some(s.into()),
1330 ModuleDef::Enum(e) => Some(e.into()),
1303 ModuleDef::Module(_) => None, 1331 ModuleDef::Module(_) => None,
1304 }) 1332 })
1305 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), 1333 .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 {
430} 430}
431 431
432impl EnumVariant { 432impl EnumVariant {
433 pub fn parent_enum(&self) -> &EnumDef {
434 self.syntax()
435 .parent()
436 .and_then(|it| it.parent())
437 .and_then(EnumDef::cast)
438 .expect("EnumVariants are always nested in Enums")
439 }
433 pub fn flavor(&self) -> StructFlavor { 440 pub fn flavor(&self) -> StructFlavor {
434 StructFlavor::from_node(self) 441 StructFlavor::from_node(self)
435 } 442 }