diff options
author | Aleksey Kladov <[email protected]> | 2019-01-24 15:56:38 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-24 15:56:38 +0000 |
commit | 566c8e321e89e5ff8996daa615cc47aea0012881 (patch) | |
tree | 58c2f4741b9305e840d41eb35eb8f4e7d5761fe2 | |
parent | cefc5cbb4a95d2a473ea656efe603bef979b5c49 (diff) |
migrate enums to new id
-rw-r--r-- | crates/ra_hir/src/adt.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 42 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/generics.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/lower.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 90 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 7 |
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 | ||
19 | impl Struct { | 19 | impl Struct { |
@@ -33,6 +33,19 @@ impl Struct { | |||
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
36 | impl 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)] |
37 | pub struct StructData { | 50 | pub struct StructData { |
38 | pub(crate) name: Option<Name>, | 51 | pub(crate) name: Option<Name>, |
@@ -55,20 +68,20 @@ impl StructData { | |||
55 | 68 | ||
56 | fn get_def_id( | 69 | fn 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 | ||
76 | impl From<Module> for ModuleDef { | ||
77 | fn from(it: Module) -> ModuleDef { | ||
78 | ModuleDef::Module(it) | ||
79 | } | ||
80 | } | ||
74 | 81 | ||
75 | impl Into<ModuleDef> for Module { | 82 | impl 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 | ||
81 | impl Into<ModuleDef> for Function { | 88 | impl 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 | ||
87 | impl Into<ModuleDef> for Struct { | 94 | impl 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 | ||
93 | impl Into<ModuleDef> for DefId { | 100 | impl 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)] |
253 | pub struct Enum { | 260 | pub struct Enum { |
254 | pub(crate) def_id: DefId, | 261 | pub(crate) id: EnumId, |
255 | } | 262 | } |
256 | 263 | ||
257 | impl Enum { | 264 | impl 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 | ||
4 | use crate::{ | 4 | use 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 | ||
8 | use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner}; | 8 | use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner}; |
9 | 9 | ||
10 | use crate::{db::HirDatabase, DefId, Name, AsName, Function, Struct}; | 10 | use 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 { | |||
26 | pub enum GenericDef { | 26 | pub 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 | ||
38 | impl From<Struct> for GenericDef { | 39 | impl 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 | |||
45 | impl 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}; | |||
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, 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)] |
249 | pub(crate) enum DefKind { | 249 | pub(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 | ||
271 | impl DefId { | 268 | impl 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; | |||
10 | use crate::{ | 10 | use 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)] |
167 | pub enum AdtDef { | 167 | pub enum AdtDef { |
168 | Struct(Struct), | 168 | Struct(Struct), |
169 | Def(DefId), // Enum | 169 | Enum(Enum), |
170 | } | 170 | } |
171 | 171 | ||
172 | impl From<Struct> for AdtDef { | 172 | impl 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 | ||
178 | impl From<DefId> for AdtDef { | 178 | impl 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 | ||
184 | impl AdtDef { | 184 | impl 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 { | |||
680 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { | 682 | pub(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 | |||
696 | pub enum TypableDef { | 698 | pub 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 | ||
708 | impl From<Struct> for TypableDef { | 711 | impl 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 | |||
717 | impl 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 | ||
729 | impl 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 | |||
720 | pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { | 742 | pub(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 | ||
432 | impl EnumVariant { | 432 | impl 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 | } |