diff options
author | Aleksey Kladov <[email protected]> | 2019-01-24 20:32:41 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-24 20:32:41 +0000 |
commit | 4c514a3e02b019cdd3a17c9bcd78d93c210ab267 (patch) | |
tree | acd4a571cec5c44d1ccbc705578f47a898da4139 /crates/ra_hir/src | |
parent | 11dda8a0fb905a1b41a64001d564632eb062b9aa (diff) |
move enum variant to the new API
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 64 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 121 |
6 files changed, 97 insertions, 142 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index 17ece93a7..b2631d6a6 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -4,14 +4,12 @@ | |||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | SyntaxNode, | 7 | ast::{self, NameOwner, StructFlavor} |
8 | ast::{self, NameOwner, StructFlavor, AstNode} | ||
9 | }; | 8 | }; |
10 | 9 | ||
11 | use crate::{ | 10 | use crate::{ |
12 | DefId, DefLoc, Name, AsName, Struct, Enum, EnumVariant, Module, HirFileId, | 11 | Name, AsName, Struct, Enum, EnumVariant, Module, HirFileId, |
13 | HirDatabase, DefKind, | 12 | HirDatabase, |
14 | SourceItemId, | ||
15 | type_ref::TypeRef, | 13 | type_ref::TypeRef, |
16 | ids::ItemLoc, | 14 | ids::ItemLoc, |
17 | }; | 15 | }; |
@@ -66,26 +64,17 @@ impl StructData { | |||
66 | } | 64 | } |
67 | } | 65 | } |
68 | 66 | ||
69 | fn get_def_id( | 67 | impl EnumVariant { |
70 | db: &impl HirDatabase, | 68 | pub(crate) fn from_ast( |
71 | module: Module, | 69 | db: &impl HirDatabase, |
72 | file_id: HirFileId, | 70 | module: Module, |
73 | node: &SyntaxNode, | 71 | file_id: HirFileId, |
74 | expected_kind: DefKind, | 72 | ast: &ast::EnumVariant, |
75 | ) -> DefId { | 73 | ) -> EnumVariant { |
76 | let file_items = db.file_items(file_id); | 74 | let loc = ItemLoc::from_ast(db, module, file_id, ast); |
77 | 75 | let id = db.as_ref().enum_variants.loc2id(&loc); | |
78 | let item_id = file_items.id_of(file_id, node); | 76 | EnumVariant { id } |
79 | let source_item_id = SourceItemId { | 77 | } |
80 | file_id, | ||
81 | item_id: Some(item_id), | ||
82 | }; | ||
83 | let loc = DefLoc { | ||
84 | module, | ||
85 | kind: expected_kind, | ||
86 | source_item_id, | ||
87 | }; | ||
88 | loc.id(db) | ||
89 | } | 78 | } |
90 | 79 | ||
91 | #[derive(Debug, Clone, PartialEq, Eq)] | 80 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -107,17 +96,7 @@ impl EnumData { | |||
107 | vl.variants() | 96 | vl.variants() |
108 | .filter_map(|variant_def| { | 97 | .filter_map(|variant_def| { |
109 | let name = variant_def.name().map(|n| n.as_name()); | 98 | let name = variant_def.name().map(|n| n.as_name()); |
110 | 99 | name.map(|n| (n, EnumVariant::from_ast(db, module, file_id, variant_def))) | |
111 | name.map(|n| { | ||
112 | let def_id = get_def_id( | ||
113 | db, | ||
114 | module, | ||
115 | file_id, | ||
116 | variant_def.syntax(), | ||
117 | DefKind::EnumVariant, | ||
118 | ); | ||
119 | (n, EnumVariant::new(def_id)) | ||
120 | }) | ||
121 | }) | 100 | }) |
122 | .collect() | 101 | .collect() |
123 | } else { | 102 | } else { |
@@ -148,17 +127,12 @@ impl EnumVariantData { | |||
148 | 127 | ||
149 | pub(crate) fn enum_variant_data_query( | 128 | pub(crate) fn enum_variant_data_query( |
150 | db: &impl HirDatabase, | 129 | db: &impl HirDatabase, |
151 | def_id: DefId, | 130 | var: EnumVariant, |
152 | ) -> Arc<EnumVariantData> { | 131 | ) -> Arc<EnumVariantData> { |
153 | let def_loc = def_id.loc(db); | 132 | let (file_id, variant_def) = var.source(db); |
154 | assert!(def_loc.kind == DefKind::EnumVariant); | ||
155 | let syntax = db.file_item(def_loc.source_item_id); | ||
156 | let variant_def = ast::EnumVariant::cast(&syntax) | ||
157 | .expect("enum variant def should point to EnumVariant node"); | ||
158 | let enum_def = variant_def.parent_enum(); | 133 | let enum_def = variant_def.parent_enum(); |
159 | let e = Enum::from_ast(db, def_loc.module, def_loc.source_item_id.file_id, enum_def); | 134 | let e = Enum::from_ast(db, var.module(db), file_id, enum_def); |
160 | 135 | Arc::new(EnumVariantData::new(&*variant_def, e)) | |
161 | Arc::new(EnumVariantData::new(variant_def, e)) | ||
162 | } | 136 | } |
163 | } | 137 | } |
164 | 138 | ||
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 4b79358e4..5e927e41d 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, EnumId}, | 19 | ids::{FunctionId, StructId, EnumId, EnumVariantId}, |
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 |
@@ -68,9 +68,11 @@ pub enum ModuleDef { | |||
68 | Function(Function), | 68 | Function(Function), |
69 | Struct(Struct), | 69 | Struct(Struct), |
70 | Enum(Enum), | 70 | Enum(Enum), |
71 | // Can't be directly declared, but can be imported. | ||
72 | EnumVariant(EnumVariant), | ||
71 | Def(DefId), | 73 | Def(DefId), |
72 | } | 74 | } |
73 | impl_froms!(ModuleDef: Module, Function, Struct, Enum); | 75 | impl_froms!(ModuleDef: Module, Function, Struct, Enum, EnumVariant); |
74 | 76 | ||
75 | impl From<DefId> for ModuleDef { | 77 | impl From<DefId> for ModuleDef { |
76 | fn from(it: DefId) -> ModuleDef { | 78 | fn from(it: DefId) -> ModuleDef { |
@@ -264,30 +266,25 @@ impl Docs for Enum { | |||
264 | } | 266 | } |
265 | } | 267 | } |
266 | 268 | ||
267 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 269 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
268 | pub struct EnumVariant { | 270 | pub struct EnumVariant { |
269 | pub(crate) def_id: DefId, | 271 | pub(crate) id: EnumVariantId, |
270 | } | 272 | } |
271 | 273 | ||
272 | impl EnumVariant { | 274 | impl EnumVariant { |
273 | pub(crate) fn new(def_id: DefId) -> Self { | 275 | pub fn module(&self, db: &impl HirDatabase) -> Module { |
274 | EnumVariant { def_id } | 276 | self.id.loc(db).module |
275 | } | ||
276 | |||
277 | pub fn def_id(&self) -> DefId { | ||
278 | self.def_id | ||
279 | } | 277 | } |
280 | |||
281 | pub fn parent_enum(&self, db: &impl HirDatabase) -> Enum { | 278 | pub fn parent_enum(&self, db: &impl HirDatabase) -> Enum { |
282 | db.enum_variant_data(self.def_id).parent_enum.clone() | 279 | db.enum_variant_data(*self).parent_enum.clone() |
283 | } | 280 | } |
284 | 281 | ||
285 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { | 282 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { |
286 | db.enum_variant_data(self.def_id).name.clone() | 283 | db.enum_variant_data(*self).name.clone() |
287 | } | 284 | } |
288 | 285 | ||
289 | pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { | 286 | pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { |
290 | db.enum_variant_data(self.def_id).variant_data.clone() | 287 | db.enum_variant_data(*self).variant_data.clone() |
291 | } | 288 | } |
292 | 289 | ||
293 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> { | 290 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> { |
@@ -295,14 +292,14 @@ impl EnumVariant { | |||
295 | .fields() | 292 | .fields() |
296 | .iter() | 293 | .iter() |
297 | .map(|it| StructField { | 294 | .map(|it| StructField { |
298 | parent: self.def_id.into(), | 295 | parent: (*self).into(), |
299 | name: it.name.clone(), | 296 | name: it.name.clone(), |
300 | }) | 297 | }) |
301 | .collect() | 298 | .collect() |
302 | } | 299 | } |
303 | 300 | ||
304 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) { | 301 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) { |
305 | def_id_to_ast(db, self.def_id) | 302 | self.id.loc(db).source(db) |
306 | } | 303 | } |
307 | } | 304 | } |
308 | 305 | ||
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 4ea649770..aa5e5d689 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -143,11 +143,11 @@ impl Module { | |||
143 | .find(|(n, _variant)| n == &segment.name); | 143 | .find(|(n, _variant)| n == &segment.name); |
144 | 144 | ||
145 | match matching_variant { | 145 | match matching_variant { |
146 | Some((_n, variant)) => PerNs::both(variant.def_id().into(), (*e).into()), | 146 | Some((_n, variant)) => PerNs::both(variant.into(), (*e).into()), |
147 | None => PerNs::none(), | 147 | None => PerNs::none(), |
148 | } | 148 | } |
149 | } | 149 | } |
150 | ModuleDef::Function(_) | ModuleDef::Struct(_) => { | 150 | ModuleDef::Function(_) | ModuleDef::Struct(_) | ModuleDef::EnumVariant(_) => { |
151 | // could be an inherent method call in UFCS form | 151 | // could be an inherent method call in UFCS form |
152 | // (`Struct::method`), or some other kind of associated | 152 | // (`Struct::method`), or some other kind of associated |
153 | // item... Which we currently don't handle (TODO) | 153 | // item... Which we currently don't handle (TODO) |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 34e41017b..5304f5d31 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -4,11 +4,11 @@ use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; | |||
4 | use ra_db::{SyntaxDatabase, CrateId, salsa}; | 4 | use ra_db::{SyntaxDatabase, CrateId, salsa}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | DefId, MacroCallId, Name, HirFileId, | 7 | MacroCallId, Name, HirFileId, |
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, Enum, | 11 | Struct, Enum, EnumVariant, |
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}}, |
@@ -36,7 +36,7 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> { | |||
36 | fn enum_data(&self, e: Enum) -> 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, var: EnumVariant) -> Arc<EnumVariantData>; |
40 | 40 | ||
41 | #[salsa::invoke(crate::ty::infer)] | 41 | #[salsa::invoke(crate::ty::infer)] |
42 | fn infer(&self, func: Function) -> Arc<InferenceResult>; | 42 | fn infer(&self, func: Function) -> Arc<InferenceResult>; |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 6375c76c9..8cdc7ee56 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}; | |||
5 | use ra_arena::{Arena, RawId, impl_arena_id}; | 5 | use ra_arena::{Arena, RawId, impl_arena_id}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | HirDatabase, Def, EnumVariant, Crate, | 8 | HirDatabase, Def, Crate, |
9 | Module, Trait, Type, Static, Const, | 9 | Module, Trait, Type, Static, Const, |
10 | }; | 10 | }; |
11 | 11 | ||
@@ -16,6 +16,7 @@ pub struct HirInterner { | |||
16 | pub(crate) fns: LocationIntener<ItemLoc<ast::FnDef>, FunctionId>, | 16 | pub(crate) fns: LocationIntener<ItemLoc<ast::FnDef>, FunctionId>, |
17 | pub(crate) structs: LocationIntener<ItemLoc<ast::StructDef>, StructId>, | 17 | pub(crate) structs: LocationIntener<ItemLoc<ast::StructDef>, StructId>, |
18 | pub(crate) enums: LocationIntener<ItemLoc<ast::EnumDef>, EnumId>, | 18 | pub(crate) enums: LocationIntener<ItemLoc<ast::EnumDef>, EnumId>, |
19 | pub(crate) enum_variants: LocationIntener<ItemLoc<ast::EnumVariant>, EnumVariantId>, | ||
19 | } | 20 | } |
20 | 21 | ||
21 | impl HirInterner { | 22 | impl HirInterner { |
@@ -208,6 +209,16 @@ impl EnumId { | |||
208 | } | 209 | } |
209 | } | 210 | } |
210 | 211 | ||
212 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
213 | pub struct EnumVariantId(RawId); | ||
214 | impl_arena_id!(EnumVariantId); | ||
215 | |||
216 | impl EnumVariantId { | ||
217 | pub(crate) fn loc(self, db: &impl AsRef<HirInterner>) -> ItemLoc<ast::EnumVariant> { | ||
218 | db.as_ref().enum_variants.id2loc(self) | ||
219 | } | ||
220 | } | ||
221 | |||
211 | /// Def's are a core concept of hir. A `Def` is an Item (function, module, etc) | 222 | /// Def's are a core concept of hir. A `Def` is an Item (function, module, etc) |
212 | /// in a specific module. | 223 | /// in a specific module. |
213 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 224 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -223,7 +234,6 @@ pub struct DefLoc { | |||
223 | 234 | ||
224 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 235 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
225 | pub(crate) enum DefKind { | 236 | pub(crate) enum DefKind { |
226 | EnumVariant, | ||
227 | Const, | 237 | Const, |
228 | Static, | 238 | Static, |
229 | Trait, | 239 | Trait, |
@@ -249,7 +259,6 @@ impl DefId { | |||
249 | pub fn resolve(self, db: &impl HirDatabase) -> Def { | 259 | pub fn resolve(self, db: &impl HirDatabase) -> Def { |
250 | let loc = self.loc(db); | 260 | let loc = self.loc(db); |
251 | match loc.kind { | 261 | match loc.kind { |
252 | DefKind::EnumVariant => Def::EnumVariant(EnumVariant::new(self)), | ||
253 | DefKind::Const => { | 262 | DefKind::Const => { |
254 | let def = Const::new(self); | 263 | let def = Const::new(self); |
255 | Def::Const(def) | 264 | Def::Const(def) |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index fcf8a1dbb..66cf2bd64 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -431,25 +431,24 @@ impl Ty { | |||
431 | TypableDef::Function(func) => (func.generic_params(db), last), | 431 | TypableDef::Function(func) => (func.generic_params(db), last), |
432 | TypableDef::Struct(s) => (s.generic_params(db), last), | 432 | TypableDef::Struct(s) => (s.generic_params(db), last), |
433 | TypableDef::Enum(e) => (e.generic_params(db), last), | 433 | TypableDef::Enum(e) => (e.generic_params(db), last), |
434 | TypableDef::EnumVariant(var) => { | ||
435 | // the generic args for an enum variant may be either specified | ||
436 | // on the segment referring to the enum, or on the segment | ||
437 | // referring to the variant. So `Option::<T>::None` and | ||
438 | // `Option::None::<T>` are both allowed (though the former is | ||
439 | // preferred). See also `def_ids_for_path_segments` in rustc. | ||
440 | let len = path.segments.len(); | ||
441 | let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some() { | ||
442 | // Option::<T>::None | ||
443 | &path.segments[len - 2] | ||
444 | } else { | ||
445 | // Option::None::<T> | ||
446 | last | ||
447 | }; | ||
448 | (var.parent_enum(db).generic_params(db), segment) | ||
449 | } | ||
434 | TypableDef::Def(def_id) => match def_id.resolve(db) { | 450 | TypableDef::Def(def_id) => match def_id.resolve(db) { |
435 | Def::Trait(t) => (t.generic_params(db), last), | 451 | Def::Trait(t) => (t.generic_params(db), last), |
436 | Def::EnumVariant(ev) => { | ||
437 | // the generic args for an enum variant may be either specified | ||
438 | // on the segment referring to the enum, or on the segment | ||
439 | // referring to the variant. So `Option::<T>::None` and | ||
440 | // `Option::None::<T>` are both allowed (though the former is | ||
441 | // preferred). See also `def_ids_for_path_segments` in rustc. | ||
442 | let len = path.segments.len(); | ||
443 | let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some() | ||
444 | { | ||
445 | // Option::<T>::None | ||
446 | &path.segments[len - 2] | ||
447 | } else { | ||
448 | // Option::None::<T> | ||
449 | last | ||
450 | }; | ||
451 | (ev.parent_enum(db).generic_params(db), segment) | ||
452 | } | ||
453 | _ => return Substs::empty(), | 452 | _ => return Substs::empty(), |
454 | }, | 453 | }, |
455 | }; | 454 | }; |
@@ -688,9 +687,10 @@ pub enum TypableDef { | |||
688 | Function(Function), | 687 | Function(Function), |
689 | Struct(Struct), | 688 | Struct(Struct), |
690 | Enum(Enum), | 689 | Enum(Enum), |
690 | EnumVariant(EnumVariant), | ||
691 | Def(DefId), | 691 | Def(DefId), |
692 | } | 692 | } |
693 | impl_froms!(TypableDef: Function, Struct, Enum); | 693 | impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant); |
694 | 694 | ||
695 | impl From<DefId> for TypableDef { | 695 | impl From<DefId> for TypableDef { |
696 | fn from(func: DefId) -> TypableDef { | 696 | fn from(func: DefId) -> TypableDef { |
@@ -705,6 +705,7 @@ impl From<ModuleDef> for Option<TypableDef> { | |||
705 | ModuleDef::Function(f) => f.into(), | 705 | ModuleDef::Function(f) => f.into(), |
706 | ModuleDef::Struct(s) => s.into(), | 706 | ModuleDef::Struct(s) => s.into(), |
707 | ModuleDef::Enum(e) => e.into(), | 707 | ModuleDef::Enum(e) => e.into(), |
708 | ModuleDef::EnumVariant(v) => v.into(), | ||
708 | ModuleDef::Module(_) => return None, | 709 | ModuleDef::Module(_) => return None, |
709 | }; | 710 | }; |
710 | Some(res) | 711 | Some(res) |
@@ -716,48 +717,33 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { | |||
716 | TypableDef::Function(f) => type_for_fn(db, f), | 717 | TypableDef::Function(f) => type_for_fn(db, f), |
717 | TypableDef::Struct(s) => type_for_struct(db, s), | 718 | TypableDef::Struct(s) => type_for_struct(db, s), |
718 | TypableDef::Enum(e) => type_for_enum(db, e), | 719 | TypableDef::Enum(e) => type_for_enum(db, e), |
719 | TypableDef::Def(def_id) => match def_id.resolve(db) { | 720 | TypableDef::EnumVariant(v) => type_for_enum_variant(db, v), |
720 | Def::EnumVariant(ev) => type_for_enum_variant(db, ev), | 721 | TypableDef::Def(def_id) => { |
721 | _ => { | 722 | log::debug!( |
722 | log::debug!( | 723 | "trying to get type for item of unknown type {:?} {:?}", |
723 | "trying to get type for item of unknown type {:?} {:?}", | 724 | def_id, |
724 | def_id, | 725 | def |
725 | def | 726 | ); |
726 | ); | 727 | Ty::Unknown |
727 | Ty::Unknown | 728 | } |
728 | } | ||
729 | }, | ||
730 | } | 729 | } |
731 | } | 730 | } |
732 | 731 | ||
733 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 732 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
734 | pub enum VariantDef { | 733 | pub enum VariantDef { |
735 | Struct(Struct), | 734 | Struct(Struct), |
736 | Def(DefId), // EnumVariant | 735 | EnumVariant(EnumVariant), |
737 | } | ||
738 | impl_froms!(VariantDef: Struct); | ||
739 | |||
740 | impl From<DefId> for VariantDef { | ||
741 | fn from(def_id: DefId) -> VariantDef { | ||
742 | VariantDef::Def(def_id) | ||
743 | } | ||
744 | } | 736 | } |
737 | impl_froms!(VariantDef: Struct, EnumVariant); | ||
745 | 738 | ||
746 | pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> { | 739 | pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> { |
747 | let (variant_data, generics, module) = match def { | 740 | let (variant_data, generics, module) = match def { |
748 | VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)), | 741 | VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)), |
749 | VariantDef::Def(def_id) => match def_id.resolve(db) { | 742 | VariantDef::EnumVariant(var) => ( |
750 | Def::EnumVariant(ev) => ( | 743 | var.variant_data(db), |
751 | ev.variant_data(db), | 744 | var.parent_enum(db).generic_params(db), |
752 | ev.parent_enum(db).generic_params(db), | 745 | var.module(db), |
753 | def_id.module(db), | 746 | ), |
754 | ), | ||
755 | // TODO: unions | ||
756 | _ => panic!( | ||
757 | "trying to get type for field {:?} in non-struct/variant {:?}", | ||
758 | field, def_id | ||
759 | ), | ||
760 | }, | ||
761 | }; | 747 | }; |
762 | // We can't have an impl block ere, right? | 748 | // We can't have an impl block ere, right? |
763 | // let impl_block = def_id.impl_block(db); | 749 | // let impl_block = def_id.impl_block(db); |
@@ -1156,21 +1142,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1156 | def, | 1142 | def, |
1157 | ); | 1143 | ); |
1158 | match def { | 1144 | match def { |
1159 | TypableDef::Def(def_id) => match def_id.resolve(self.db) { | ||
1160 | Def::EnumVariant(ev) => { | ||
1161 | let ty = type_for_enum_variant(self.db, ev); | ||
1162 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | ||
1163 | (ty, Some(def_id.into())) | ||
1164 | } | ||
1165 | _ => (Ty::Unknown, None), | ||
1166 | }, | ||
1167 | TypableDef::Function(_) => (Ty::Unknown, None), | ||
1168 | TypableDef::Struct(s) => { | 1145 | TypableDef::Struct(s) => { |
1169 | let ty = type_for_struct(self.db, s); | 1146 | let ty = type_for_struct(self.db, s); |
1170 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 1147 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
1171 | (ty, Some(s.into())) | 1148 | (ty, Some(s.into())) |
1172 | } | 1149 | } |
1173 | TypableDef::Enum(_) => (Ty::Unknown, None), | 1150 | TypableDef::EnumVariant(var) => { |
1151 | let ty = type_for_enum_variant(self.db, var); | ||
1152 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | ||
1153 | (ty, Some(var.into())) | ||
1154 | } | ||
1155 | TypableDef::Def(_) | TypableDef::Enum(_) | TypableDef::Function(_) => { | ||
1156 | (Ty::Unknown, None) | ||
1157 | } | ||
1174 | } | 1158 | } |
1175 | } | 1159 | } |
1176 | 1160 | ||
@@ -1181,13 +1165,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1181 | let fields = s.fields(self.db); | 1165 | let fields = s.fields(self.db); |
1182 | Some((ty, fields)) | 1166 | Some((ty, fields)) |
1183 | } | 1167 | } |
1184 | VariantDef::Def(def_id) => match def_id.resolve(self.db) { | 1168 | VariantDef::EnumVariant(var) => { |
1185 | Def::EnumVariant(ev) => { | 1169 | let fields = var.fields(self.db); |
1186 | let fields = ev.fields(self.db); | 1170 | Some((ty, fields)) |
1187 | Some((ty, fields)) | 1171 | } |
1188 | } | ||
1189 | _ => None, | ||
1190 | }, | ||
1191 | } | 1172 | } |
1192 | } | 1173 | } |
1193 | 1174 | ||
@@ -1285,13 +1266,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1285 | .module | 1266 | .module |
1286 | .resolve_path(self.db, &path) | 1267 | .resolve_path(self.db, &path) |
1287 | .take_values() | 1268 | .take_values() |
1288 | .and_then(|module_def| match module_def { | 1269 | .and_then(|module_def| module_def.into()) |
1289 | ModuleDef::Def(it) => Some(it.into()), | ||
1290 | ModuleDef::Function(func) => Some(func.into()), | ||
1291 | ModuleDef::Struct(s) => Some(s.into()), | ||
1292 | ModuleDef::Enum(e) => Some(e.into()), | ||
1293 | ModuleDef::Module(_) => None, | ||
1294 | }) | ||
1295 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), | 1270 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), |
1296 | Pat::Bind { | 1271 | Pat::Bind { |
1297 | mode, | 1272 | mode, |