diff options
Diffstat (limited to 'crates/ra_hir/src')
27 files changed, 780 insertions, 637 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index bcb705c24..d87fe7049 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -1,6 +1,5 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_db::Cancelable; | ||
4 | use ra_syntax::{ | 3 | use ra_syntax::{ |
5 | SyntaxNode, | 4 | SyntaxNode, |
6 | ast::{self, NameOwner, StructFlavor, AstNode} | 5 | ast::{self, NameOwner, StructFlavor, AstNode} |
@@ -18,8 +17,8 @@ impl Struct { | |||
18 | Struct { def_id } | 17 | Struct { def_id } |
19 | } | 18 | } |
20 | 19 | ||
21 | pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<VariantData>> { | 20 | pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { |
22 | Ok(db.struct_data(self.def_id)?.variant_data.clone()) | 21 | db.struct_data(self.def_id).variant_data.clone() |
23 | } | 22 | } |
24 | } | 23 | } |
25 | 24 | ||
@@ -37,16 +36,13 @@ impl StructData { | |||
37 | StructData { name, variant_data } | 36 | StructData { name, variant_data } |
38 | } | 37 | } |
39 | 38 | ||
40 | pub(crate) fn struct_data_query( | 39 | pub(crate) fn struct_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc<StructData> { |
41 | db: &impl HirDatabase, | ||
42 | def_id: DefId, | ||
43 | ) -> Cancelable<Arc<StructData>> { | ||
44 | let def_loc = def_id.loc(db); | 40 | let def_loc = def_id.loc(db); |
45 | assert!(def_loc.kind == DefKind::Struct); | 41 | assert!(def_loc.kind == DefKind::Struct); |
46 | let syntax = db.file_item(def_loc.source_item_id); | 42 | let syntax = db.file_item(def_loc.source_item_id); |
47 | let struct_def = | 43 | let struct_def = |
48 | ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node"); | 44 | ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node"); |
49 | Ok(Arc::new(StructData::new(struct_def))) | 45 | Arc::new(StructData::new(struct_def)) |
50 | } | 46 | } |
51 | } | 47 | } |
52 | 48 | ||
@@ -84,10 +80,7 @@ impl EnumData { | |||
84 | EnumData { name, variants } | 80 | EnumData { name, variants } |
85 | } | 81 | } |
86 | 82 | ||
87 | pub(crate) fn enum_data_query( | 83 | pub(crate) fn enum_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc<EnumData> { |
88 | db: &impl HirDatabase, | ||
89 | def_id: DefId, | ||
90 | ) -> Cancelable<Arc<EnumData>> { | ||
91 | let def_loc = def_id.loc(db); | 84 | let def_loc = def_id.loc(db); |
92 | assert!(def_loc.kind == DefKind::Enum); | 85 | assert!(def_loc.kind == DefKind::Enum); |
93 | let syntax = db.file_item(def_loc.source_item_id); | 86 | let syntax = db.file_item(def_loc.source_item_id); |
@@ -107,7 +100,7 @@ impl EnumData { | |||
107 | } else { | 100 | } else { |
108 | Vec::new() | 101 | Vec::new() |
109 | }; | 102 | }; |
110 | Ok(Arc::new(EnumData::new(enum_def, variants))) | 103 | Arc::new(EnumData::new(enum_def, variants)) |
111 | } | 104 | } |
112 | } | 105 | } |
113 | 106 | ||
@@ -133,7 +126,7 @@ impl EnumVariantData { | |||
133 | pub(crate) fn enum_variant_data_query( | 126 | pub(crate) fn enum_variant_data_query( |
134 | db: &impl HirDatabase, | 127 | db: &impl HirDatabase, |
135 | def_id: DefId, | 128 | def_id: DefId, |
136 | ) -> Cancelable<Arc<EnumVariantData>> { | 129 | ) -> Arc<EnumVariantData> { |
137 | let def_loc = def_id.loc(db); | 130 | let def_loc = def_id.loc(db); |
138 | assert!(def_loc.kind == DefKind::EnumVariant); | 131 | assert!(def_loc.kind == DefKind::EnumVariant); |
139 | let syntax = db.file_item(def_loc.source_item_id); | 132 | let syntax = db.file_item(def_loc.source_item_id); |
@@ -146,10 +139,7 @@ impl EnumVariantData { | |||
146 | .expect("enum variant list should have enum ancestor"); | 139 | .expect("enum variant list should have enum ancestor"); |
147 | let enum_def_id = get_def_id(db, &def_loc, enum_node, DefKind::Enum); | 140 | let enum_def_id = get_def_id(db, &def_loc, enum_node, DefKind::Enum); |
148 | 141 | ||
149 | Ok(Arc::new(EnumVariantData::new( | 142 | Arc::new(EnumVariantData::new(variant_def, Enum::new(enum_def_id))) |
150 | variant_def, | ||
151 | Enum::new(enum_def_id), | ||
152 | ))) | ||
153 | } | 143 | } |
154 | } | 144 | } |
155 | 145 | ||
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 91b235594..0cf7deac9 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use relative_path::RelativePathBuf; | 3 | use relative_path::RelativePathBuf; |
4 | use ra_db::{CrateId, Cancelable, FileId}; | 4 | use ra_db::{CrateId, FileId}; |
5 | use ra_syntax::{ast, TreeArc, SyntaxNode}; | 5 | use ra_syntax::{ast, TreeArc, SyntaxNode}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
@@ -33,10 +33,10 @@ impl Crate { | |||
33 | pub fn crate_id(&self) -> CrateId { | 33 | pub fn crate_id(&self) -> CrateId { |
34 | self.crate_id | 34 | self.crate_id |
35 | } | 35 | } |
36 | pub fn dependencies(&self, db: &impl HirDatabase) -> Cancelable<Vec<CrateDependency>> { | 36 | pub fn dependencies(&self, db: &impl HirDatabase) -> Vec<CrateDependency> { |
37 | Ok(self.dependencies_impl(db)) | 37 | self.dependencies_impl(db) |
38 | } | 38 | } |
39 | pub fn root_module(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | 39 | pub fn root_module(&self, db: &impl HirDatabase) -> Option<Module> { |
40 | self.root_module_impl(db) | 40 | self.root_module_impl(db) |
41 | } | 41 | } |
42 | } | 42 | } |
@@ -78,12 +78,12 @@ pub enum Problem { | |||
78 | 78 | ||
79 | impl Module { | 79 | impl Module { |
80 | /// Name of this module. | 80 | /// Name of this module. |
81 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { | 81 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { |
82 | self.name_impl(db) | 82 | self.name_impl(db) |
83 | } | 83 | } |
84 | 84 | ||
85 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | 85 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. |
86 | pub fn definition_source(&self, db: &impl HirDatabase) -> Cancelable<(FileId, ModuleSource)> { | 86 | pub fn definition_source(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { |
87 | self.definition_source_impl(db) | 87 | self.definition_source_impl(db) |
88 | } | 88 | } |
89 | 89 | ||
@@ -92,60 +92,57 @@ impl Module { | |||
92 | pub fn declaration_source( | 92 | pub fn declaration_source( |
93 | &self, | 93 | &self, |
94 | db: &impl HirDatabase, | 94 | db: &impl HirDatabase, |
95 | ) -> Cancelable<Option<(FileId, TreeArc<ast::Module>)>> { | 95 | ) -> Option<(FileId, TreeArc<ast::Module>)> { |
96 | self.declaration_source_impl(db) | 96 | self.declaration_source_impl(db) |
97 | } | 97 | } |
98 | 98 | ||
99 | /// Returns the crate this module is part of. | 99 | /// Returns the crate this module is part of. |
100 | pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { | 100 | pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { |
101 | self.krate_impl(db) | 101 | self.krate_impl(db) |
102 | } | 102 | } |
103 | 103 | ||
104 | /// Topmost parent of this module. Every module has a `crate_root`, but some | 104 | /// Topmost parent of this module. Every module has a `crate_root`, but some |
105 | /// might be missing `krate`. This can happen if a module's file is not included | 105 | /// might be missing `krate`. This can happen if a module's file is not included |
106 | /// in the module tree of any target in Cargo.toml. | 106 | /// in the module tree of any target in Cargo.toml. |
107 | pub fn crate_root(&self, db: &impl HirDatabase) -> Cancelable<Module> { | 107 | pub fn crate_root(&self, db: &impl HirDatabase) -> Module { |
108 | self.crate_root_impl(db) | 108 | self.crate_root_impl(db) |
109 | } | 109 | } |
110 | 110 | ||
111 | /// Finds a child module with the specified name. | 111 | /// Finds a child module with the specified name. |
112 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 112 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { |
113 | self.child_impl(db, name) | 113 | self.child_impl(db, name) |
114 | } | 114 | } |
115 | 115 | ||
116 | /// Iterates over all child modules. | 116 | /// Iterates over all child modules. |
117 | pub fn children(&self, db: &impl HirDatabase) -> Cancelable<impl Iterator<Item = Module>> { | 117 | pub fn children(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { |
118 | self.children_impl(db) | 118 | self.children_impl(db) |
119 | } | 119 | } |
120 | 120 | ||
121 | /// Finds a parent module. | 121 | /// Finds a parent module. |
122 | pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | 122 | pub fn parent(&self, db: &impl HirDatabase) -> Option<Module> { |
123 | self.parent_impl(db) | 123 | self.parent_impl(db) |
124 | } | 124 | } |
125 | 125 | ||
126 | pub fn path_to_root(&self, db: &impl HirDatabase) -> Cancelable<Vec<Module>> { | 126 | pub fn path_to_root(&self, db: &impl HirDatabase) -> Vec<Module> { |
127 | let mut res = vec![self.clone()]; | 127 | let mut res = vec![self.clone()]; |
128 | let mut curr = self.clone(); | 128 | let mut curr = self.clone(); |
129 | while let Some(next) = curr.parent(db)? { | 129 | while let Some(next) = curr.parent(db) { |
130 | res.push(next.clone()); | 130 | res.push(next.clone()); |
131 | curr = next | 131 | curr = next |
132 | } | 132 | } |
133 | Ok(res) | 133 | res |
134 | } | 134 | } |
135 | 135 | ||
136 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 136 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
137 | pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { | 137 | pub fn scope(&self, db: &impl HirDatabase) -> ModuleScope { |
138 | self.scope_impl(db) | 138 | self.scope_impl(db) |
139 | } | 139 | } |
140 | 140 | ||
141 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { | 141 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { |
142 | self.resolve_path_impl(db, path) | 142 | self.resolve_path_impl(db, path) |
143 | } | 143 | } |
144 | 144 | ||
145 | pub fn problems( | 145 | pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> { |
146 | &self, | ||
147 | db: &impl HirDatabase, | ||
148 | ) -> Cancelable<Vec<(TreeArc<SyntaxNode>, Problem)>> { | ||
149 | self.problems_impl(db) | 146 | self.problems_impl(db) |
150 | } | 147 | } |
151 | } | 148 | } |
@@ -160,7 +157,7 @@ impl StructField { | |||
160 | pub fn name(&self) -> &Name { | 157 | pub fn name(&self) -> &Name { |
161 | &self.name | 158 | &self.name |
162 | } | 159 | } |
163 | pub fn ty(&self, db: &impl HirDatabase) -> Cancelable<Option<Ty>> { | 160 | pub fn ty(&self, db: &impl HirDatabase) -> Option<Ty> { |
164 | db.type_for_field(self.struct_.def_id, self.name.clone()) | 161 | db.type_for_field(self.struct_.def_id, self.name.clone()) |
165 | } | 162 | } |
166 | } | 163 | } |
@@ -175,13 +172,12 @@ impl Struct { | |||
175 | self.def_id | 172 | self.def_id |
176 | } | 173 | } |
177 | 174 | ||
178 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { | 175 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { |
179 | Ok(db.struct_data(self.def_id)?.name.clone()) | 176 | db.struct_data(self.def_id).name.clone() |
180 | } | 177 | } |
181 | 178 | ||
182 | pub fn fields(&self, db: &impl HirDatabase) -> Cancelable<Vec<StructField>> { | 179 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> { |
183 | let res = db | 180 | db.struct_data(self.def_id) |
184 | .struct_data(self.def_id)? | ||
185 | .variant_data | 181 | .variant_data |
186 | .fields() | 182 | .fields() |
187 | .iter() | 183 | .iter() |
@@ -189,15 +185,11 @@ impl Struct { | |||
189 | struct_: self.clone(), | 185 | struct_: self.clone(), |
190 | name: it.name.clone(), | 186 | name: it.name.clone(), |
191 | }) | 187 | }) |
192 | .collect(); | 188 | .collect() |
193 | Ok(res) | ||
194 | } | 189 | } |
195 | 190 | ||
196 | pub fn source( | 191 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::StructDef>) { |
197 | &self, | 192 | def_id_to_ast(db, self.def_id) |
198 | db: &impl HirDatabase, | ||
199 | ) -> Cancelable<(HirFileId, TreeArc<ast::StructDef>)> { | ||
200 | Ok(def_id_to_ast(db, self.def_id)) | ||
201 | } | 193 | } |
202 | } | 194 | } |
203 | 195 | ||
@@ -215,16 +207,16 @@ impl Enum { | |||
215 | self.def_id | 207 | self.def_id |
216 | } | 208 | } |
217 | 209 | ||
218 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { | 210 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { |
219 | Ok(db.enum_data(self.def_id)?.name.clone()) | 211 | db.enum_data(self.def_id).name.clone() |
220 | } | 212 | } |
221 | 213 | ||
222 | pub fn variants(&self, db: &impl HirDatabase) -> Cancelable<Vec<(Name, EnumVariant)>> { | 214 | pub fn variants(&self, db: &impl HirDatabase) -> Vec<(Name, EnumVariant)> { |
223 | Ok(db.enum_data(self.def_id)?.variants.clone()) | 215 | db.enum_data(self.def_id).variants.clone() |
224 | } | 216 | } |
225 | 217 | ||
226 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<(HirFileId, TreeArc<ast::EnumDef>)> { | 218 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) { |
227 | Ok(def_id_to_ast(db, self.def_id)) | 219 | def_id_to_ast(db, self.def_id) |
228 | } | 220 | } |
229 | } | 221 | } |
230 | 222 | ||
@@ -242,23 +234,20 @@ impl EnumVariant { | |||
242 | self.def_id | 234 | self.def_id |
243 | } | 235 | } |
244 | 236 | ||
245 | pub fn parent_enum(&self, db: &impl HirDatabase) -> Cancelable<Enum> { | 237 | pub fn parent_enum(&self, db: &impl HirDatabase) -> Enum { |
246 | Ok(db.enum_variant_data(self.def_id)?.parent_enum.clone()) | 238 | db.enum_variant_data(self.def_id).parent_enum.clone() |
247 | } | 239 | } |
248 | 240 | ||
249 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { | 241 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { |
250 | Ok(db.enum_variant_data(self.def_id)?.name.clone()) | 242 | db.enum_variant_data(self.def_id).name.clone() |
251 | } | 243 | } |
252 | 244 | ||
253 | pub fn variant_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<VariantData>> { | 245 | pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { |
254 | Ok(db.enum_variant_data(self.def_id)?.variant_data.clone()) | 246 | db.enum_variant_data(self.def_id).variant_data.clone() |
255 | } | 247 | } |
256 | 248 | ||
257 | pub fn source( | 249 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) { |
258 | &self, | 250 | def_id_to_ast(db, self.def_id) |
259 | db: &impl HirDatabase, | ||
260 | ) -> Cancelable<(HirFileId, TreeArc<ast::EnumVariant>)> { | ||
261 | Ok(def_id_to_ast(db, self.def_id)) | ||
262 | } | 251 | } |
263 | } | 252 | } |
264 | 253 | ||
@@ -305,28 +294,28 @@ impl Function { | |||
305 | self.def_id | 294 | self.def_id |
306 | } | 295 | } |
307 | 296 | ||
308 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<(HirFileId, TreeArc<ast::FnDef>)> { | 297 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::FnDef>) { |
309 | Ok(def_id_to_ast(db, self.def_id)) | 298 | def_id_to_ast(db, self.def_id) |
310 | } | 299 | } |
311 | 300 | ||
312 | pub fn body_syntax_mapping(&self, db: &impl HirDatabase) -> Cancelable<Arc<BodySyntaxMapping>> { | 301 | pub fn body_syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> { |
313 | db.body_syntax_mapping(self.def_id) | 302 | db.body_syntax_mapping(self.def_id) |
314 | } | 303 | } |
315 | 304 | ||
316 | pub fn scopes(&self, db: &impl HirDatabase) -> Cancelable<ScopesWithSyntaxMapping> { | 305 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { |
317 | let scopes = db.fn_scopes(self.def_id)?; | 306 | let scopes = db.fn_scopes(self.def_id); |
318 | let syntax_mapping = db.body_syntax_mapping(self.def_id)?; | 307 | let syntax_mapping = db.body_syntax_mapping(self.def_id); |
319 | Ok(ScopesWithSyntaxMapping { | 308 | ScopesWithSyntaxMapping { |
320 | scopes, | 309 | scopes, |
321 | syntax_mapping, | 310 | syntax_mapping, |
322 | }) | 311 | } |
323 | } | 312 | } |
324 | 313 | ||
325 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { | 314 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { |
326 | db.fn_signature(self.def_id) | 315 | db.fn_signature(self.def_id) |
327 | } | 316 | } |
328 | 317 | ||
329 | pub fn infer(&self, db: &impl HirDatabase) -> Cancelable<Arc<InferenceResult>> { | 318 | pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
330 | db.infer(self.def_id) | 319 | db.infer(self.def_id) |
331 | } | 320 | } |
332 | } | 321 | } |
@@ -341,8 +330,8 @@ impl Const { | |||
341 | Const { def_id } | 330 | Const { def_id } |
342 | } | 331 | } |
343 | 332 | ||
344 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<(HirFileId, TreeArc<ast::ConstDef>)> { | 333 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) { |
345 | Ok(def_id_to_ast(db, self.def_id)) | 334 | def_id_to_ast(db, self.def_id) |
346 | } | 335 | } |
347 | } | 336 | } |
348 | 337 | ||
@@ -356,11 +345,8 @@ impl Static { | |||
356 | Static { def_id } | 345 | Static { def_id } |
357 | } | 346 | } |
358 | 347 | ||
359 | pub fn source( | 348 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) { |
360 | &self, | 349 | def_id_to_ast(db, self.def_id) |
361 | db: &impl HirDatabase, | ||
362 | ) -> Cancelable<(HirFileId, TreeArc<ast::StaticDef>)> { | ||
363 | Ok(def_id_to_ast(db, self.def_id)) | ||
364 | } | 350 | } |
365 | } | 351 | } |
366 | 352 | ||
@@ -374,8 +360,8 @@ impl Trait { | |||
374 | Trait { def_id } | 360 | Trait { def_id } |
375 | } | 361 | } |
376 | 362 | ||
377 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<(HirFileId, TreeArc<ast::TraitDef>)> { | 363 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) { |
378 | Ok(def_id_to_ast(db, self.def_id)) | 364 | def_id_to_ast(db, self.def_id) |
379 | } | 365 | } |
380 | } | 366 | } |
381 | 367 | ||
@@ -389,7 +375,7 @@ impl Type { | |||
389 | Type { def_id } | 375 | Type { def_id } |
390 | } | 376 | } |
391 | 377 | ||
392 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<(HirFileId, TreeArc<ast::TypeDef>)> { | 378 | pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TypeDef>) { |
393 | Ok(def_id_to_ast(db, self.def_id)) | 379 | def_id_to_ast(db, self.def_id) |
394 | } | 380 | } |
395 | } | 381 | } |
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs index 8d6b7fc19..66d7e1713 100644 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ b/crates/ra_hir/src/code_model_impl/function.rs | |||
@@ -2,7 +2,6 @@ mod scope; | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_db::Cancelable; | ||
6 | use ra_syntax::{TreeArc, ast::{self, NameOwner}}; | 5 | use ra_syntax::{TreeArc, ast::{self, NameOwner}}; |
7 | 6 | ||
8 | use crate::{ | 7 | use crate::{ |
@@ -20,16 +19,16 @@ impl Function { | |||
20 | Function { def_id } | 19 | Function { def_id } |
21 | } | 20 | } |
22 | 21 | ||
23 | pub(crate) fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> { | 22 | pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> { |
24 | db.body_hir(self.def_id) | 23 | db.body_hir(self.def_id) |
25 | } | 24 | } |
26 | 25 | ||
27 | pub(crate) fn module(&self, db: &impl HirDatabase) -> Cancelable<Module> { | 26 | pub(crate) fn module(&self, db: &impl HirDatabase) -> Module { |
28 | self.def_id.module(db) | 27 | self.def_id.module(db) |
29 | } | 28 | } |
30 | 29 | ||
31 | /// The containing impl block, if this is a method. | 30 | /// The containing impl block, if this is a method. |
32 | pub(crate) fn impl_block(&self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> { | 31 | pub(crate) fn impl_block(&self, db: &impl HirDatabase) -> Option<ImplBlock> { |
33 | self.def_id.impl_block(db) | 32 | self.def_id.impl_block(db) |
34 | } | 33 | } |
35 | } | 34 | } |
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs index 3275eafed..8c6e34873 100644 --- a/crates/ra_hir/src/code_model_impl/krate.rs +++ b/crates/ra_hir/src/code_model_impl/krate.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use ra_db::{CrateId, Cancelable}; | 1 | use ra_db::CrateId; |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId, | 4 | HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId, |
@@ -20,18 +20,18 @@ impl Crate { | |||
20 | }) | 20 | }) |
21 | .collect() | 21 | .collect() |
22 | } | 22 | } |
23 | pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | 23 | pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { |
24 | let crate_graph = db.crate_graph(); | 24 | let crate_graph = db.crate_graph(); |
25 | let file_id = crate_graph.crate_root(self.crate_id); | 25 | let file_id = crate_graph.crate_root(self.crate_id); |
26 | let source_root_id = db.file_source_root(file_id); | 26 | let source_root_id = db.file_source_root(file_id); |
27 | let file_id = HirFileId::from(file_id); | 27 | let file_id = HirFileId::from(file_id); |
28 | let module_tree = db.module_tree(source_root_id)?; | 28 | let module_tree = db.module_tree(source_root_id); |
29 | // FIXME: teach module tree about crate roots instead of guessing | 29 | // FIXME: teach module tree about crate roots instead of guessing |
30 | let source = SourceItemId { | 30 | let source = SourceItemId { |
31 | file_id, | 31 | file_id, |
32 | item_id: None, | 32 | item_id: None, |
33 | }; | 33 | }; |
34 | let module_id = ctry!(module_tree.find_module_by_source(source)); | 34 | let module_id = module_tree.find_module_by_source(source)?; |
35 | 35 | ||
36 | let def_loc = DefLoc { | 36 | let def_loc = DefLoc { |
37 | kind: DefKind::Module, | 37 | kind: DefKind::Module, |
@@ -42,6 +42,6 @@ impl Crate { | |||
42 | let def_id = def_loc.id(db); | 42 | let def_id = def_loc.id(db); |
43 | 43 | ||
44 | let module = Module::new(def_id); | 44 | let module = Module::new(def_id); |
45 | Ok(Some(module)) | 45 | Some(module) |
46 | } | 46 | } |
47 | } | 47 | } |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 775dd6709..a5c032d69 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use ra_db::{Cancelable, SourceRootId, FileId}; | 1 | use ra_db::{SourceRootId, FileId}; |
2 | use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc}; | 2 | use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc}; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
@@ -18,8 +18,8 @@ impl Module { | |||
18 | db: &impl HirDatabase, | 18 | db: &impl HirDatabase, |
19 | source_root_id: SourceRootId, | 19 | source_root_id: SourceRootId, |
20 | module_id: ModuleId, | 20 | module_id: ModuleId, |
21 | ) -> Cancelable<Self> { | 21 | ) -> Self { |
22 | let module_tree = db.module_tree(source_root_id)?; | 22 | let module_tree = db.module_tree(source_root_id); |
23 | let def_loc = DefLoc { | 23 | let def_loc = DefLoc { |
24 | kind: DefKind::Module, | 24 | kind: DefKind::Module, |
25 | source_root_id, | 25 | source_root_id, |
@@ -27,21 +27,17 @@ impl Module { | |||
27 | source_item_id: module_id.source(&module_tree), | 27 | source_item_id: module_id.source(&module_tree), |
28 | }; | 28 | }; |
29 | let def_id = def_loc.id(db); | 29 | let def_id = def_loc.id(db); |
30 | let module = Module::new(def_id); | 30 | Module::new(def_id) |
31 | Ok(module) | ||
32 | } | 31 | } |
33 | 32 | ||
34 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { | 33 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { |
35 | let loc = self.def_id.loc(db); | 34 | let loc = self.def_id.loc(db); |
36 | let module_tree = db.module_tree(loc.source_root_id)?; | 35 | let module_tree = db.module_tree(loc.source_root_id); |
37 | let link = ctry!(loc.module_id.parent_link(&module_tree)); | 36 | let link = loc.module_id.parent_link(&module_tree)?; |
38 | Ok(Some(link.name(&module_tree).clone())) | 37 | Some(link.name(&module_tree).clone()) |
39 | } | 38 | } |
40 | 39 | ||
41 | pub fn definition_source_impl( | 40 | pub fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { |
42 | &self, | ||
43 | db: &impl HirDatabase, | ||
44 | ) -> Cancelable<(FileId, ModuleSource)> { | ||
45 | let loc = self.def_id.loc(db); | 41 | let loc = self.def_id.loc(db); |
46 | let file_id = loc.source_item_id.file_id.as_original_file(); | 42 | let file_id = loc.source_item_id.file_id.as_original_file(); |
47 | let syntax_node = db.file_item(loc.source_item_id); | 43 | let syntax_node = db.file_item(loc.source_item_id); |
@@ -51,94 +47,89 @@ impl Module { | |||
51 | let module = ast::Module::cast(&syntax_node).unwrap(); | 47 | let module = ast::Module::cast(&syntax_node).unwrap(); |
52 | ModuleSource::Module(module.to_owned()) | 48 | ModuleSource::Module(module.to_owned()) |
53 | }; | 49 | }; |
54 | Ok((file_id, module_source)) | 50 | (file_id, module_source) |
55 | } | 51 | } |
56 | 52 | ||
57 | pub fn declaration_source_impl( | 53 | pub fn declaration_source_impl( |
58 | &self, | 54 | &self, |
59 | db: &impl HirDatabase, | 55 | db: &impl HirDatabase, |
60 | ) -> Cancelable<Option<(FileId, TreeArc<ast::Module>)>> { | 56 | ) -> Option<(FileId, TreeArc<ast::Module>)> { |
61 | let loc = self.def_id.loc(db); | 57 | let loc = self.def_id.loc(db); |
62 | let module_tree = db.module_tree(loc.source_root_id)?; | 58 | let module_tree = db.module_tree(loc.source_root_id); |
63 | let link = ctry!(loc.module_id.parent_link(&module_tree)); | 59 | let link = loc.module_id.parent_link(&module_tree)?; |
64 | let file_id = link | 60 | let file_id = link |
65 | .owner(&module_tree) | 61 | .owner(&module_tree) |
66 | .source(&module_tree) | 62 | .source(&module_tree) |
67 | .file_id | 63 | .file_id |
68 | .as_original_file(); | 64 | .as_original_file(); |
69 | let src = link.source(&module_tree, db); | 65 | let src = link.source(&module_tree, db); |
70 | Ok(Some((file_id, src))) | 66 | Some((file_id, src)) |
71 | } | 67 | } |
72 | 68 | ||
73 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { | 69 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> { |
74 | let root = self.crate_root(db)?; | 70 | let root = self.crate_root(db); |
75 | let loc = root.def_id.loc(db); | 71 | let loc = root.def_id.loc(db); |
76 | let file_id = loc.source_item_id.file_id.as_original_file(); | 72 | let file_id = loc.source_item_id.file_id.as_original_file(); |
77 | 73 | ||
78 | let crate_graph = db.crate_graph(); | 74 | let crate_graph = db.crate_graph(); |
79 | let crate_id = ctry!(crate_graph.crate_id_for_crate_root(file_id)); | 75 | let crate_id = crate_graph.crate_id_for_crate_root(file_id)?; |
80 | Ok(Some(Crate::new(crate_id))) | 76 | Some(Crate::new(crate_id)) |
81 | } | 77 | } |
82 | 78 | ||
83 | pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Cancelable<Module> { | 79 | pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module { |
84 | let loc = self.def_id.loc(db); | 80 | let loc = self.def_id.loc(db); |
85 | let module_tree = db.module_tree(loc.source_root_id)?; | 81 | let module_tree = db.module_tree(loc.source_root_id); |
86 | let module_id = loc.module_id.crate_root(&module_tree); | 82 | let module_id = loc.module_id.crate_root(&module_tree); |
87 | Module::from_module_id(db, loc.source_root_id, module_id) | 83 | Module::from_module_id(db, loc.source_root_id, module_id) |
88 | } | 84 | } |
89 | 85 | ||
90 | /// Finds a child module with the specified name. | 86 | /// Finds a child module with the specified name. |
91 | pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 87 | pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { |
92 | let loc = self.def_id.loc(db); | 88 | let loc = self.def_id.loc(db); |
93 | let module_tree = db.module_tree(loc.source_root_id)?; | 89 | let module_tree = db.module_tree(loc.source_root_id); |
94 | let child_id = ctry!(loc.module_id.child(&module_tree, name)); | 90 | let child_id = loc.module_id.child(&module_tree, name)?; |
95 | Module::from_module_id(db, loc.source_root_id, child_id).map(Some) | 91 | Some(Module::from_module_id(db, loc.source_root_id, child_id)) |
96 | } | 92 | } |
97 | 93 | ||
98 | /// Iterates over all child modules. | 94 | /// Iterates over all child modules. |
99 | pub fn children_impl(&self, db: &impl HirDatabase) -> Cancelable<impl Iterator<Item = Module>> { | 95 | pub fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { |
100 | // FIXME this should be implementable without collecting into a vec, but | 96 | // FIXME this should be implementable without collecting into a vec, but |
101 | // it's kind of hard since the iterator needs to keep a reference to the | 97 | // it's kind of hard since the iterator needs to keep a reference to the |
102 | // module tree. | 98 | // module tree. |
103 | let loc = self.def_id.loc(db); | 99 | let loc = self.def_id.loc(db); |
104 | let module_tree = db.module_tree(loc.source_root_id)?; | 100 | let module_tree = db.module_tree(loc.source_root_id); |
105 | let children = loc | 101 | let children = loc |
106 | .module_id | 102 | .module_id |
107 | .children(&module_tree) | 103 | .children(&module_tree) |
108 | .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id)) | 104 | .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id)) |
109 | .collect::<Cancelable<Vec<_>>>()?; | 105 | .collect::<Vec<_>>(); |
110 | Ok(children.into_iter()) | 106 | children.into_iter() |
111 | } | 107 | } |
112 | 108 | ||
113 | pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | 109 | pub fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { |
114 | let loc = self.def_id.loc(db); | 110 | let loc = self.def_id.loc(db); |
115 | let module_tree = db.module_tree(loc.source_root_id)?; | 111 | let module_tree = db.module_tree(loc.source_root_id); |
116 | let parent_id = ctry!(loc.module_id.parent(&module_tree)); | 112 | let parent_id = loc.module_id.parent(&module_tree)?; |
117 | Module::from_module_id(db, loc.source_root_id, parent_id).map(Some) | 113 | Some(Module::from_module_id(db, loc.source_root_id, parent_id)) |
118 | } | 114 | } |
119 | 115 | ||
120 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 116 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
121 | pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { | 117 | pub fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { |
122 | let loc = self.def_id.loc(db); | 118 | let loc = self.def_id.loc(db); |
123 | let item_map = db.item_map(loc.source_root_id)?; | 119 | let item_map = db.item_map(loc.source_root_id); |
124 | let res = item_map.per_module[&loc.module_id].clone(); | 120 | item_map.per_module[&loc.module_id].clone() |
125 | Ok(res) | ||
126 | } | 121 | } |
127 | 122 | ||
128 | pub fn resolve_path_impl( | 123 | pub fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { |
129 | &self, | ||
130 | db: &impl HirDatabase, | ||
131 | path: &Path, | ||
132 | ) -> Cancelable<PerNs<DefId>> { | ||
133 | let mut curr_per_ns = PerNs::types( | 124 | let mut curr_per_ns = PerNs::types( |
134 | match path.kind { | 125 | match path.kind { |
135 | PathKind::Crate => self.crate_root(db)?, | 126 | PathKind::Crate => self.crate_root(db), |
136 | PathKind::Self_ | PathKind::Plain => self.clone(), | 127 | PathKind::Self_ | PathKind::Plain => self.clone(), |
137 | PathKind::Super => { | 128 | PathKind::Super => { |
138 | if let Some(p) = self.parent(db)? { | 129 | if let Some(p) = self.parent(db) { |
139 | p | 130 | p |
140 | } else { | 131 | } else { |
141 | return Ok(PerNs::none()); | 132 | return PerNs::none(); |
142 | } | 133 | } |
143 | } | 134 | } |
144 | } | 135 | } |
@@ -150,47 +141,44 @@ impl Module { | |||
150 | let curr = if let Some(r) = curr_per_ns.as_ref().take_types() { | 141 | let curr = if let Some(r) = curr_per_ns.as_ref().take_types() { |
151 | r | 142 | r |
152 | } else { | 143 | } else { |
153 | return Ok(PerNs::none()); | 144 | return PerNs::none(); |
154 | }; | 145 | }; |
155 | let module = match curr.resolve(db)? { | 146 | let module = match curr.resolve(db) { |
156 | Def::Module(it) => it, | 147 | Def::Module(it) => it, |
157 | Def::Enum(e) => { | 148 | Def::Enum(e) => { |
158 | if segments.len() == idx + 1 { | 149 | if segments.len() == idx + 1 { |
159 | // enum variant | 150 | // enum variant |
160 | let matching_variant = | 151 | let matching_variant = |
161 | e.variants(db)?.into_iter().find(|(n, _variant)| n == name); | 152 | e.variants(db).into_iter().find(|(n, _variant)| n == name); |
162 | 153 | ||
163 | if let Some((_n, variant)) = matching_variant { | 154 | if let Some((_n, variant)) = matching_variant { |
164 | return Ok(PerNs::both(variant.def_id(), e.def_id())); | 155 | return PerNs::both(variant.def_id(), e.def_id()); |
165 | } else { | 156 | } else { |
166 | return Ok(PerNs::none()); | 157 | return PerNs::none(); |
167 | } | 158 | } |
168 | } else if segments.len() == idx { | 159 | } else if segments.len() == idx { |
169 | // enum | 160 | // enum |
170 | return Ok(PerNs::types(e.def_id())); | 161 | return PerNs::types(e.def_id()); |
171 | } else { | 162 | } else { |
172 | // malformed enum? | 163 | // malformed enum? |
173 | return Ok(PerNs::none()); | 164 | return PerNs::none(); |
174 | } | 165 | } |
175 | } | 166 | } |
176 | _ => return Ok(PerNs::none()), | 167 | _ => return PerNs::none(), |
177 | }; | 168 | }; |
178 | let scope = module.scope(db)?; | 169 | let scope = module.scope(db); |
179 | curr_per_ns = if let Some(r) = scope.get(&name) { | 170 | curr_per_ns = if let Some(r) = scope.get(&name) { |
180 | r.def_id | 171 | r.def_id |
181 | } else { | 172 | } else { |
182 | return Ok(PerNs::none()); | 173 | return PerNs::none(); |
183 | }; | 174 | }; |
184 | } | 175 | } |
185 | Ok(curr_per_ns) | 176 | curr_per_ns |
186 | } | 177 | } |
187 | 178 | ||
188 | pub fn problems_impl( | 179 | pub fn problems_impl(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> { |
189 | &self, | ||
190 | db: &impl HirDatabase, | ||
191 | ) -> Cancelable<Vec<(TreeArc<SyntaxNode>, Problem)>> { | ||
192 | let loc = self.def_id.loc(db); | 180 | let loc = self.def_id.loc(db); |
193 | let module_tree = db.module_tree(loc.source_root_id)?; | 181 | let module_tree = db.module_tree(loc.source_root_id); |
194 | Ok(loc.module_id.problems(&module_tree, db)) | 182 | loc.module_id.problems(&module_tree, db) |
195 | } | 183 | } |
196 | } | 184 | } |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index fd6336dd8..0a0994f5f 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; | 3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; |
4 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; | 4 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, | 7 | DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, |
@@ -32,37 +32,37 @@ pub trait HirDatabase: SyntaxDatabase | |||
32 | use fn crate::macros::expand_macro_invocation; | 32 | use fn crate::macros::expand_macro_invocation; |
33 | } | 33 | } |
34 | 34 | ||
35 | fn fn_scopes(def_id: DefId) -> Cancelable<Arc<FnScopes>> { | 35 | fn fn_scopes(def_id: DefId) -> Arc<FnScopes> { |
36 | type FnScopesQuery; | 36 | type FnScopesQuery; |
37 | use fn query_definitions::fn_scopes; | 37 | use fn query_definitions::fn_scopes; |
38 | } | 38 | } |
39 | 39 | ||
40 | fn struct_data(def_id: DefId) -> Cancelable<Arc<StructData>> { | 40 | fn struct_data(def_id: DefId) -> Arc<StructData> { |
41 | type StructDataQuery; | 41 | type StructDataQuery; |
42 | use fn crate::adt::StructData::struct_data_query; | 42 | use fn crate::adt::StructData::struct_data_query; |
43 | } | 43 | } |
44 | 44 | ||
45 | fn enum_data(def_id: DefId) -> Cancelable<Arc<EnumData>> { | 45 | fn enum_data(def_id: DefId) -> Arc<EnumData> { |
46 | type EnumDataQuery; | 46 | type EnumDataQuery; |
47 | use fn crate::adt::EnumData::enum_data_query; | 47 | use fn crate::adt::EnumData::enum_data_query; |
48 | } | 48 | } |
49 | 49 | ||
50 | fn enum_variant_data(def_id: DefId) -> Cancelable<Arc<EnumVariantData>> { | 50 | fn enum_variant_data(def_id: DefId) -> Arc<EnumVariantData> { |
51 | type EnumVariantDataQuery; | 51 | type EnumVariantDataQuery; |
52 | use fn crate::adt::EnumVariantData::enum_variant_data_query; | 52 | use fn crate::adt::EnumVariantData::enum_variant_data_query; |
53 | } | 53 | } |
54 | 54 | ||
55 | fn infer(def_id: DefId) -> Cancelable<Arc<InferenceResult>> { | 55 | fn infer(def_id: DefId) -> Arc<InferenceResult> { |
56 | type InferQuery; | 56 | type InferQuery; |
57 | use fn crate::ty::infer; | 57 | use fn crate::ty::infer; |
58 | } | 58 | } |
59 | 59 | ||
60 | fn type_for_def(def_id: DefId) -> Cancelable<Ty> { | 60 | fn type_for_def(def_id: DefId) -> Ty { |
61 | type TypeForDefQuery; | 61 | type TypeForDefQuery; |
62 | use fn crate::ty::type_for_def; | 62 | use fn crate::ty::type_for_def; |
63 | } | 63 | } |
64 | 64 | ||
65 | fn type_for_field(def_id: DefId, field: Name) -> Cancelable<Option<Ty>> { | 65 | fn type_for_field(def_id: DefId, field: Name) -> Option<Ty> { |
66 | type TypeForFieldQuery; | 66 | type TypeForFieldQuery; |
67 | use fn crate::ty::type_for_field; | 67 | use fn crate::ty::type_for_field; |
68 | } | 68 | } |
@@ -77,42 +77,42 @@ pub trait HirDatabase: SyntaxDatabase | |||
77 | use fn query_definitions::file_item; | 77 | use fn query_definitions::file_item; |
78 | } | 78 | } |
79 | 79 | ||
80 | fn submodules(source: SourceItemId) -> Cancelable<Arc<Vec<crate::module_tree::Submodule>>> { | 80 | fn submodules(source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>> { |
81 | type SubmodulesQuery; | 81 | type SubmodulesQuery; |
82 | use fn crate::module_tree::Submodule::submodules_query; | 82 | use fn crate::module_tree::Submodule::submodules_query; |
83 | } | 83 | } |
84 | 84 | ||
85 | fn input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> { | 85 | fn input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Arc<InputModuleItems> { |
86 | type InputModuleItemsQuery; | 86 | type InputModuleItemsQuery; |
87 | use fn query_definitions::input_module_items; | 87 | use fn query_definitions::input_module_items; |
88 | } | 88 | } |
89 | 89 | ||
90 | fn item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> { | 90 | fn item_map(source_root_id: SourceRootId) -> Arc<ItemMap> { |
91 | type ItemMapQuery; | 91 | type ItemMapQuery; |
92 | use fn query_definitions::item_map; | 92 | use fn query_definitions::item_map; |
93 | } | 93 | } |
94 | 94 | ||
95 | fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> { | 95 | fn module_tree(source_root_id: SourceRootId) -> Arc<ModuleTree> { |
96 | type ModuleTreeQuery; | 96 | type ModuleTreeQuery; |
97 | use fn crate::module_tree::ModuleTree::module_tree_query; | 97 | use fn crate::module_tree::ModuleTree::module_tree_query; |
98 | } | 98 | } |
99 | 99 | ||
100 | fn impls_in_module(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<ModuleImplBlocks>> { | 100 | fn impls_in_module(source_root_id: SourceRootId, module_id: ModuleId) -> Arc<ModuleImplBlocks> { |
101 | type ImplsInModuleQuery; | 101 | type ImplsInModuleQuery; |
102 | use fn crate::impl_block::impls_in_module; | 102 | use fn crate::impl_block::impls_in_module; |
103 | } | 103 | } |
104 | 104 | ||
105 | fn impls_in_crate(krate: Crate) -> Cancelable<Arc<CrateImplBlocks>> { | 105 | fn impls_in_crate(krate: Crate) -> Arc<CrateImplBlocks> { |
106 | type ImplsInCrateQuery; | 106 | type ImplsInCrateQuery; |
107 | use fn crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query; | 107 | use fn crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query; |
108 | } | 108 | } |
109 | 109 | ||
110 | fn body_hir(def_id: DefId) -> Cancelable<Arc<crate::expr::Body>> { | 110 | fn body_hir(def_id: DefId) -> Arc<crate::expr::Body> { |
111 | type BodyHirQuery; | 111 | type BodyHirQuery; |
112 | use fn crate::expr::body_hir; | 112 | use fn crate::expr::body_hir; |
113 | } | 113 | } |
114 | 114 | ||
115 | fn body_syntax_mapping(def_id: DefId) -> Cancelable<Arc<crate::expr::BodySyntaxMapping>> { | 115 | fn body_syntax_mapping(def_id: DefId) -> Arc<crate::expr::BodySyntaxMapping> { |
116 | type BodySyntaxMappingQuery; | 116 | type BodySyntaxMappingQuery; |
117 | use fn crate::expr::body_syntax_mapping; | 117 | use fn crate::expr::body_syntax_mapping; |
118 | } | 118 | } |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index f0936e9f3..663338844 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -4,10 +4,11 @@ use std::sync::Arc; | |||
4 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
5 | 5 | ||
6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
7 | use ra_db::{LocalSyntaxPtr, Cancelable}; | 7 | use ra_db::LocalSyntaxPtr; |
8 | use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}; | 8 | use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}; |
9 | 9 | ||
10 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; | 10 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; |
11 | use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; | ||
11 | 12 | ||
12 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 13 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
13 | pub struct ExprId(RawId); | 14 | pub struct ExprId(RawId); |
@@ -104,6 +105,16 @@ impl BodySyntaxMapping { | |||
104 | } | 105 | } |
105 | 106 | ||
106 | #[derive(Debug, Clone, Eq, PartialEq)] | 107 | #[derive(Debug, Clone, Eq, PartialEq)] |
108 | pub enum Literal { | ||
109 | String(String), | ||
110 | ByteString(Vec<u8>), | ||
111 | Char(char), | ||
112 | Bool(bool), | ||
113 | Int(u64, UncertainIntTy), | ||
114 | Float(u64, UncertainFloatTy), // FIXME: f64 is not Eq | ||
115 | } | ||
116 | |||
117 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
107 | pub enum Expr { | 118 | pub enum Expr { |
108 | /// This is produced if syntax tree does not have a required expression piece. | 119 | /// This is produced if syntax tree does not have a required expression piece. |
109 | Missing, | 120 | Missing, |
@@ -171,7 +182,7 @@ pub enum Expr { | |||
171 | }, | 182 | }, |
172 | UnaryOp { | 183 | UnaryOp { |
173 | expr: ExprId, | 184 | expr: ExprId, |
174 | op: Option<UnaryOp>, | 185 | op: UnaryOp, |
175 | }, | 186 | }, |
176 | BinaryOp { | 187 | BinaryOp { |
177 | lhs: ExprId, | 188 | lhs: ExprId, |
@@ -186,6 +197,7 @@ pub enum Expr { | |||
186 | Tuple { | 197 | Tuple { |
187 | exprs: Vec<ExprId>, | 198 | exprs: Vec<ExprId>, |
188 | }, | 199 | }, |
200 | Literal(Literal), | ||
189 | } | 201 | } |
190 | 202 | ||
191 | pub use ra_syntax::ast::PrefixOp as UnaryOp; | 203 | pub use ra_syntax::ast::PrefixOp as UnaryOp; |
@@ -305,6 +317,7 @@ impl Expr { | |||
305 | f(*expr); | 317 | f(*expr); |
306 | } | 318 | } |
307 | } | 319 | } |
320 | Expr::Literal(_) => {} | ||
308 | } | 321 | } |
309 | } | 322 | } |
310 | } | 323 | } |
@@ -343,8 +356,8 @@ impl Pat { | |||
343 | 356 | ||
344 | // Queries | 357 | // Queries |
345 | 358 | ||
346 | pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<Body>> { | 359 | pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Arc<Body> { |
347 | Ok(Arc::clone(&body_syntax_mapping(db, def_id)?.body)) | 360 | Arc::clone(&body_syntax_mapping(db, def_id).body) |
348 | } | 361 | } |
349 | 362 | ||
350 | struct ExprCollector { | 363 | struct ExprCollector { |
@@ -599,8 +612,11 @@ impl ExprCollector { | |||
599 | } | 612 | } |
600 | ast::ExprKind::PrefixExpr(e) => { | 613 | ast::ExprKind::PrefixExpr(e) => { |
601 | let expr = self.collect_expr_opt(e.expr()); | 614 | let expr = self.collect_expr_opt(e.expr()); |
602 | let op = e.op(); | 615 | if let Some(op) = e.op() { |
603 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) | 616 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) |
617 | } else { | ||
618 | self.alloc_expr(Expr::Missing, syntax_ptr) | ||
619 | } | ||
604 | } | 620 | } |
605 | ast::ExprKind::LambdaExpr(e) => { | 621 | ast::ExprKind::LambdaExpr(e) => { |
606 | let mut args = Vec::new(); | 622 | let mut args = Vec::new(); |
@@ -633,13 +649,50 @@ impl ExprCollector { | |||
633 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 649 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); |
634 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 650 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
635 | } | 651 | } |
652 | ast::ExprKind::Literal(e) => { | ||
653 | let child = if let Some(child) = e.literal_expr() { | ||
654 | child | ||
655 | } else { | ||
656 | return self.alloc_expr(Expr::Missing, syntax_ptr); | ||
657 | }; | ||
658 | |||
659 | let lit = match child.flavor() { | ||
660 | LiteralFlavor::IntNumber { suffix } => { | ||
661 | let known_name = suffix | ||
662 | .map(|s| Name::new(s)) | ||
663 | .and_then(|name| UncertainIntTy::from_name(&name)); | ||
664 | |||
665 | Literal::Int( | ||
666 | Default::default(), | ||
667 | known_name.unwrap_or(UncertainIntTy::Unknown), | ||
668 | ) | ||
669 | } | ||
670 | LiteralFlavor::FloatNumber { suffix } => { | ||
671 | let known_name = suffix | ||
672 | .map(|s| Name::new(s)) | ||
673 | .and_then(|name| UncertainFloatTy::from_name(&name)); | ||
674 | |||
675 | Literal::Float( | ||
676 | Default::default(), | ||
677 | known_name.unwrap_or(UncertainFloatTy::Unknown), | ||
678 | ) | ||
679 | } | ||
680 | LiteralFlavor::ByteString => Literal::ByteString(Default::default()), | ||
681 | LiteralFlavor::String => Literal::String(Default::default()), | ||
682 | LiteralFlavor::Byte => { | ||
683 | Literal::Int(Default::default(), UncertainIntTy::Unsigned(UintTy::U8)) | ||
684 | } | ||
685 | LiteralFlavor::Bool => Literal::Bool(Default::default()), | ||
686 | LiteralFlavor::Char => Literal::Char(Default::default()), | ||
687 | }; | ||
688 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) | ||
689 | } | ||
636 | 690 | ||
637 | // TODO implement HIR for these: | 691 | // TODO implement HIR for these: |
638 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 692 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
639 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 693 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
640 | ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 694 | ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
641 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 695 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
642 | ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
643 | } | 696 | } |
644 | } | 697 | } |
645 | 698 | ||
@@ -776,17 +829,14 @@ pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping { | |||
776 | collector.into_body_syntax_mapping(params, body) | 829 | collector.into_body_syntax_mapping(params, body) |
777 | } | 830 | } |
778 | 831 | ||
779 | pub(crate) fn body_syntax_mapping( | 832 | pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, def_id: DefId) -> Arc<BodySyntaxMapping> { |
780 | db: &impl HirDatabase, | 833 | let def = def_id.resolve(db); |
781 | def_id: DefId, | ||
782 | ) -> Cancelable<Arc<BodySyntaxMapping>> { | ||
783 | let def = def_id.resolve(db)?; | ||
784 | 834 | ||
785 | let body_syntax_mapping = match def { | 835 | let body_syntax_mapping = match def { |
786 | Def::Function(f) => collect_fn_body_syntax(&f.source(db)?.1), | 836 | Def::Function(f) => collect_fn_body_syntax(&f.source(db).1), |
787 | // TODO: consts, etc. | 837 | // TODO: consts, etc. |
788 | _ => panic!("Trying to get body for item type without body"), | 838 | _ => panic!("Trying to get body for item type without body"), |
789 | }; | 839 | }; |
790 | 840 | ||
791 | Ok(Arc::new(body_syntax_mapping)) | 841 | Arc::new(body_syntax_mapping) |
792 | } | 842 | } |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 316896dce..0d8e67547 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId}; | 1 | use ra_db::{SourceRootId, LocationIntener, FileId}; |
2 | use ra_syntax::{TreeArc, SyntaxKind, SyntaxNode, SourceFile, AstNode, ast}; | 2 | use ra_syntax::{TreeArc, SyntaxKind, SyntaxNode, SourceFile, AstNode, ast}; |
3 | use ra_arena::{Arena, RawId, impl_arena_id}; | 3 | use ra_arena::{Arena, RawId, impl_arena_id}; |
4 | 4 | ||
@@ -159,11 +159,11 @@ impl DefId { | |||
159 | db.as_ref().id2loc(self) | 159 | db.as_ref().id2loc(self) |
160 | } | 160 | } |
161 | 161 | ||
162 | pub fn resolve(self, db: &impl HirDatabase) -> Cancelable<Def> { | 162 | pub fn resolve(self, db: &impl HirDatabase) -> Def { |
163 | let loc = self.loc(db); | 163 | let loc = self.loc(db); |
164 | let res = match loc.kind { | 164 | match loc.kind { |
165 | DefKind::Module => { | 165 | DefKind::Module => { |
166 | let module = Module::from_module_id(db, loc.source_root_id, loc.module_id)?; | 166 | let module = Module::from_module_id(db, loc.source_root_id, loc.module_id); |
167 | Def::Module(module) | 167 | Def::Module(module) |
168 | } | 168 | } |
169 | DefKind::Function => { | 169 | DefKind::Function => { |
@@ -195,8 +195,7 @@ impl DefId { | |||
195 | 195 | ||
196 | DefKind::StructCtor => Def::Item, | 196 | DefKind::StructCtor => Def::Item, |
197 | DefKind::Item => Def::Item, | 197 | DefKind::Item => Def::Item, |
198 | }; | 198 | } |
199 | Ok(res) | ||
200 | } | 199 | } |
201 | 200 | ||
202 | pub(crate) fn source(self, db: &impl HirDatabase) -> (HirFileId, TreeArc<SyntaxNode>) { | 201 | pub(crate) fn source(self, db: &impl HirDatabase) -> (HirFileId, TreeArc<SyntaxNode>) { |
@@ -206,21 +205,21 @@ impl DefId { | |||
206 | } | 205 | } |
207 | 206 | ||
208 | /// For a module, returns that module; for any other def, returns the containing module. | 207 | /// For a module, returns that module; for any other def, returns the containing module. |
209 | pub fn module(self, db: &impl HirDatabase) -> Cancelable<Module> { | 208 | pub fn module(self, db: &impl HirDatabase) -> Module { |
210 | let loc = self.loc(db); | 209 | let loc = self.loc(db); |
211 | Module::from_module_id(db, loc.source_root_id, loc.module_id) | 210 | Module::from_module_id(db, loc.source_root_id, loc.module_id) |
212 | } | 211 | } |
213 | 212 | ||
214 | /// Returns the containing crate. | 213 | /// Returns the containing crate. |
215 | pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { | 214 | pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { |
216 | Ok(self.module(db)?.krate(db)?) | 215 | self.module(db).krate(db) |
217 | } | 216 | } |
218 | 217 | ||
219 | /// Returns the containing impl block, if this is an impl item. | 218 | /// Returns the containing impl block, if this is an impl item. |
220 | pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> { | 219 | pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> { |
221 | let loc = self.loc(db); | 220 | let loc = self.loc(db); |
222 | let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id)?; | 221 | let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id); |
223 | Ok(ImplBlock::containing(module_impls, self)) | 222 | ImplBlock::containing(module_impls, self) |
224 | } | 223 | } |
225 | } | 224 | } |
226 | 225 | ||
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index d0b086308..ab996a12c 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -3,7 +3,7 @@ use rustc_hash::FxHashMap; | |||
3 | 3 | ||
4 | use ra_arena::{Arena, RawId, impl_arena_id}; | 4 | use ra_arena::{Arena, RawId, impl_arena_id}; |
5 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | use ra_db::{LocationIntener, Cancelable, SourceRootId}; | 6 | use ra_db::{LocationIntener, SourceRootId}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, | 9 | DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, |
@@ -166,8 +166,8 @@ impl ModuleImplBlocks { | |||
166 | } | 166 | } |
167 | } | 167 | } |
168 | 168 | ||
169 | fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { | 169 | fn collect(&mut self, db: &impl HirDatabase, module: Module) { |
170 | let (file_id, module_source) = module.definition_source(db)?; | 170 | let (file_id, module_source) = module.definition_source(db); |
171 | let node = match &module_source { | 171 | let node = match &module_source { |
172 | ModuleSource::SourceFile(node) => node.syntax(), | 172 | ModuleSource::SourceFile(node) => node.syntax(), |
173 | ModuleSource::Module(node) => node | 173 | ModuleSource::Module(node) => node |
@@ -185,8 +185,6 @@ impl ModuleImplBlocks { | |||
185 | self.impls_by_def.insert(impl_item.def_id(), id); | 185 | self.impls_by_def.insert(impl_item.def_id(), id); |
186 | } | 186 | } |
187 | } | 187 | } |
188 | |||
189 | Ok(()) | ||
190 | } | 188 | } |
191 | } | 189 | } |
192 | 190 | ||
@@ -194,9 +192,9 @@ pub(crate) fn impls_in_module( | |||
194 | db: &impl HirDatabase, | 192 | db: &impl HirDatabase, |
195 | source_root_id: SourceRootId, | 193 | source_root_id: SourceRootId, |
196 | module_id: ModuleId, | 194 | module_id: ModuleId, |
197 | ) -> Cancelable<Arc<ModuleImplBlocks>> { | 195 | ) -> Arc<ModuleImplBlocks> { |
198 | let mut result = ModuleImplBlocks::new(); | 196 | let mut result = ModuleImplBlocks::new(); |
199 | let module = Module::from_module_id(db, source_root_id, module_id)?; | 197 | let module = Module::from_module_id(db, source_root_id, module_id); |
200 | result.collect(db, module)?; | 198 | result.collect(db, module); |
201 | Ok(Arc::new(result)) | 199 | Arc::new(result) |
202 | } | 200 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 45dda4f7f..ef7d049ee 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -5,15 +5,6 @@ | |||
5 | //! to a particular crate instance. That is, it has cfg flags and features | 5 | //! to a particular crate instance. That is, it has cfg flags and features |
6 | //! applied. So, the relation between syntax and HIR is many-to-one. | 6 | //! applied. So, the relation between syntax and HIR is many-to-one. |
7 | 7 | ||
8 | macro_rules! ctry { | ||
9 | ($expr:expr) => { | ||
10 | match $expr { | ||
11 | None => return Ok(None), | ||
12 | Some(it) => it, | ||
13 | } | ||
14 | }; | ||
15 | } | ||
16 | |||
17 | pub mod db; | 8 | pub mod db; |
18 | #[cfg(test)] | 9 | #[cfg(test)] |
19 | mod mock; | 10 | mod mock; |
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index 67823e970..0256d7996 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | use arrayvec::ArrayVec; | 4 | use arrayvec::ArrayVec; |
5 | use relative_path::RelativePathBuf; | 5 | use relative_path::RelativePathBuf; |
6 | use ra_db::{FileId, SourceRootId, Cancelable, SourceRoot}; | 6 | use ra_db::{FileId, SourceRootId, SourceRoot}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | SyntaxNode, TreeArc, | 8 | SyntaxNode, TreeArc, |
9 | algo::generate, | 9 | algo::generate, |
@@ -41,8 +41,8 @@ impl Submodule { | |||
41 | pub(crate) fn submodules_query( | 41 | pub(crate) fn submodules_query( |
42 | db: &impl HirDatabase, | 42 | db: &impl HirDatabase, |
43 | source: SourceItemId, | 43 | source: SourceItemId, |
44 | ) -> Cancelable<Arc<Vec<Submodule>>> { | 44 | ) -> Arc<Vec<Submodule>> { |
45 | db.check_canceled()?; | 45 | db.check_canceled(); |
46 | let file_id = source.file_id; | 46 | let file_id = source.file_id; |
47 | let file_items = db.file_items(file_id); | 47 | let file_items = db.file_items(file_id); |
48 | let module_source = ModuleSource::from_source_item_id(db, source); | 48 | let module_source = ModuleSource::from_source_item_id(db, source); |
@@ -54,7 +54,7 @@ impl Submodule { | |||
54 | collect_submodules(file_id, &file_items, module.item_list().unwrap()) | 54 | collect_submodules(file_id, &file_items, module.item_list().unwrap()) |
55 | } | 55 | } |
56 | }; | 56 | }; |
57 | return Ok(Arc::new(submodules)); | 57 | return Arc::new(submodules); |
58 | 58 | ||
59 | fn collect_submodules( | 59 | fn collect_submodules( |
60 | file_id: HirFileId, | 60 | file_id: HirFileId, |
@@ -116,10 +116,10 @@ impl ModuleTree { | |||
116 | pub(crate) fn module_tree_query( | 116 | pub(crate) fn module_tree_query( |
117 | db: &impl HirDatabase, | 117 | db: &impl HirDatabase, |
118 | source_root: SourceRootId, | 118 | source_root: SourceRootId, |
119 | ) -> Cancelable<Arc<ModuleTree>> { | 119 | ) -> Arc<ModuleTree> { |
120 | db.check_canceled()?; | 120 | db.check_canceled(); |
121 | let res = create_module_tree(db, source_root); | 121 | let res = create_module_tree(db, source_root); |
122 | Ok(Arc::new(res?)) | 122 | Arc::new(res) |
123 | } | 123 | } |
124 | 124 | ||
125 | pub(crate) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a { | 125 | pub(crate) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a { |
@@ -225,10 +225,7 @@ fn modules(root: &impl ast::ModuleItemOwner) -> impl Iterator<Item = (Name, &ast | |||
225 | }) | 225 | }) |
226 | } | 226 | } |
227 | 227 | ||
228 | fn create_module_tree<'a>( | 228 | fn create_module_tree<'a>(db: &impl HirDatabase, source_root: SourceRootId) -> ModuleTree { |
229 | db: &impl HirDatabase, | ||
230 | source_root: SourceRootId, | ||
231 | ) -> Cancelable<ModuleTree> { | ||
232 | let mut tree = ModuleTree::default(); | 229 | let mut tree = ModuleTree::default(); |
233 | 230 | ||
234 | let mut roots = FxHashMap::default(); | 231 | let mut roots = FxHashMap::default(); |
@@ -252,10 +249,10 @@ fn create_module_tree<'a>( | |||
252 | &mut roots, | 249 | &mut roots, |
253 | None, | 250 | None, |
254 | source, | 251 | source, |
255 | )?; | 252 | ); |
256 | roots.insert(file_id, module_id); | 253 | roots.insert(file_id, module_id); |
257 | } | 254 | } |
258 | Ok(tree) | 255 | tree |
259 | } | 256 | } |
260 | 257 | ||
261 | fn build_subtree( | 258 | fn build_subtree( |
@@ -266,14 +263,14 @@ fn build_subtree( | |||
266 | roots: &mut FxHashMap<FileId, ModuleId>, | 263 | roots: &mut FxHashMap<FileId, ModuleId>, |
267 | parent: Option<LinkId>, | 264 | parent: Option<LinkId>, |
268 | source: SourceItemId, | 265 | source: SourceItemId, |
269 | ) -> Cancelable<ModuleId> { | 266 | ) -> ModuleId { |
270 | visited.insert(source); | 267 | visited.insert(source); |
271 | let id = tree.push_mod(ModuleData { | 268 | let id = tree.push_mod(ModuleData { |
272 | source, | 269 | source, |
273 | parent, | 270 | parent, |
274 | children: Vec::new(), | 271 | children: Vec::new(), |
275 | }); | 272 | }); |
276 | for sub in db.submodules(source)?.iter() { | 273 | for sub in db.submodules(source).iter() { |
277 | let link = tree.push_link(LinkData { | 274 | let link = tree.push_link(LinkData { |
278 | source: sub.source, | 275 | source: sub.source, |
279 | name: sub.name.clone(), | 276 | name: sub.name.clone(), |
@@ -289,7 +286,7 @@ fn build_subtree( | |||
289 | .map(|file_id| match roots.remove(&file_id) { | 286 | .map(|file_id| match roots.remove(&file_id) { |
290 | Some(module_id) => { | 287 | Some(module_id) => { |
291 | tree.mods[module_id].parent = Some(link); | 288 | tree.mods[module_id].parent = Some(link); |
292 | Ok(module_id) | 289 | module_id |
293 | } | 290 | } |
294 | None => build_subtree( | 291 | None => build_subtree( |
295 | db, | 292 | db, |
@@ -304,7 +301,7 @@ fn build_subtree( | |||
304 | }, | 301 | }, |
305 | ), | 302 | ), |
306 | }) | 303 | }) |
307 | .collect::<Cancelable<Vec<_>>>()?; | 304 | .collect::<Vec<_>>(); |
308 | (points_to, problem) | 305 | (points_to, problem) |
309 | } else { | 306 | } else { |
310 | let points_to = build_subtree( | 307 | let points_to = build_subtree( |
@@ -315,14 +312,14 @@ fn build_subtree( | |||
315 | roots, | 312 | roots, |
316 | Some(link), | 313 | Some(link), |
317 | sub.source, | 314 | sub.source, |
318 | )?; | 315 | ); |
319 | (vec![points_to], None) | 316 | (vec![points_to], None) |
320 | }; | 317 | }; |
321 | 318 | ||
322 | tree.links[link].points_to = points_to; | 319 | tree.links[link].points_to = points_to; |
323 | tree.links[link].problem = problem; | 320 | tree.links[link].problem = problem; |
324 | } | 321 | } |
325 | Ok(id) | 322 | id |
326 | } | 323 | } |
327 | 324 | ||
328 | fn resolve_submodule( | 325 | fn resolve_submodule( |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index d9683549c..8d786d2ac 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs | |||
@@ -23,7 +23,7 @@ impl fmt::Debug for Name { | |||
23 | } | 23 | } |
24 | 24 | ||
25 | impl Name { | 25 | impl Name { |
26 | fn new(text: SmolStr) -> Name { | 26 | pub(crate) fn new(text: SmolStr) -> Name { |
27 | Name { text } | 27 | Name { text } |
28 | } | 28 | } |
29 | 29 | ||
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 6bf949654..484f668d0 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -22,7 +22,7 @@ use ra_syntax::{ | |||
22 | SyntaxKind::{self, *}, | 22 | SyntaxKind::{self, *}, |
23 | ast::{self, AstNode} | 23 | ast::{self, AstNode} |
24 | }; | 24 | }; |
25 | use ra_db::{SourceRootId, Cancelable, FileId}; | 25 | use ra_db::{SourceRootId, FileId}; |
26 | 26 | ||
27 | use crate::{ | 27 | use crate::{ |
28 | HirFileId, | 28 | HirFileId, |
@@ -319,30 +319,26 @@ where | |||
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | pub(crate) fn resolve(mut self) -> Cancelable<ItemMap> { | 322 | pub(crate) fn resolve(mut self) -> ItemMap { |
323 | for (&module_id, items) in self.input.iter() { | 323 | for (&module_id, items) in self.input.iter() { |
324 | self.populate_module(module_id, Arc::clone(items))?; | 324 | self.populate_module(module_id, Arc::clone(items)); |
325 | } | 325 | } |
326 | 326 | ||
327 | loop { | 327 | loop { |
328 | let processed_imports_count = self.processed_imports.len(); | 328 | let processed_imports_count = self.processed_imports.len(); |
329 | for &module_id in self.input.keys() { | 329 | for &module_id in self.input.keys() { |
330 | self.db.check_canceled()?; | 330 | self.db.check_canceled(); |
331 | self.resolve_imports(module_id)?; | 331 | self.resolve_imports(module_id); |
332 | } | 332 | } |
333 | if processed_imports_count == self.processed_imports.len() { | 333 | if processed_imports_count == self.processed_imports.len() { |
334 | // no new imports resolved | 334 | // no new imports resolved |
335 | break; | 335 | break; |
336 | } | 336 | } |
337 | } | 337 | } |
338 | Ok(self.result) | 338 | self.result |
339 | } | 339 | } |
340 | 340 | ||
341 | fn populate_module( | 341 | fn populate_module(&mut self, module_id: ModuleId, input: Arc<InputModuleItems>) { |
342 | &mut self, | ||
343 | module_id: ModuleId, | ||
344 | input: Arc<InputModuleItems>, | ||
345 | ) -> Cancelable<()> { | ||
346 | let mut module_items = ModuleScope::default(); | 342 | let mut module_items = ModuleScope::default(); |
347 | 343 | ||
348 | // Populate extern crates prelude | 344 | // Populate extern crates prelude |
@@ -353,8 +349,8 @@ where | |||
353 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file()) | 349 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file()) |
354 | { | 350 | { |
355 | let krate = Crate::new(crate_id); | 351 | let krate = Crate::new(crate_id); |
356 | for dep in krate.dependencies(self.db)? { | 352 | for dep in krate.dependencies(self.db) { |
357 | if let Some(module) = dep.krate.root_module(self.db)? { | 353 | if let Some(module) = dep.krate.root_module(self.db) { |
358 | let def_id = module.def_id; | 354 | let def_id = module.def_id; |
359 | self.add_module_item( | 355 | self.add_module_item( |
360 | &mut module_items, | 356 | &mut module_items, |
@@ -415,7 +411,6 @@ where | |||
415 | } | 411 | } |
416 | 412 | ||
417 | self.result.per_module.insert(module_id, module_items); | 413 | self.result.per_module.insert(module_id, module_items); |
418 | Ok(()) | ||
419 | } | 414 | } |
420 | 415 | ||
421 | fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def_id: PerNs<DefId>) { | 416 | fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def_id: PerNs<DefId>) { |
@@ -426,24 +421,23 @@ where | |||
426 | module_items.items.insert(name, resolution); | 421 | module_items.items.insert(name, resolution); |
427 | } | 422 | } |
428 | 423 | ||
429 | fn resolve_imports(&mut self, module_id: ModuleId) -> Cancelable<()> { | 424 | fn resolve_imports(&mut self, module_id: ModuleId) { |
430 | for (i, import) in self.input[&module_id].imports.iter().enumerate() { | 425 | for (i, import) in self.input[&module_id].imports.iter().enumerate() { |
431 | if self.processed_imports.contains(&(module_id, i)) { | 426 | if self.processed_imports.contains(&(module_id, i)) { |
432 | // already done | 427 | // already done |
433 | continue; | 428 | continue; |
434 | } | 429 | } |
435 | if self.resolve_import(module_id, import)? { | 430 | if self.resolve_import(module_id, import) { |
436 | log::debug!("import {:?} resolved (or definite error)", import); | 431 | log::debug!("import {:?} resolved (or definite error)", import); |
437 | self.processed_imports.insert((module_id, i)); | 432 | self.processed_imports.insert((module_id, i)); |
438 | } | 433 | } |
439 | } | 434 | } |
440 | Ok(()) | ||
441 | } | 435 | } |
442 | 436 | ||
443 | fn resolve_import(&mut self, module_id: ModuleId, import: &Import) -> Cancelable<bool> { | 437 | fn resolve_import(&mut self, module_id: ModuleId, import: &Import) -> bool { |
444 | log::debug!("resolving import: {:?}", import); | 438 | log::debug!("resolving import: {:?}", import); |
445 | let ptr = match import.kind { | 439 | let ptr = match import.kind { |
446 | ImportKind::Glob => return Ok(false), | 440 | ImportKind::Glob => return false, |
447 | ImportKind::Named(ptr) => ptr, | 441 | ImportKind::Named(ptr) => ptr, |
448 | }; | 442 | }; |
449 | 443 | ||
@@ -455,7 +449,7 @@ where | |||
455 | None => { | 449 | None => { |
456 | // TODO: error | 450 | // TODO: error |
457 | log::debug!("super path in root module"); | 451 | log::debug!("super path in root module"); |
458 | return Ok(true); // this can't suddenly resolve if we just resolve some other imports | 452 | return true; // this can't suddenly resolve if we just resolve some other imports |
459 | } | 453 | } |
460 | } | 454 | } |
461 | } | 455 | } |
@@ -469,7 +463,7 @@ where | |||
469 | Some(res) if !res.def_id.is_none() => res.def_id, | 463 | Some(res) if !res.def_id.is_none() => res.def_id, |
470 | _ => { | 464 | _ => { |
471 | log::debug!("path segment {:?} not found", name); | 465 | log::debug!("path segment {:?} not found", name); |
472 | return Ok(false); | 466 | return false; |
473 | } | 467 | } |
474 | }; | 468 | }; |
475 | 469 | ||
@@ -481,7 +475,7 @@ where | |||
481 | "path segment {:?} resolved to value only, but is not last", | 475 | "path segment {:?} resolved to value only, but is not last", |
482 | name | 476 | name |
483 | ); | 477 | ); |
484 | return Ok(false); | 478 | return false; |
485 | }; | 479 | }; |
486 | curr = match type_def_id.loc(self.db) { | 480 | curr = match type_def_id.loc(self.db) { |
487 | DefLoc { | 481 | DefLoc { |
@@ -499,7 +493,7 @@ where | |||
499 | kind: PathKind::Crate, | 493 | kind: PathKind::Crate, |
500 | }; | 494 | }; |
501 | log::debug!("resolving {:?} in other source root", path); | 495 | log::debug!("resolving {:?} in other source root", path); |
502 | let def_id = module.resolve_path(self.db, &path)?; | 496 | let def_id = module.resolve_path(self.db, &path); |
503 | if !def_id.is_none() { | 497 | if !def_id.is_none() { |
504 | let name = path.segments.last().unwrap(); | 498 | let name = path.segments.last().unwrap(); |
505 | self.update(module_id, |items| { | 499 | self.update(module_id, |items| { |
@@ -515,10 +509,10 @@ where | |||
515 | import, | 509 | import, |
516 | def_id.map(|did| did.loc(self.db)) | 510 | def_id.map(|did| did.loc(self.db)) |
517 | ); | 511 | ); |
518 | return Ok(true); | 512 | return true; |
519 | } else { | 513 | } else { |
520 | log::debug!("rest of path did not resolve in other source root"); | 514 | log::debug!("rest of path did not resolve in other source root"); |
521 | return Ok(true); | 515 | return true; |
522 | } | 516 | } |
523 | } | 517 | } |
524 | } | 518 | } |
@@ -528,7 +522,7 @@ where | |||
528 | name, | 522 | name, |
529 | type_def_id.loc(self.db) | 523 | type_def_id.loc(self.db) |
530 | ); | 524 | ); |
531 | return Ok(true); // this resolved to a non-module, so the path won't ever resolve | 525 | return true; // this resolved to a non-module, so the path won't ever resolve |
532 | } | 526 | } |
533 | } | 527 | } |
534 | } else { | 528 | } else { |
@@ -547,7 +541,7 @@ where | |||
547 | }) | 541 | }) |
548 | } | 542 | } |
549 | } | 543 | } |
550 | Ok(true) | 544 | true |
551 | } | 545 | } |
552 | 546 | ||
553 | fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) { | 547 | fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) { |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 647fd92aa..9a0474045 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -15,11 +15,9 @@ use crate::{ | |||
15 | fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { | 15 | fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { |
16 | let (db, pos) = MockDatabase::with_position(fixture); | 16 | let (db, pos) = MockDatabase::with_position(fixture); |
17 | let source_root = db.file_source_root(pos.file_id); | 17 | let source_root = db.file_source_root(pos.file_id); |
18 | let module = crate::source_binder::module_from_position(&db, pos) | 18 | let module = crate::source_binder::module_from_position(&db, pos).unwrap(); |
19 | .unwrap() | ||
20 | .unwrap(); | ||
21 | let module_id = module.def_id.loc(&db).module_id; | 19 | let module_id = module.def_id.loc(&db).module_id; |
22 | (db.item_map(source_root).unwrap(), module_id) | 20 | (db.item_map(source_root), module_id) |
23 | } | 21 | } |
24 | 22 | ||
25 | fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { | 23 | fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { |
@@ -242,11 +240,9 @@ fn item_map_across_crates() { | |||
242 | db.set_crate_graph(crate_graph); | 240 | db.set_crate_graph(crate_graph); |
243 | 241 | ||
244 | let source_root = db.file_source_root(main_id); | 242 | let source_root = db.file_source_root(main_id); |
245 | let module = crate::source_binder::module_from_file_id(&db, main_id) | 243 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); |
246 | .unwrap() | ||
247 | .unwrap(); | ||
248 | let module_id = module.def_id.loc(&db).module_id; | 244 | let module_id = module.def_id.loc(&db).module_id; |
249 | let item_map = db.item_map(source_root).unwrap(); | 245 | let item_map = db.item_map(source_root); |
250 | 246 | ||
251 | check_module_item_map( | 247 | check_module_item_map( |
252 | &item_map, | 248 | &item_map, |
@@ -296,11 +292,9 @@ fn import_across_source_roots() { | |||
296 | 292 | ||
297 | db.set_crate_graph(crate_graph); | 293 | db.set_crate_graph(crate_graph); |
298 | 294 | ||
299 | let module = crate::source_binder::module_from_file_id(&db, main_id) | 295 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); |
300 | .unwrap() | ||
301 | .unwrap(); | ||
302 | let module_id = module.def_id.loc(&db).module_id; | 296 | let module_id = module.def_id.loc(&db).module_id; |
303 | let item_map = db.item_map(source_root).unwrap(); | 297 | let item_map = db.item_map(source_root); |
304 | 298 | ||
305 | check_module_item_map( | 299 | check_module_item_map( |
306 | &item_map, | 300 | &item_map, |
@@ -341,11 +335,9 @@ fn reexport_across_crates() { | |||
341 | db.set_crate_graph(crate_graph); | 335 | db.set_crate_graph(crate_graph); |
342 | 336 | ||
343 | let source_root = db.file_source_root(main_id); | 337 | let source_root = db.file_source_root(main_id); |
344 | let module = crate::source_binder::module_from_file_id(&db, main_id) | 338 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); |
345 | .unwrap() | ||
346 | .unwrap(); | ||
347 | let module_id = module.def_id.loc(&db).module_id; | 339 | let module_id = module.def_id.loc(&db).module_id; |
348 | let item_map = db.item_map(source_root).unwrap(); | 340 | let item_map = db.item_map(source_root); |
349 | 341 | ||
350 | check_module_item_map( | 342 | check_module_item_map( |
351 | &item_map, | 343 | &item_map, |
@@ -362,7 +354,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { | |||
362 | let source_root = db.file_source_root(pos.file_id); | 354 | let source_root = db.file_source_root(pos.file_id); |
363 | { | 355 | { |
364 | let events = db.log_executed(|| { | 356 | let events = db.log_executed(|| { |
365 | db.item_map(source_root).unwrap(); | 357 | db.item_map(source_root); |
366 | }); | 358 | }); |
367 | assert!(format!("{:?}", events).contains("item_map")) | 359 | assert!(format!("{:?}", events).contains("item_map")) |
368 | } | 360 | } |
@@ -371,7 +363,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { | |||
371 | 363 | ||
372 | { | 364 | { |
373 | let events = db.log_executed(|| { | 365 | let events = db.log_executed(|| { |
374 | db.item_map(source_root).unwrap(); | 366 | db.item_map(source_root); |
375 | }); | 367 | }); |
376 | assert!( | 368 | assert!( |
377 | !format!("{:?}", events).contains("item_map"), | 369 | !format!("{:?}", events).contains("item_map"), |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index 214a9d68b..24cb5c752 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -8,7 +8,7 @@ use ra_syntax::{ | |||
8 | AstNode, SyntaxNode, TreeArc, | 8 | AstNode, SyntaxNode, TreeArc, |
9 | ast::{self, ModuleItemOwner} | 9 | ast::{self, ModuleItemOwner} |
10 | }; | 10 | }; |
11 | use ra_db::{SourceRootId, Cancelable,}; | 11 | use ra_db::SourceRootId; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | SourceFileItems, SourceItemId, DefId, HirFileId, ModuleSource, | 14 | SourceFileItems, SourceItemId, DefId, HirFileId, ModuleSource, |
@@ -18,10 +18,10 @@ use crate::{ | |||
18 | nameres::{InputModuleItems, ItemMap, Resolver}, | 18 | nameres::{InputModuleItems, ItemMap, Resolver}, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | pub(super) fn fn_scopes(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<FnScopes>> { | 21 | pub(super) fn fn_scopes(db: &impl HirDatabase, def_id: DefId) -> Arc<FnScopes> { |
22 | let body = db.body_hir(def_id)?; | 22 | let body = db.body_hir(def_id); |
23 | let res = FnScopes::new(body); | 23 | let res = FnScopes::new(body); |
24 | Ok(Arc::new(res)) | 24 | Arc::new(res) |
25 | } | 25 | } |
26 | 26 | ||
27 | pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { | 27 | pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { |
@@ -47,8 +47,8 @@ pub(super) fn input_module_items( | |||
47 | db: &impl HirDatabase, | 47 | db: &impl HirDatabase, |
48 | source_root_id: SourceRootId, | 48 | source_root_id: SourceRootId, |
49 | module_id: ModuleId, | 49 | module_id: ModuleId, |
50 | ) -> Cancelable<Arc<InputModuleItems>> { | 50 | ) -> Arc<InputModuleItems> { |
51 | let module_tree = db.module_tree(source_root_id)?; | 51 | let module_tree = db.module_tree(source_root_id); |
52 | let source = module_id.source(&module_tree); | 52 | let source = module_id.source(&module_tree); |
53 | let file_id = source.file_id; | 53 | let file_id = source.file_id; |
54 | let source = ModuleSource::from_source_item_id(db, source); | 54 | let source = ModuleSource::from_source_item_id(db, source); |
@@ -90,26 +90,20 @@ pub(super) fn input_module_items( | |||
90 | } | 90 | } |
91 | } | 91 | } |
92 | }; | 92 | }; |
93 | Ok(Arc::new(res)) | 93 | Arc::new(res) |
94 | } | 94 | } |
95 | 95 | ||
96 | pub(super) fn item_map( | 96 | pub(super) fn item_map(db: &impl HirDatabase, source_root: SourceRootId) -> Arc<ItemMap> { |
97 | db: &impl HirDatabase, | ||
98 | source_root: SourceRootId, | ||
99 | ) -> Cancelable<Arc<ItemMap>> { | ||
100 | let start = Instant::now(); | 97 | let start = Instant::now(); |
101 | let module_tree = db.module_tree(source_root)?; | 98 | let module_tree = db.module_tree(source_root); |
102 | let input = module_tree | 99 | let input = module_tree |
103 | .modules() | 100 | .modules() |
104 | .map(|id| { | 101 | .map(|id| (id, db.input_module_items(source_root, id))) |
105 | let items = db.input_module_items(source_root, id)?; | 102 | .collect::<FxHashMap<_, _>>(); |
106 | Ok((id, items)) | ||
107 | }) | ||
108 | .collect::<Cancelable<FxHashMap<_, _>>>()?; | ||
109 | 103 | ||
110 | let resolver = Resolver::new(db, &input, source_root, module_tree); | 104 | let resolver = Resolver::new(db, &input, source_root, module_tree); |
111 | let res = resolver.resolve()?; | 105 | let res = resolver.resolve(); |
112 | let elapsed = start.elapsed(); | 106 | let elapsed = start.elapsed(); |
113 | log::info!("item_map: {:?}", elapsed); | 107 | log::info!("item_map: {:?}", elapsed); |
114 | Ok(Arc::new(res)) | 108 | Arc::new(res) |
115 | } | 109 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 1f149a366..7ab8eeae2 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | /// | 5 | /// |
6 | /// So, this modules should not be used during hir construction, it exists | 6 | /// So, this modules should not be used during hir construction, it exists |
7 | /// purely for "IDE needs". | 7 | /// purely for "IDE needs". |
8 | use ra_db::{FileId, FilePosition, Cancelable}; | 8 | use ra_db::{FileId, FilePosition}; |
9 | use ra_syntax::{ | 9 | use ra_syntax::{ |
10 | SmolStr, TextRange, SyntaxNode, | 10 | SmolStr, TextRange, SyntaxNode, |
11 | ast::{self, AstNode, NameOwner}, | 11 | ast::{self, AstNode, NameOwner}, |
@@ -18,7 +18,7 @@ use crate::{ | |||
18 | }; | 18 | }; |
19 | 19 | ||
20 | /// Locates the module by `FileId`. Picks topmost module in the file. | 20 | /// Locates the module by `FileId`. Picks topmost module in the file. |
21 | pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable<Option<Module>> { | 21 | pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Option<Module> { |
22 | let module_source = SourceItemId { | 22 | let module_source = SourceItemId { |
23 | file_id: file_id.into(), | 23 | file_id: file_id.into(), |
24 | item_id: None, | 24 | item_id: None, |
@@ -31,25 +31,22 @@ pub fn module_from_declaration( | |||
31 | db: &impl HirDatabase, | 31 | db: &impl HirDatabase, |
32 | file_id: FileId, | 32 | file_id: FileId, |
33 | decl: &ast::Module, | 33 | decl: &ast::Module, |
34 | ) -> Cancelable<Option<Module>> { | 34 | ) -> Option<Module> { |
35 | let parent_module = module_from_file_id(db, file_id)?; | 35 | let parent_module = module_from_file_id(db, file_id); |
36 | let child_name = decl.name(); | 36 | let child_name = decl.name(); |
37 | match (parent_module, child_name) { | 37 | match (parent_module, child_name) { |
38 | (Some(parent_module), Some(child_name)) => { | 38 | (Some(parent_module), Some(child_name)) => { |
39 | if let Some(child) = parent_module.child(db, &child_name.as_name())? { | 39 | if let Some(child) = parent_module.child(db, &child_name.as_name()) { |
40 | return Ok(Some(child)); | 40 | return Some(child); |
41 | } | 41 | } |
42 | } | 42 | } |
43 | _ => (), | 43 | _ => (), |
44 | } | 44 | } |
45 | Ok(None) | 45 | None |
46 | } | 46 | } |
47 | 47 | ||
48 | /// Locates the module by position in the source code. | 48 | /// Locates the module by position in the source code. |
49 | pub fn module_from_position( | 49 | pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { |
50 | db: &impl HirDatabase, | ||
51 | position: FilePosition, | ||
52 | ) -> Cancelable<Option<Module>> { | ||
53 | let file = db.source_file(position.file_id); | 50 | let file = db.source_file(position.file_id); |
54 | match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { | 51 | match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { |
55 | Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), | 52 | Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), |
@@ -61,7 +58,7 @@ fn module_from_inline( | |||
61 | db: &impl HirDatabase, | 58 | db: &impl HirDatabase, |
62 | file_id: FileId, | 59 | file_id: FileId, |
63 | module: &ast::Module, | 60 | module: &ast::Module, |
64 | ) -> Cancelable<Option<Module>> { | 61 | ) -> Option<Module> { |
65 | assert!(!module.has_semi()); | 62 | assert!(!module.has_semi()); |
66 | let file_id = file_id.into(); | 63 | let file_id = file_id.into(); |
67 | let file_items = db.file_items(file_id); | 64 | let file_items = db.file_items(file_id); |
@@ -78,7 +75,7 @@ pub fn module_from_child_node( | |||
78 | db: &impl HirDatabase, | 75 | db: &impl HirDatabase, |
79 | file_id: FileId, | 76 | file_id: FileId, |
80 | child: &SyntaxNode, | 77 | child: &SyntaxNode, |
81 | ) -> Cancelable<Option<Module>> { | 78 | ) -> Option<Module> { |
82 | if let Some(m) = child | 79 | if let Some(m) = child |
83 | .ancestors() | 80 | .ancestors() |
84 | .filter_map(ast::Module::cast) | 81 | .filter_map(ast::Module::cast) |
@@ -90,22 +87,16 @@ pub fn module_from_child_node( | |||
90 | } | 87 | } |
91 | } | 88 | } |
92 | 89 | ||
93 | fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Cancelable<Option<Module>> { | 90 | fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Module> { |
94 | let source_root_id = db.file_source_root(source.file_id.as_original_file()); | 91 | let source_root_id = db.file_source_root(source.file_id.as_original_file()); |
95 | let module_tree = db.module_tree(source_root_id)?; | 92 | let module_tree = db.module_tree(source_root_id); |
96 | let module_id = ctry!(module_tree.find_module_by_source(source)); | 93 | let module_id = module_tree.find_module_by_source(source)?; |
97 | Ok(Some(Module::from_module_id(db, source_root_id, module_id)?)) | 94 | Some(Module::from_module_id(db, source_root_id, module_id)) |
98 | } | 95 | } |
99 | 96 | ||
100 | pub fn function_from_position( | 97 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { |
101 | db: &impl HirDatabase, | ||
102 | position: FilePosition, | ||
103 | ) -> Cancelable<Option<Function>> { | ||
104 | let file = db.source_file(position.file_id); | 98 | let file = db.source_file(position.file_id); |
105 | let fn_def = ctry!(find_node_at_offset::<ast::FnDef>( | 99 | let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), position.offset)?; |
106 | file.syntax(), | ||
107 | position.offset | ||
108 | )); | ||
109 | function_from_source(db, position.file_id, fn_def) | 100 | function_from_source(db, position.file_id, fn_def) |
110 | } | 101 | } |
111 | 102 | ||
@@ -113,10 +104,10 @@ pub fn function_from_source( | |||
113 | db: &impl HirDatabase, | 104 | db: &impl HirDatabase, |
114 | file_id: FileId, | 105 | file_id: FileId, |
115 | fn_def: &ast::FnDef, | 106 | fn_def: &ast::FnDef, |
116 | ) -> Cancelable<Option<Function>> { | 107 | ) -> Option<Function> { |
117 | let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?); | 108 | let module = module_from_child_node(db, file_id, fn_def.syntax())?; |
118 | let res = function_from_module(db, &module, fn_def); | 109 | let res = function_from_module(db, &module, fn_def); |
119 | Ok(Some(res)) | 110 | Some(res) |
120 | } | 111 | } |
121 | 112 | ||
122 | pub fn function_from_module( | 113 | pub fn function_from_module( |
@@ -145,21 +136,18 @@ pub fn function_from_child_node( | |||
145 | db: &impl HirDatabase, | 136 | db: &impl HirDatabase, |
146 | file_id: FileId, | 137 | file_id: FileId, |
147 | node: &SyntaxNode, | 138 | node: &SyntaxNode, |
148 | ) -> Cancelable<Option<Function>> { | 139 | ) -> Option<Function> { |
149 | let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast)); | 140 | let fn_def = node.ancestors().find_map(ast::FnDef::cast)?; |
150 | function_from_source(db, file_id, fn_def) | 141 | function_from_source(db, file_id, fn_def) |
151 | } | 142 | } |
152 | 143 | ||
153 | pub fn macro_symbols( | 144 | pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { |
154 | db: &impl HirDatabase, | 145 | let module = match module_from_file_id(db, file_id) { |
155 | file_id: FileId, | ||
156 | ) -> Cancelable<Vec<(SmolStr, TextRange)>> { | ||
157 | let module = match module_from_file_id(db, file_id)? { | ||
158 | Some(it) => it, | 146 | Some(it) => it, |
159 | None => return Ok(Vec::new()), | 147 | None => return Vec::new(), |
160 | }; | 148 | }; |
161 | let loc = module.def_id.loc(db); | 149 | let loc = module.def_id.loc(db); |
162 | let items = db.input_module_items(loc.source_root_id, loc.module_id)?; | 150 | let items = db.input_module_items(loc.source_root_id, loc.module_id); |
163 | let mut res = Vec::new(); | 151 | let mut res = Vec::new(); |
164 | 152 | ||
165 | for macro_call_id in items | 153 | for macro_call_id in items |
@@ -184,5 +172,5 @@ pub fn macro_symbols( | |||
184 | } | 172 | } |
185 | } | 173 | } |
186 | 174 | ||
187 | Ok(res) | 175 | res |
188 | } | 176 | } |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index fa46ddfe9..85d4dc05c 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -14,7 +14,7 @@ | |||
14 | //! rustc. | 14 | //! rustc. |
15 | 15 | ||
16 | mod autoderef; | 16 | mod autoderef; |
17 | mod primitive; | 17 | pub(crate) mod primitive; |
18 | #[cfg(test)] | 18 | #[cfg(test)] |
19 | mod tests; | 19 | mod tests; |
20 | pub(crate) mod method_resolution; | 20 | pub(crate) mod method_resolution; |
@@ -30,25 +30,15 @@ use ra_arena::map::ArenaMap; | |||
30 | use join_to_string::join; | 30 | use join_to_string::join; |
31 | use rustc_hash::FxHashMap; | 31 | use rustc_hash::FxHashMap; |
32 | 32 | ||
33 | use ra_db::Cancelable; | ||
34 | |||
35 | use crate::{ | 33 | use crate::{ |
36 | Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, | 34 | Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, |
37 | FnSignature, FnScopes, | 35 | FnSignature, FnScopes, |
38 | db::HirDatabase, | 36 | db::HirDatabase, |
39 | type_ref::{TypeRef, Mutability}, | 37 | type_ref::{TypeRef, Mutability}, |
40 | name::KnownName, | 38 | name::KnownName, |
41 | expr::{Body, Expr, ExprId, PatId, UnaryOp, BinaryOp, Statement}, | 39 | expr::{Body, Expr, Literal, ExprId, PatId, UnaryOp, BinaryOp, Statement}, |
42 | }; | 40 | }; |
43 | 41 | ||
44 | fn transpose<T>(x: Cancelable<Option<T>>) -> Option<Cancelable<T>> { | ||
45 | match x { | ||
46 | Ok(Some(t)) => Some(Ok(t)), | ||
47 | Ok(None) => None, | ||
48 | Err(e) => Some(Err(e)), | ||
49 | } | ||
50 | } | ||
51 | |||
52 | /// The ID of a type variable. | 42 | /// The ID of a type variable. |
53 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | 43 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
54 | pub struct TypeVarId(u32); | 44 | pub struct TypeVarId(u32); |
@@ -107,13 +97,35 @@ impl UnifyValue for TypeVarValue { | |||
107 | } | 97 | } |
108 | } | 98 | } |
109 | 99 | ||
110 | /// The kinds of placeholders we need during type inference. Currently, we only | 100 | /// The kinds of placeholders we need during type inference. There's separate |
111 | /// have type variables; in the future, we will probably also need int and float | 101 | /// values for general types, and for integer and float variables. The latter |
112 | /// variables, for inference of literal values (e.g. `100` could be one of | 102 | /// two are used for inference of literal values (e.g. `100` could be one of |
113 | /// several integer types). | 103 | /// several integer types). |
114 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 104 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] |
115 | pub enum InferTy { | 105 | pub enum InferTy { |
116 | TypeVar(TypeVarId), | 106 | TypeVar(TypeVarId), |
107 | IntVar(TypeVarId), | ||
108 | FloatVar(TypeVarId), | ||
109 | } | ||
110 | |||
111 | impl InferTy { | ||
112 | fn to_inner(self) -> TypeVarId { | ||
113 | match self { | ||
114 | InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty, | ||
115 | } | ||
116 | } | ||
117 | |||
118 | fn fallback_value(self) -> Ty { | ||
119 | match self { | ||
120 | InferTy::TypeVar(..) => Ty::Unknown, | ||
121 | InferTy::IntVar(..) => { | ||
122 | Ty::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32)) | ||
123 | } | ||
124 | InferTy::FloatVar(..) => { | ||
125 | Ty::Float(primitive::UncertainFloatTy::Known(primitive::FloatTy::F64)) | ||
126 | } | ||
127 | } | ||
128 | } | ||
117 | } | 129 | } |
118 | 130 | ||
119 | /// When inferring an expression, we propagate downward whatever type hint we | 131 | /// When inferring an expression, we propagate downward whatever type hint we |
@@ -151,14 +163,11 @@ pub enum Ty { | |||
151 | /// (a non-surrogate code point). Written as `char`. | 163 | /// (a non-surrogate code point). Written as `char`. |
152 | Char, | 164 | Char, |
153 | 165 | ||
154 | /// A primitive signed integer type. For example, `i32`. | 166 | /// A primitive integer type. For example, `i32`. |
155 | Int(primitive::IntTy), | 167 | Int(primitive::UncertainIntTy), |
156 | |||
157 | /// A primitive unsigned integer type. For example, `u32`. | ||
158 | Uint(primitive::UintTy), | ||
159 | 168 | ||
160 | /// A primitive floating-point type. For example, `f64`. | 169 | /// A primitive floating-point type. For example, `f64`. |
161 | Float(primitive::FloatTy), | 170 | Float(primitive::UncertainFloatTy), |
162 | 171 | ||
163 | /// Structures, enumerations and unions. | 172 | /// Structures, enumerations and unions. |
164 | Adt { | 173 | Adt { |
@@ -198,8 +207,9 @@ pub enum Ty { | |||
198 | // above function pointer type. Once we implement generics, we will probably | 207 | // above function pointer type. Once we implement generics, we will probably |
199 | // need this as well. | 208 | // need this as well. |
200 | 209 | ||
201 | // A trait, defined with `dyn trait`. | 210 | // A trait, defined with `dyn Trait`. |
202 | // Dynamic(), | 211 | // Dynamic(), |
212 | |||
203 | // The anonymous type of a closure. Used to represent the type of | 213 | // The anonymous type of a closure. Used to represent the type of |
204 | // `|a| a`. | 214 | // `|a| a`. |
205 | // Closure(DefId, ClosureSubsts<'tcx>), | 215 | // Closure(DefId, ClosureSubsts<'tcx>), |
@@ -251,28 +261,28 @@ impl Ty { | |||
251 | module: &Module, | 261 | module: &Module, |
252 | impl_block: Option<&ImplBlock>, | 262 | impl_block: Option<&ImplBlock>, |
253 | type_ref: &TypeRef, | 263 | type_ref: &TypeRef, |
254 | ) -> Cancelable<Self> { | 264 | ) -> Self { |
255 | Ok(match type_ref { | 265 | match type_ref { |
256 | TypeRef::Never => Ty::Never, | 266 | TypeRef::Never => Ty::Never, |
257 | TypeRef::Tuple(inner) => { | 267 | TypeRef::Tuple(inner) => { |
258 | let inner_tys = inner | 268 | let inner_tys = inner |
259 | .iter() | 269 | .iter() |
260 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) | 270 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) |
261 | .collect::<Cancelable<Vec<_>>>()?; | 271 | .collect::<Vec<_>>(); |
262 | Ty::Tuple(inner_tys.into()) | 272 | Ty::Tuple(inner_tys.into()) |
263 | } | 273 | } |
264 | TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path)?, | 274 | TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path), |
265 | TypeRef::RawPtr(inner, mutability) => { | 275 | TypeRef::RawPtr(inner, mutability) => { |
266 | let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; | 276 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); |
267 | Ty::RawPtr(Arc::new(inner_ty), *mutability) | 277 | Ty::RawPtr(Arc::new(inner_ty), *mutability) |
268 | } | 278 | } |
269 | TypeRef::Array(_inner) => Ty::Unknown, // TODO | 279 | TypeRef::Array(_inner) => Ty::Unknown, // TODO |
270 | TypeRef::Slice(inner) => { | 280 | TypeRef::Slice(inner) => { |
271 | let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; | 281 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); |
272 | Ty::Slice(Arc::new(inner_ty)) | 282 | Ty::Slice(Arc::new(inner_ty)) |
273 | } | 283 | } |
274 | TypeRef::Reference(inner, mutability) => { | 284 | TypeRef::Reference(inner, mutability) => { |
275 | let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; | 285 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); |
276 | Ty::Ref(Arc::new(inner_ty), *mutability) | 286 | Ty::Ref(Arc::new(inner_ty), *mutability) |
277 | } | 287 | } |
278 | TypeRef::Placeholder => Ty::Unknown, | 288 | TypeRef::Placeholder => Ty::Unknown, |
@@ -280,7 +290,7 @@ impl Ty { | |||
280 | let mut inner_tys = params | 290 | let mut inner_tys = params |
281 | .iter() | 291 | .iter() |
282 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) | 292 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) |
283 | .collect::<Cancelable<Vec<_>>>()?; | 293 | .collect::<Vec<_>>(); |
284 | let return_ty = inner_tys | 294 | let return_ty = inner_tys |
285 | .pop() | 295 | .pop() |
286 | .expect("TypeRef::Fn should always have at least return type"); | 296 | .expect("TypeRef::Fn should always have at least return type"); |
@@ -291,7 +301,7 @@ impl Ty { | |||
291 | Ty::FnPtr(Arc::new(sig)) | 301 | Ty::FnPtr(Arc::new(sig)) |
292 | } | 302 | } |
293 | TypeRef::Error => Ty::Unknown, | 303 | TypeRef::Error => Ty::Unknown, |
294 | }) | 304 | } |
295 | } | 305 | } |
296 | 306 | ||
297 | pub(crate) fn from_hir_opt( | 307 | pub(crate) fn from_hir_opt( |
@@ -299,10 +309,8 @@ impl Ty { | |||
299 | module: &Module, | 309 | module: &Module, |
300 | impl_block: Option<&ImplBlock>, | 310 | impl_block: Option<&ImplBlock>, |
301 | type_ref: Option<&TypeRef>, | 311 | type_ref: Option<&TypeRef>, |
302 | ) -> Cancelable<Self> { | 312 | ) -> Self { |
303 | type_ref | 313 | type_ref.map_or(Ty::Unknown, |t| Ty::from_hir(db, module, impl_block, t)) |
304 | .map(|t| Ty::from_hir(db, module, impl_block, t)) | ||
305 | .unwrap_or(Ok(Ty::Unknown)) | ||
306 | } | 314 | } |
307 | 315 | ||
308 | pub(crate) fn from_hir_path( | 316 | pub(crate) fn from_hir_path( |
@@ -310,33 +318,31 @@ impl Ty { | |||
310 | module: &Module, | 318 | module: &Module, |
311 | impl_block: Option<&ImplBlock>, | 319 | impl_block: Option<&ImplBlock>, |
312 | path: &Path, | 320 | path: &Path, |
313 | ) -> Cancelable<Self> { | 321 | ) -> Self { |
314 | if let Some(name) = path.as_ident() { | 322 | if let Some(name) = path.as_ident() { |
315 | if let Some(KnownName::Bool) = name.as_known_name() { | 323 | if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { |
316 | return Ok(Ty::Bool); | 324 | return Ty::Int(int_ty); |
317 | } else if let Some(KnownName::Char) = name.as_known_name() { | 325 | } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { |
318 | return Ok(Ty::Char); | 326 | return Ty::Float(float_ty); |
319 | } else if let Some(KnownName::Str) = name.as_known_name() { | ||
320 | return Ok(Ty::Str); | ||
321 | } else if let Some(int_ty) = primitive::IntTy::from_name(name) { | ||
322 | return Ok(Ty::Int(int_ty)); | ||
323 | } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { | ||
324 | return Ok(Ty::Uint(uint_ty)); | ||
325 | } else if let Some(float_ty) = primitive::FloatTy::from_name(name) { | ||
326 | return Ok(Ty::Float(float_ty)); | ||
327 | } else if name.as_known_name() == Some(KnownName::SelfType) { | 327 | } else if name.as_known_name() == Some(KnownName::SelfType) { |
328 | return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); | 328 | return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); |
329 | } else if let Some(known) = name.as_known_name() { | ||
330 | match known { | ||
331 | KnownName::Bool => return Ty::Bool, | ||
332 | KnownName::Char => return Ty::Char, | ||
333 | KnownName::Str => return Ty::Str, | ||
334 | _ => {} | ||
335 | } | ||
329 | } | 336 | } |
330 | } | 337 | } |
331 | 338 | ||
332 | // Resolve in module (in type namespace) | 339 | // Resolve in module (in type namespace) |
333 | let resolved = if let Some(r) = module.resolve_path(db, path)?.take_types() { | 340 | let resolved = if let Some(r) = module.resolve_path(db, path).take_types() { |
334 | r | 341 | r |
335 | } else { | 342 | } else { |
336 | return Ok(Ty::Unknown); | 343 | return Ty::Unknown; |
337 | }; | 344 | }; |
338 | let ty = db.type_for_def(resolved)?; | 345 | db.type_for_def(resolved) |
339 | Ok(ty) | ||
340 | } | 346 | } |
341 | 347 | ||
342 | pub fn unit() -> Self { | 348 | pub fn unit() -> Self { |
@@ -392,7 +398,6 @@ impl fmt::Display for Ty { | |||
392 | Ty::Bool => write!(f, "bool"), | 398 | Ty::Bool => write!(f, "bool"), |
393 | Ty::Char => write!(f, "char"), | 399 | Ty::Char => write!(f, "char"), |
394 | Ty::Int(t) => write!(f, "{}", t.ty_to_string()), | 400 | Ty::Int(t) => write!(f, "{}", t.ty_to_string()), |
395 | Ty::Uint(t) => write!(f, "{}", t.ty_to_string()), | ||
396 | Ty::Float(t) => write!(f, "{}", t.ty_to_string()), | 401 | Ty::Float(t) => write!(f, "{}", t.ty_to_string()), |
397 | Ty::Str => write!(f, "str"), | 402 | Ty::Str => write!(f, "str"), |
398 | Ty::Slice(t) => write!(f, "[{}]", t), | 403 | Ty::Slice(t) => write!(f, "[{}]", t), |
@@ -427,47 +432,47 @@ impl fmt::Display for Ty { | |||
427 | 432 | ||
428 | /// Compute the declared type of a function. This should not need to look at the | 433 | /// Compute the declared type of a function. This should not need to look at the |
429 | /// function body. | 434 | /// function body. |
430 | fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | 435 | fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { |
431 | let signature = f.signature(db); | 436 | let signature = f.signature(db); |
432 | let module = f.module(db)?; | 437 | let module = f.module(db); |
433 | let impl_block = f.impl_block(db)?; | 438 | let impl_block = f.impl_block(db); |
434 | // TODO we ignore type parameters for now | 439 | // TODO we ignore type parameters for now |
435 | let input = signature | 440 | let input = signature |
436 | .params() | 441 | .params() |
437 | .iter() | 442 | .iter() |
438 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) | 443 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) |
439 | .collect::<Cancelable<Vec<_>>>()?; | 444 | .collect::<Vec<_>>(); |
440 | let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type())?; | 445 | let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type()); |
441 | let sig = FnSig { input, output }; | 446 | let sig = FnSig { input, output }; |
442 | Ok(Ty::FnPtr(Arc::new(sig))) | 447 | Ty::FnPtr(Arc::new(sig)) |
443 | } | 448 | } |
444 | 449 | ||
445 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Cancelable<Ty> { | 450 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { |
446 | Ok(Ty::Adt { | 451 | Ty::Adt { |
447 | def_id: s.def_id(), | 452 | def_id: s.def_id(), |
448 | name: s.name(db)?.unwrap_or_else(Name::missing), | 453 | name: s.name(db).unwrap_or_else(Name::missing), |
449 | }) | 454 | } |
450 | } | 455 | } |
451 | 456 | ||
452 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Cancelable<Ty> { | 457 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { |
453 | Ok(Ty::Adt { | 458 | Ty::Adt { |
454 | def_id: s.def_id(), | 459 | def_id: s.def_id(), |
455 | name: s.name(db)?.unwrap_or_else(Name::missing), | 460 | name: s.name(db).unwrap_or_else(Name::missing), |
456 | }) | 461 | } |
457 | } | 462 | } |
458 | 463 | ||
459 | pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> Cancelable<Ty> { | 464 | pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> Ty { |
460 | let enum_parent = ev.parent_enum(db)?; | 465 | let enum_parent = ev.parent_enum(db); |
461 | 466 | ||
462 | type_for_enum(db, enum_parent) | 467 | type_for_enum(db, enum_parent) |
463 | } | 468 | } |
464 | 469 | ||
465 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { | 470 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { |
466 | let def = def_id.resolve(db)?; | 471 | let def = def_id.resolve(db); |
467 | match def { | 472 | match def { |
468 | Def::Module(..) => { | 473 | Def::Module(..) => { |
469 | log::debug!("trying to get type for module {:?}", def_id); | 474 | log::debug!("trying to get type for module {:?}", def_id); |
470 | Ok(Ty::Unknown) | 475 | Ty::Unknown |
471 | } | 476 | } |
472 | Def::Function(f) => type_for_fn(db, f), | 477 | Def::Function(f) => type_for_fn(db, f), |
473 | Def::Struct(s) => type_for_struct(db, s), | 478 | Def::Struct(s) => type_for_struct(db, s), |
@@ -479,35 +484,26 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<T | |||
479 | def_id, | 484 | def_id, |
480 | def | 485 | def |
481 | ); | 486 | ); |
482 | Ok(Ty::Unknown) | 487 | Ty::Unknown |
483 | } | 488 | } |
484 | } | 489 | } |
485 | } | 490 | } |
486 | 491 | ||
487 | pub(super) fn type_for_field( | 492 | pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> { |
488 | db: &impl HirDatabase, | 493 | let def = def_id.resolve(db); |
489 | def_id: DefId, | ||
490 | field: Name, | ||
491 | ) -> Cancelable<Option<Ty>> { | ||
492 | let def = def_id.resolve(db)?; | ||
493 | let variant_data = match def { | 494 | let variant_data = match def { |
494 | Def::Struct(s) => s.variant_data(db)?, | 495 | Def::Struct(s) => s.variant_data(db), |
495 | Def::EnumVariant(ev) => ev.variant_data(db)?, | 496 | Def::EnumVariant(ev) => ev.variant_data(db), |
496 | // TODO: unions | 497 | // TODO: unions |
497 | _ => panic!( | 498 | _ => panic!( |
498 | "trying to get type for field in non-struct/variant {:?}", | 499 | "trying to get type for field in non-struct/variant {:?}", |
499 | def_id | 500 | def_id |
500 | ), | 501 | ), |
501 | }; | 502 | }; |
502 | let module = def_id.module(db)?; | 503 | let module = def_id.module(db); |
503 | let impl_block = def_id.impl_block(db)?; | 504 | let impl_block = def_id.impl_block(db); |
504 | let type_ref = ctry!(variant_data.get_field_type_ref(&field)); | 505 | let type_ref = variant_data.get_field_type_ref(&field)?; |
505 | Ok(Some(Ty::from_hir( | 506 | Some(Ty::from_hir(db, &module, impl_block.as_ref(), &type_ref)) |
506 | db, | ||
507 | &module, | ||
508 | impl_block.as_ref(), | ||
509 | &type_ref, | ||
510 | )?)) | ||
511 | } | 507 | } |
512 | 508 | ||
513 | /// The result of type inference: A mapping from expressions and patterns to types. | 509 | /// The result of type inference: A mapping from expressions and patterns to types. |
@@ -587,7 +583,7 @@ fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { | |||
587 | | BinaryOp::BitwiseAnd | 583 | | BinaryOp::BitwiseAnd |
588 | | BinaryOp::BitwiseOr | 584 | | BinaryOp::BitwiseOr |
589 | | BinaryOp::BitwiseXor => match rhs_ty { | 585 | | BinaryOp::BitwiseXor => match rhs_ty { |
590 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => rhs_ty, | 586 | Ty::Int(..) | Ty::Float(..) => rhs_ty, |
591 | _ => Ty::Unknown, | 587 | _ => Ty::Unknown, |
592 | }, | 588 | }, |
593 | BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, | 589 | BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, |
@@ -598,7 +594,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
598 | match op { | 594 | match op { |
599 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, | 595 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, |
600 | BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { | 596 | BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { |
601 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, | 597 | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, |
602 | _ => Ty::Unknown, | 598 | _ => Ty::Unknown, |
603 | }, | 599 | }, |
604 | BinaryOp::LesserEqualTest | 600 | BinaryOp::LesserEqualTest |
@@ -625,7 +621,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
625 | | BinaryOp::BitwiseAnd | 621 | | BinaryOp::BitwiseAnd |
626 | | BinaryOp::BitwiseOr | 622 | | BinaryOp::BitwiseOr |
627 | | BinaryOp::BitwiseXor => match lhs_ty { | 623 | | BinaryOp::BitwiseXor => match lhs_ty { |
628 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty, | 624 | Ty::Int(..) | Ty::Float(..) => lhs_ty, |
629 | _ => Ty::Unknown, | 625 | _ => Ty::Unknown, |
630 | }, | 626 | }, |
631 | _ => Ty::Unknown, | 627 | _ => Ty::Unknown, |
@@ -684,7 +680,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
684 | self.type_of_pat.insert(pat, ty); | 680 | self.type_of_pat.insert(pat, ty); |
685 | } | 681 | } |
686 | 682 | ||
687 | fn make_ty(&self, type_ref: &TypeRef) -> Cancelable<Ty> { | 683 | fn make_ty(&self, type_ref: &TypeRef) -> Ty { |
688 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref) | 684 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref) |
689 | } | 685 | } |
690 | 686 | ||
@@ -695,13 +691,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
695 | match (&*ty1, &*ty2) { | 691 | match (&*ty1, &*ty2) { |
696 | (Ty::Unknown, ..) => true, | 692 | (Ty::Unknown, ..) => true, |
697 | (.., Ty::Unknown) => true, | 693 | (.., Ty::Unknown) => true, |
698 | (Ty::Bool, _) | 694 | (Ty::Int(t1), Ty::Int(t2)) => match (t1, t2) { |
699 | | (Ty::Str, _) | 695 | (primitive::UncertainIntTy::Unknown, _) |
700 | | (Ty::Never, _) | 696 | | (_, primitive::UncertainIntTy::Unknown) => true, |
701 | | (Ty::Char, _) | 697 | _ => t1 == t2, |
702 | | (Ty::Int(..), Ty::Int(..)) | 698 | }, |
703 | | (Ty::Uint(..), Ty::Uint(..)) | 699 | (Ty::Float(t1), Ty::Float(t2)) => match (t1, t2) { |
704 | | (Ty::Float(..), Ty::Float(..)) => ty1 == ty2, | 700 | (primitive::UncertainFloatTy::Unknown, _) |
701 | | (_, primitive::UncertainFloatTy::Unknown) => true, | ||
702 | _ => t1 == t2, | ||
703 | }, | ||
704 | (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, | ||
705 | ( | 705 | ( |
706 | Ty::Adt { | 706 | Ty::Adt { |
707 | def_id: def_id1, .. | 707 | def_id: def_id1, .. |
@@ -718,12 +718,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
718 | .iter() | 718 | .iter() |
719 | .zip(ts2.iter()) | 719 | .zip(ts2.iter()) |
720 | .all(|(t1, t2)| self.unify(t1, t2)), | 720 | .all(|(t1, t2)| self.unify(t1, t2)), |
721 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) => { | 721 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
722 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | ||
723 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { | ||
722 | // both type vars are unknown since we tried to resolve them | 724 | // both type vars are unknown since we tried to resolve them |
723 | self.var_unification_table.union(*tv1, *tv2); | 725 | self.var_unification_table.union(*tv1, *tv2); |
724 | true | 726 | true |
725 | } | 727 | } |
726 | (Ty::Infer(InferTy::TypeVar(tv)), other) | (other, Ty::Infer(InferTy::TypeVar(tv))) => { | 728 | (Ty::Infer(InferTy::TypeVar(tv)), other) |
729 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | ||
730 | | (Ty::Infer(InferTy::IntVar(tv)), other) | ||
731 | | (other, Ty::Infer(InferTy::IntVar(tv))) | ||
732 | | (Ty::Infer(InferTy::FloatVar(tv)), other) | ||
733 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { | ||
727 | // the type var is unknown since we tried to resolve it | 734 | // the type var is unknown since we tried to resolve it |
728 | self.var_unification_table | 735 | self.var_unification_table |
729 | .union_value(*tv, TypeVarValue::Known(other.clone())); | 736 | .union_value(*tv, TypeVarValue::Known(other.clone())); |
@@ -739,10 +746,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
739 | )) | 746 | )) |
740 | } | 747 | } |
741 | 748 | ||
749 | fn new_integer_var(&mut self) -> Ty { | ||
750 | Ty::Infer(InferTy::IntVar( | ||
751 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
752 | )) | ||
753 | } | ||
754 | |||
755 | fn new_float_var(&mut self) -> Ty { | ||
756 | Ty::Infer(InferTy::FloatVar( | ||
757 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
758 | )) | ||
759 | } | ||
760 | |||
742 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 761 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
743 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 762 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
744 | match ty { | 763 | match ty { |
745 | Ty::Unknown => self.new_type_var(), | 764 | Ty::Unknown => self.new_type_var(), |
765 | Ty::Int(primitive::UncertainIntTy::Unknown) => self.new_integer_var(), | ||
766 | Ty::Float(primitive::UncertainFloatTy::Unknown) => self.new_float_var(), | ||
746 | _ => ty, | 767 | _ => ty, |
747 | } | 768 | } |
748 | } | 769 | } |
@@ -757,12 +778,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
757 | /// known type. | 778 | /// known type. |
758 | fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { | 779 | fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { |
759 | ty.fold(&mut |ty| match ty { | 780 | ty.fold(&mut |ty| match ty { |
760 | Ty::Infer(InferTy::TypeVar(tv)) => { | 781 | Ty::Infer(tv) => { |
761 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | 782 | let inner = tv.to_inner(); |
783 | if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { | ||
762 | // known_ty may contain other variables that are known by now | 784 | // known_ty may contain other variables that are known by now |
763 | self.resolve_ty_as_possible(known_ty.clone()) | 785 | self.resolve_ty_as_possible(known_ty.clone()) |
764 | } else { | 786 | } else { |
765 | Ty::Infer(InferTy::TypeVar(tv)) | 787 | ty |
766 | } | 788 | } |
767 | } | 789 | } |
768 | _ => ty, | 790 | _ => ty, |
@@ -773,8 +795,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
773 | /// otherwise, return ty. | 795 | /// otherwise, return ty. |
774 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { | 796 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { |
775 | match ty { | 797 | match ty { |
776 | Ty::Infer(InferTy::TypeVar(tv)) => { | 798 | Ty::Infer(tv) => { |
777 | match self.var_unification_table.probe_value(*tv).known() { | 799 | let inner = tv.to_inner(); |
800 | match self.var_unification_table.probe_value(inner).known() { | ||
778 | Some(known_ty) => { | 801 | Some(known_ty) => { |
779 | // The known_ty can't be a type var itself | 802 | // The known_ty can't be a type var itself |
780 | Cow::Owned(known_ty.clone()) | 803 | Cow::Owned(known_ty.clone()) |
@@ -790,61 +813,62 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
790 | /// replaced by Ty::Unknown. | 813 | /// replaced by Ty::Unknown. |
791 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | 814 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { |
792 | ty.fold(&mut |ty| match ty { | 815 | ty.fold(&mut |ty| match ty { |
793 | Ty::Infer(InferTy::TypeVar(tv)) => { | 816 | Ty::Infer(tv) => { |
794 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | 817 | let inner = tv.to_inner(); |
818 | if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { | ||
795 | // known_ty may contain other variables that are known by now | 819 | // known_ty may contain other variables that are known by now |
796 | self.resolve_ty_completely(known_ty.clone()) | 820 | self.resolve_ty_completely(known_ty.clone()) |
797 | } else { | 821 | } else { |
798 | Ty::Unknown | 822 | tv.fallback_value() |
799 | } | 823 | } |
800 | } | 824 | } |
801 | _ => ty, | 825 | _ => ty, |
802 | }) | 826 | }) |
803 | } | 827 | } |
804 | 828 | ||
805 | fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Cancelable<Option<Ty>> { | 829 | fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Option<Ty> { |
806 | if path.is_ident() || path.is_self() { | 830 | if path.is_ident() || path.is_self() { |
807 | // resolve locally | 831 | // resolve locally |
808 | let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); | 832 | let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); |
809 | if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { | 833 | if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { |
810 | let ty = ctry!(self.type_of_pat.get(scope_entry.pat())); | 834 | let ty = self.type_of_pat.get(scope_entry.pat())?; |
811 | let ty = self.resolve_ty_as_possible(ty.clone()); | 835 | let ty = self.resolve_ty_as_possible(ty.clone()); |
812 | return Ok(Some(ty)); | 836 | return Some(ty); |
813 | }; | 837 | }; |
814 | }; | 838 | }; |
815 | 839 | ||
816 | // resolve in module | 840 | // resolve in module |
817 | let resolved = ctry!(self.module.resolve_path(self.db, &path)?.take_values()); | 841 | let resolved = self.module.resolve_path(self.db, &path).take_values()?; |
818 | let ty = self.db.type_for_def(resolved)?; | 842 | let ty = self.db.type_for_def(resolved); |
819 | let ty = self.insert_type_vars(ty); | 843 | let ty = self.insert_type_vars(ty); |
820 | Ok(Some(ty)) | 844 | Some(ty) |
821 | } | 845 | } |
822 | 846 | ||
823 | fn resolve_variant(&self, path: Option<&Path>) -> Cancelable<(Ty, Option<DefId>)> { | 847 | fn resolve_variant(&self, path: Option<&Path>) -> (Ty, Option<DefId>) { |
824 | let path = if let Some(path) = path { | 848 | let path = if let Some(path) = path { |
825 | path | 849 | path |
826 | } else { | 850 | } else { |
827 | return Ok((Ty::Unknown, None)); | 851 | return (Ty::Unknown, None); |
828 | }; | 852 | }; |
829 | let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path)?.take_types() { | 853 | let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path).take_types() { |
830 | def_id | 854 | def_id |
831 | } else { | 855 | } else { |
832 | return Ok((Ty::Unknown, None)); | 856 | return (Ty::Unknown, None); |
833 | }; | 857 | }; |
834 | Ok(match def_id.resolve(self.db)? { | 858 | match def_id.resolve(self.db) { |
835 | Def::Struct(s) => { | 859 | Def::Struct(s) => { |
836 | let ty = type_for_struct(self.db, s)?; | 860 | let ty = type_for_struct(self.db, s); |
837 | (ty, Some(def_id)) | 861 | (ty, Some(def_id)) |
838 | } | 862 | } |
839 | Def::EnumVariant(ev) => { | 863 | Def::EnumVariant(ev) => { |
840 | let ty = type_for_enum_variant(self.db, ev)?; | 864 | let ty = type_for_enum_variant(self.db, ev); |
841 | (ty, Some(def_id)) | 865 | (ty, Some(def_id)) |
842 | } | 866 | } |
843 | _ => (Ty::Unknown, None), | 867 | _ => (Ty::Unknown, None), |
844 | }) | 868 | } |
845 | } | 869 | } |
846 | 870 | ||
847 | fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Cancelable<Ty> { | 871 | fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
848 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 872 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
849 | let ty = match &body[expr] { | 873 | let ty = match &body[expr] { |
850 | Expr::Missing => Ty::Unknown, | 874 | Expr::Missing => Ty::Unknown, |
@@ -854,11 +878,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
854 | else_branch, | 878 | else_branch, |
855 | } => { | 879 | } => { |
856 | // if let is desugared to match, so this is always simple if | 880 | // if let is desugared to match, so this is always simple if |
857 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; | 881 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); |
858 | let then_ty = self.infer_expr(*then_branch, expected)?; | 882 | let then_ty = self.infer_expr(*then_branch, expected); |
859 | match else_branch { | 883 | match else_branch { |
860 | Some(else_branch) => { | 884 | Some(else_branch) => { |
861 | self.infer_expr(*else_branch, expected)?; | 885 | self.infer_expr(*else_branch, expected); |
862 | } | 886 | } |
863 | None => { | 887 | None => { |
864 | // no else branch -> unit | 888 | // no else branch -> unit |
@@ -867,31 +891,31 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
867 | }; | 891 | }; |
868 | then_ty | 892 | then_ty |
869 | } | 893 | } |
870 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected)?, | 894 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), |
871 | Expr::Loop { body } => { | 895 | Expr::Loop { body } => { |
872 | self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; | 896 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
873 | // TODO handle break with value | 897 | // TODO handle break with value |
874 | Ty::Never | 898 | Ty::Never |
875 | } | 899 | } |
876 | Expr::While { condition, body } => { | 900 | Expr::While { condition, body } => { |
877 | // while let is desugared to a match loop, so this is always simple while | 901 | // while let is desugared to a match loop, so this is always simple while |
878 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; | 902 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); |
879 | self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; | 903 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
880 | Ty::unit() | 904 | Ty::unit() |
881 | } | 905 | } |
882 | Expr::For { iterable, body, .. } => { | 906 | Expr::For { iterable, body, .. } => { |
883 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 907 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
884 | // TODO write type for pat | 908 | // TODO write type for pat |
885 | self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; | 909 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
886 | Ty::unit() | 910 | Ty::unit() |
887 | } | 911 | } |
888 | Expr::Lambda { body, .. } => { | 912 | Expr::Lambda { body, .. } => { |
889 | // TODO write types for args, infer lambda type etc. | 913 | // TODO write types for args, infer lambda type etc. |
890 | let _body_ty = self.infer_expr(*body, &Expectation::none())?; | 914 | let _body_ty = self.infer_expr(*body, &Expectation::none()); |
891 | Ty::Unknown | 915 | Ty::Unknown |
892 | } | 916 | } |
893 | Expr::Call { callee, args } => { | 917 | Expr::Call { callee, args } => { |
894 | let callee_ty = self.infer_expr(*callee, &Expectation::none())?; | 918 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); |
895 | let (param_tys, ret_ty) = match &callee_ty { | 919 | let (param_tys, ret_ty) = match &callee_ty { |
896 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), | 920 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), |
897 | _ => { | 921 | _ => { |
@@ -904,7 +928,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
904 | self.infer_expr( | 928 | self.infer_expr( |
905 | *arg, | 929 | *arg, |
906 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | 930 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), |
907 | )?; | 931 | ); |
908 | } | 932 | } |
909 | ret_ty | 933 | ret_ty |
910 | } | 934 | } |
@@ -913,12 +937,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
913 | args, | 937 | args, |
914 | method_name, | 938 | method_name, |
915 | } => { | 939 | } => { |
916 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; | 940 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); |
917 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name)?; | 941 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); |
918 | let method_ty = match resolved { | 942 | let method_ty = match resolved { |
919 | Some(def_id) => { | 943 | Some(def_id) => { |
920 | self.write_method_resolution(expr, def_id); | 944 | self.write_method_resolution(expr, def_id); |
921 | self.db.type_for_def(def_id)? | 945 | self.db.type_for_def(def_id) |
922 | } | 946 | } |
923 | None => Ty::Unknown, | 947 | None => Ty::Unknown, |
924 | }; | 948 | }; |
@@ -940,32 +964,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
940 | self.infer_expr( | 964 | self.infer_expr( |
941 | *arg, | 965 | *arg, |
942 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | 966 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), |
943 | )?; | 967 | ); |
944 | } | 968 | } |
945 | ret_ty | 969 | ret_ty |
946 | } | 970 | } |
947 | Expr::Match { expr, arms } => { | 971 | Expr::Match { expr, arms } => { |
948 | let _ty = self.infer_expr(*expr, &Expectation::none())?; | 972 | let _ty = self.infer_expr(*expr, &Expectation::none()); |
949 | for arm in arms { | 973 | for arm in arms { |
950 | // TODO type the bindings in pats | 974 | // TODO type the bindings in pats |
951 | // TODO type the guard | 975 | // TODO type the guard |
952 | let _ty = self.infer_expr(arm.expr, &Expectation::none())?; | 976 | let _ty = self.infer_expr(arm.expr, &Expectation::none()); |
953 | } | 977 | } |
954 | // TODO unify all the match arm types | 978 | // TODO unify all the match arm types |
955 | Ty::Unknown | 979 | Ty::Unknown |
956 | } | 980 | } |
957 | Expr::Path(p) => self.infer_path_expr(expr, p)?.unwrap_or(Ty::Unknown), | 981 | Expr::Path(p) => self.infer_path_expr(expr, p).unwrap_or(Ty::Unknown), |
958 | Expr::Continue => Ty::Never, | 982 | Expr::Continue => Ty::Never, |
959 | Expr::Break { expr } => { | 983 | Expr::Break { expr } => { |
960 | if let Some(expr) = expr { | 984 | if let Some(expr) = expr { |
961 | // TODO handle break with value | 985 | // TODO handle break with value |
962 | self.infer_expr(*expr, &Expectation::none())?; | 986 | self.infer_expr(*expr, &Expectation::none()); |
963 | } | 987 | } |
964 | Ty::Never | 988 | Ty::Never |
965 | } | 989 | } |
966 | Expr::Return { expr } => { | 990 | Expr::Return { expr } => { |
967 | if let Some(expr) = expr { | 991 | if let Some(expr) = expr { |
968 | self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone()))?; | 992 | self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); |
969 | } | 993 | } |
970 | Ty::Never | 994 | Ty::Never |
971 | } | 995 | } |
@@ -974,62 +998,60 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
974 | fields, | 998 | fields, |
975 | spread, | 999 | spread, |
976 | } => { | 1000 | } => { |
977 | let (ty, def_id) = self.resolve_variant(path.as_ref())?; | 1001 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
978 | for field in fields { | 1002 | for field in fields { |
979 | let field_ty = if let Some(def_id) = def_id { | 1003 | let field_ty = if let Some(def_id) = def_id { |
980 | self.db | 1004 | self.db |
981 | .type_for_field(def_id, field.name.clone())? | 1005 | .type_for_field(def_id, field.name.clone()) |
982 | .unwrap_or(Ty::Unknown) | 1006 | .unwrap_or(Ty::Unknown) |
983 | } else { | 1007 | } else { |
984 | Ty::Unknown | 1008 | Ty::Unknown |
985 | }; | 1009 | }; |
986 | self.infer_expr(field.expr, &Expectation::has_type(field_ty))?; | 1010 | self.infer_expr(field.expr, &Expectation::has_type(field_ty)); |
987 | } | 1011 | } |
988 | if let Some(expr) = spread { | 1012 | if let Some(expr) = spread { |
989 | self.infer_expr(*expr, &Expectation::has_type(ty.clone()))?; | 1013 | self.infer_expr(*expr, &Expectation::has_type(ty.clone())); |
990 | } | 1014 | } |
991 | ty | 1015 | ty |
992 | } | 1016 | } |
993 | Expr::Field { expr, name } => { | 1017 | Expr::Field { expr, name } => { |
994 | let receiver_ty = self.infer_expr(*expr, &Expectation::none())?; | 1018 | let receiver_ty = self.infer_expr(*expr, &Expectation::none()); |
995 | let ty = receiver_ty | 1019 | let ty = receiver_ty |
996 | .autoderef(self.db) | 1020 | .autoderef(self.db) |
997 | .find_map(|derefed_ty| match derefed_ty { | 1021 | .find_map(|derefed_ty| match derefed_ty { |
998 | // this is more complicated than necessary because type_for_field is cancelable | 1022 | // this is more complicated than necessary because type_for_field is cancelable |
999 | Ty::Tuple(fields) => { | 1023 | Ty::Tuple(fields) => { |
1000 | let i = name.to_string().parse::<usize>().ok(); | 1024 | let i = name.to_string().parse::<usize>().ok(); |
1001 | i.and_then(|i| fields.get(i).cloned()).map(Ok) | 1025 | i.and_then(|i| fields.get(i).cloned()) |
1002 | } | ||
1003 | Ty::Adt { def_id, .. } => { | ||
1004 | transpose(self.db.type_for_field(def_id, name.clone())) | ||
1005 | } | 1026 | } |
1027 | Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, name.clone()), | ||
1006 | _ => None, | 1028 | _ => None, |
1007 | }) | 1029 | }) |
1008 | .unwrap_or(Ok(Ty::Unknown))?; | 1030 | .unwrap_or(Ty::Unknown); |
1009 | self.insert_type_vars(ty) | 1031 | self.insert_type_vars(ty) |
1010 | } | 1032 | } |
1011 | Expr::Try { expr } => { | 1033 | Expr::Try { expr } => { |
1012 | let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1034 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1013 | Ty::Unknown | 1035 | Ty::Unknown |
1014 | } | 1036 | } |
1015 | Expr::Cast { expr, type_ref } => { | 1037 | Expr::Cast { expr, type_ref } => { |
1016 | let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1038 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1017 | let cast_ty = | 1039 | let cast_ty = |
1018 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref)?; | 1040 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref); |
1019 | let cast_ty = self.insert_type_vars(cast_ty); | 1041 | let cast_ty = self.insert_type_vars(cast_ty); |
1020 | // TODO check the cast... | 1042 | // TODO check the cast... |
1021 | cast_ty | 1043 | cast_ty |
1022 | } | 1044 | } |
1023 | Expr::Ref { expr, mutability } => { | 1045 | Expr::Ref { expr, mutability } => { |
1024 | // TODO pass the expectation down | 1046 | // TODO pass the expectation down |
1025 | let inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1047 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1026 | // TODO reference coercions etc. | 1048 | // TODO reference coercions etc. |
1027 | Ty::Ref(Arc::new(inner_ty), *mutability) | 1049 | Ty::Ref(Arc::new(inner_ty), *mutability) |
1028 | } | 1050 | } |
1029 | Expr::UnaryOp { expr, op } => { | 1051 | Expr::UnaryOp { expr, op } => { |
1030 | let inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1052 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1031 | match op { | 1053 | match op { |
1032 | Some(UnaryOp::Deref) => { | 1054 | UnaryOp::Deref => { |
1033 | if let Some(derefed_ty) = inner_ty.builtin_deref() { | 1055 | if let Some(derefed_ty) = inner_ty.builtin_deref() { |
1034 | derefed_ty | 1056 | derefed_ty |
1035 | } else { | 1057 | } else { |
@@ -1037,7 +1059,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1037 | Ty::Unknown | 1059 | Ty::Unknown |
1038 | } | 1060 | } |
1039 | } | 1061 | } |
1040 | _ => Ty::Unknown, | 1062 | UnaryOp::Neg => { |
1063 | match inner_ty { | ||
1064 | Ty::Int(primitive::UncertainIntTy::Unknown) | ||
1065 | | Ty::Int(primitive::UncertainIntTy::Signed(..)) | ||
1066 | | Ty::Infer(InferTy::IntVar(..)) | ||
1067 | | Ty::Infer(InferTy::FloatVar(..)) | ||
1068 | | Ty::Float(..) => inner_ty, | ||
1069 | // TODO: resolve ops::Neg trait | ||
1070 | _ => Ty::Unknown, | ||
1071 | } | ||
1072 | } | ||
1073 | UnaryOp::Not if inner_ty == Ty::Bool => Ty::Bool, | ||
1074 | // TODO: resolve ops::Not trait for inner_ty | ||
1075 | UnaryOp::Not => Ty::Unknown, | ||
1041 | } | 1076 | } |
1042 | } | 1077 | } |
1043 | Expr::BinaryOp { lhs, rhs, op } => match op { | 1078 | Expr::BinaryOp { lhs, rhs, op } => match op { |
@@ -1048,11 +1083,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1048 | } | 1083 | } |
1049 | _ => Expectation::none(), | 1084 | _ => Expectation::none(), |
1050 | }; | 1085 | }; |
1051 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?; | 1086 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
1052 | // TODO: find implementation of trait corresponding to operation | 1087 | // TODO: find implementation of trait corresponding to operation |
1053 | // symbol and resolve associated `Output` type | 1088 | // symbol and resolve associated `Output` type |
1054 | let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); | 1089 | let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); |
1055 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?; | 1090 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); |
1056 | 1091 | ||
1057 | // TODO: similar as above, return ty is often associated trait type | 1092 | // TODO: similar as above, return ty is often associated trait type |
1058 | binary_op_return_ty(*op, rhs_ty) | 1093 | binary_op_return_ty(*op, rhs_ty) |
@@ -1062,18 +1097,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1062 | Expr::Tuple { exprs } => { | 1097 | Expr::Tuple { exprs } => { |
1063 | let mut ty_vec = Vec::with_capacity(exprs.len()); | 1098 | let mut ty_vec = Vec::with_capacity(exprs.len()); |
1064 | for arg in exprs.iter() { | 1099 | for arg in exprs.iter() { |
1065 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())?); | 1100 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); |
1066 | } | 1101 | } |
1067 | 1102 | ||
1068 | Ty::Tuple(Arc::from(ty_vec)) | 1103 | Ty::Tuple(Arc::from(ty_vec)) |
1069 | } | 1104 | } |
1105 | Expr::Literal(lit) => match lit { | ||
1106 | Literal::Bool(..) => Ty::Bool, | ||
1107 | Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared), | ||
1108 | Literal::ByteString(..) => { | ||
1109 | let byte_type = Arc::new(Ty::Int(primitive::UncertainIntTy::Unsigned( | ||
1110 | primitive::UintTy::U8, | ||
1111 | ))); | ||
1112 | let slice_type = Arc::new(Ty::Slice(byte_type)); | ||
1113 | Ty::Ref(slice_type, Mutability::Shared) | ||
1114 | } | ||
1115 | Literal::Char(..) => Ty::Char, | ||
1116 | Literal::Int(_v, ty) => Ty::Int(*ty), | ||
1117 | Literal::Float(_v, ty) => Ty::Float(*ty), | ||
1118 | }, | ||
1070 | }; | 1119 | }; |
1071 | // use a new type variable if we got Ty::Unknown here | 1120 | // use a new type variable if we got Ty::Unknown here |
1072 | let ty = self.insert_type_vars_shallow(ty); | 1121 | let ty = self.insert_type_vars_shallow(ty); |
1073 | self.unify(&ty, &expected.ty); | 1122 | self.unify(&ty, &expected.ty); |
1074 | let ty = self.resolve_ty_as_possible(ty); | 1123 | let ty = self.resolve_ty_as_possible(ty); |
1075 | self.write_expr_ty(expr, ty.clone()); | 1124 | self.write_expr_ty(expr, ty.clone()); |
1076 | Ok(ty) | 1125 | ty |
1077 | } | 1126 | } |
1078 | 1127 | ||
1079 | fn infer_block( | 1128 | fn infer_block( |
@@ -1081,7 +1130,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1081 | statements: &[Statement], | 1130 | statements: &[Statement], |
1082 | tail: Option<ExprId>, | 1131 | tail: Option<ExprId>, |
1083 | expected: &Expectation, | 1132 | expected: &Expectation, |
1084 | ) -> Cancelable<Ty> { | 1133 | ) -> Ty { |
1085 | for stmt in statements { | 1134 | for stmt in statements { |
1086 | match stmt { | 1135 | match stmt { |
1087 | Statement::Let { | 1136 | Statement::Let { |
@@ -1094,10 +1143,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1094 | &self.module, | 1143 | &self.module, |
1095 | self.impl_block.as_ref(), | 1144 | self.impl_block.as_ref(), |
1096 | type_ref.as_ref(), | 1145 | type_ref.as_ref(), |
1097 | )?; | 1146 | ); |
1098 | let decl_ty = self.insert_type_vars(decl_ty); | 1147 | let decl_ty = self.insert_type_vars(decl_ty); |
1099 | let ty = if let Some(expr) = initializer { | 1148 | let ty = if let Some(expr) = initializer { |
1100 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty))?; | 1149 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); |
1101 | expr_ty | 1150 | expr_ty |
1102 | } else { | 1151 | } else { |
1103 | decl_ty | 1152 | decl_ty |
@@ -1106,55 +1155,53 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1106 | self.write_pat_ty(*pat, ty); | 1155 | self.write_pat_ty(*pat, ty); |
1107 | } | 1156 | } |
1108 | Statement::Expr(expr) => { | 1157 | Statement::Expr(expr) => { |
1109 | self.infer_expr(*expr, &Expectation::none())?; | 1158 | self.infer_expr(*expr, &Expectation::none()); |
1110 | } | 1159 | } |
1111 | } | 1160 | } |
1112 | } | 1161 | } |
1113 | let ty = if let Some(expr) = tail { | 1162 | let ty = if let Some(expr) = tail { |
1114 | self.infer_expr(expr, expected)? | 1163 | self.infer_expr(expr, expected) |
1115 | } else { | 1164 | } else { |
1116 | Ty::unit() | 1165 | Ty::unit() |
1117 | }; | 1166 | }; |
1118 | Ok(ty) | 1167 | ty |
1119 | } | 1168 | } |
1120 | 1169 | ||
1121 | fn collect_fn_signature(&mut self, signature: &FnSignature) -> Cancelable<()> { | 1170 | fn collect_fn_signature(&mut self, signature: &FnSignature) { |
1122 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 1171 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
1123 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { | 1172 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { |
1124 | let ty = self.make_ty(type_ref)?; | 1173 | let ty = self.make_ty(type_ref); |
1125 | let ty = self.insert_type_vars(ty); | 1174 | let ty = self.insert_type_vars(ty); |
1126 | self.write_pat_ty(*pat, ty); | 1175 | self.write_pat_ty(*pat, ty); |
1127 | } | 1176 | } |
1128 | self.return_ty = { | 1177 | self.return_ty = { |
1129 | let ty = self.make_ty(signature.ret_type())?; | 1178 | let ty = self.make_ty(signature.ret_type()); |
1130 | let ty = self.insert_type_vars(ty); | 1179 | let ty = self.insert_type_vars(ty); |
1131 | ty | 1180 | ty |
1132 | }; | 1181 | }; |
1133 | Ok(()) | ||
1134 | } | 1182 | } |
1135 | 1183 | ||
1136 | fn infer_body(&mut self) -> Cancelable<()> { | 1184 | fn infer_body(&mut self) { |
1137 | self.infer_expr( | 1185 | self.infer_expr( |
1138 | self.body.body_expr(), | 1186 | self.body.body_expr(), |
1139 | &Expectation::has_type(self.return_ty.clone()), | 1187 | &Expectation::has_type(self.return_ty.clone()), |
1140 | )?; | 1188 | ); |
1141 | Ok(()) | ||
1142 | } | 1189 | } |
1143 | } | 1190 | } |
1144 | 1191 | ||
1145 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> { | 1192 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc<InferenceResult> { |
1146 | db.check_canceled()?; | 1193 | db.check_canceled(); |
1147 | let function = Function::new(def_id); // TODO: consts also need inference | 1194 | let function = Function::new(def_id); // TODO: consts also need inference |
1148 | let body = function.body(db)?; | 1195 | let body = function.body(db); |
1149 | let scopes = db.fn_scopes(def_id)?; | 1196 | let scopes = db.fn_scopes(def_id); |
1150 | let module = function.module(db)?; | 1197 | let module = function.module(db); |
1151 | let impl_block = function.impl_block(db)?; | 1198 | let impl_block = function.impl_block(db); |
1152 | let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); | 1199 | let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); |
1153 | 1200 | ||
1154 | let signature = function.signature(db); | 1201 | let signature = function.signature(db); |
1155 | ctx.collect_fn_signature(&signature)?; | 1202 | ctx.collect_fn_signature(&signature); |
1156 | 1203 | ||
1157 | ctx.infer_body()?; | 1204 | ctx.infer_body(); |
1158 | 1205 | ||
1159 | Ok(Arc::new(ctx.resolve_all())) | 1206 | Arc::new(ctx.resolve_all()) |
1160 | } | 1207 | } |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 7c3839388..b221bd142 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -6,7 +6,7 @@ use std::sync::Arc; | |||
6 | 6 | ||
7 | use rustc_hash::FxHashMap; | 7 | use rustc_hash::FxHashMap; |
8 | 8 | ||
9 | use ra_db::{Cancelable, SourceRootId}; | 9 | use ra_db::SourceRootId; |
10 | 10 | ||
11 | use crate::{HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, impl_block::{ImplId, ImplBlock, ImplItem}}; | 11 | use crate::{HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, impl_block::{ImplId, ImplBlock, ImplItem}}; |
12 | use super::Ty; | 12 | use super::Ty; |
@@ -42,21 +42,21 @@ impl CrateImplBlocks { | |||
42 | &'a self, | 42 | &'a self, |
43 | db: &'a impl HirDatabase, | 43 | db: &'a impl HirDatabase, |
44 | ty: &Ty, | 44 | ty: &Ty, |
45 | ) -> impl Iterator<Item = Cancelable<ImplBlock>> + 'a { | 45 | ) -> impl Iterator<Item = ImplBlock> + 'a { |
46 | let fingerprint = TyFingerprint::for_impl(ty); | 46 | let fingerprint = TyFingerprint::for_impl(ty); |
47 | fingerprint | 47 | fingerprint |
48 | .and_then(|f| self.impls.get(&f)) | 48 | .and_then(|f| self.impls.get(&f)) |
49 | .into_iter() | 49 | .into_iter() |
50 | .flat_map(|i| i.iter()) | 50 | .flat_map(|i| i.iter()) |
51 | .map(move |(module_id, impl_id)| { | 51 | .map(move |(module_id, impl_id)| { |
52 | let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id)?; | 52 | let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id); |
53 | Ok(ImplBlock::from_id(module_impl_blocks, *impl_id)) | 53 | ImplBlock::from_id(module_impl_blocks, *impl_id) |
54 | }) | 54 | }) |
55 | } | 55 | } |
56 | 56 | ||
57 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { | 57 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { |
58 | let module_id = module.def_id.loc(db).module_id; | 58 | let module_id = module.def_id.loc(db).module_id; |
59 | let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id)?; | 59 | let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id); |
60 | 60 | ||
61 | for (impl_id, impl_data) in module_impl_blocks.impls.iter() { | 61 | for (impl_id, impl_data) in module_impl_blocks.impls.iter() { |
62 | let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); | 62 | let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); |
@@ -65,7 +65,7 @@ impl CrateImplBlocks { | |||
65 | // ignore for now | 65 | // ignore for now |
66 | } else { | 66 | } else { |
67 | let target_ty = | 67 | let target_ty = |
68 | Ty::from_hir(db, &module, Some(&impl_block), impl_data.target_type())?; | 68 | Ty::from_hir(db, &module, Some(&impl_block), impl_data.target_type()); |
69 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | 69 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { |
70 | self.impls | 70 | self.impls |
71 | .entry(target_ty_fp) | 71 | .entry(target_ty_fp) |
@@ -75,17 +75,15 @@ impl CrateImplBlocks { | |||
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
78 | for child in module.children(db)? { | 78 | for child in module.children(db) { |
79 | self.collect_recursive(db, child)?; | 79 | self.collect_recursive(db, child); |
80 | } | 80 | } |
81 | |||
82 | Ok(()) | ||
83 | } | 81 | } |
84 | 82 | ||
85 | pub(crate) fn impls_in_crate_query( | 83 | pub(crate) fn impls_in_crate_query( |
86 | db: &impl HirDatabase, | 84 | db: &impl HirDatabase, |
87 | krate: Crate, | 85 | krate: Crate, |
88 | ) -> Cancelable<Arc<CrateImplBlocks>> { | 86 | ) -> Arc<CrateImplBlocks> { |
89 | let crate_graph = db.crate_graph(); | 87 | let crate_graph = db.crate_graph(); |
90 | let file_id = crate_graph.crate_root(krate.crate_id); | 88 | let file_id = crate_graph.crate_root(krate.crate_id); |
91 | let source_root_id = db.file_source_root(file_id); | 89 | let source_root_id = db.file_source_root(file_id); |
@@ -93,17 +91,17 @@ impl CrateImplBlocks { | |||
93 | source_root_id, | 91 | source_root_id, |
94 | impls: FxHashMap::default(), | 92 | impls: FxHashMap::default(), |
95 | }; | 93 | }; |
96 | if let Some(module) = krate.root_module(db)? { | 94 | if let Some(module) = krate.root_module(db) { |
97 | crate_impl_blocks.collect_recursive(db, module)?; | 95 | crate_impl_blocks.collect_recursive(db, module); |
98 | } | 96 | } |
99 | Ok(Arc::new(crate_impl_blocks)) | 97 | Arc::new(crate_impl_blocks) |
100 | } | 98 | } |
101 | } | 99 | } |
102 | 100 | ||
103 | fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Cancelable<Option<Crate>> { | 101 | fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> { |
104 | match ty { | 102 | match ty { |
105 | Ty::Adt { def_id, .. } => def_id.krate(db), | 103 | Ty::Adt { def_id, .. } => def_id.krate(db), |
106 | _ => Ok(None), | 104 | _ => None, |
107 | } | 105 | } |
108 | } | 106 | } |
109 | 107 | ||
@@ -111,13 +109,13 @@ impl Ty { | |||
111 | // TODO: cache this as a query? | 109 | // TODO: cache this as a query? |
112 | // - if so, what signature? (TyFingerprint, Name)? | 110 | // - if so, what signature? (TyFingerprint, Name)? |
113 | // - or maybe cache all names and def_ids of methods per fingerprint? | 111 | // - or maybe cache all names and def_ids of methods per fingerprint? |
114 | pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<DefId>> { | 112 | pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<DefId> { |
115 | self.iterate_methods(db, |f| { | 113 | self.iterate_methods(db, |f| { |
116 | let sig = f.signature(db); | 114 | let sig = f.signature(db); |
117 | if sig.name() == name && sig.has_self_param() { | 115 | if sig.name() == name && sig.has_self_param() { |
118 | Ok(Some(f.def_id())) | 116 | Some(f.def_id()) |
119 | } else { | 117 | } else { |
120 | Ok(None) | 118 | None |
121 | } | 119 | } |
122 | }) | 120 | }) |
123 | } | 121 | } |
@@ -127,8 +125,8 @@ impl Ty { | |||
127 | pub fn iterate_methods<T>( | 125 | pub fn iterate_methods<T>( |
128 | self, | 126 | self, |
129 | db: &impl HirDatabase, | 127 | db: &impl HirDatabase, |
130 | mut callback: impl FnMut(Function) -> Cancelable<Option<T>>, | 128 | mut callback: impl FnMut(Function) -> Option<T>, |
131 | ) -> Cancelable<Option<T>> { | 129 | ) -> Option<T> { |
132 | // For method calls, rust first does any number of autoderef, and then one | 130 | // For method calls, rust first does any number of autoderef, and then one |
133 | // autoref (i.e. when the method takes &self or &mut self). We just ignore | 131 | // autoref (i.e. when the method takes &self or &mut self). We just ignore |
134 | // the autoref currently -- when we find a method matching the given name, | 132 | // the autoref currently -- when we find a method matching the given name, |
@@ -139,19 +137,18 @@ impl Ty { | |||
139 | // rustc does an autoderef and then autoref again). | 137 | // rustc does an autoderef and then autoref again). |
140 | 138 | ||
141 | for derefed_ty in self.autoderef(db) { | 139 | for derefed_ty in self.autoderef(db) { |
142 | let krate = match def_crate(db, &derefed_ty)? { | 140 | let krate = match def_crate(db, &derefed_ty) { |
143 | Some(krate) => krate, | 141 | Some(krate) => krate, |
144 | None => continue, | 142 | None => continue, |
145 | }; | 143 | }; |
146 | let impls = db.impls_in_crate(krate)?; | 144 | let impls = db.impls_in_crate(krate); |
147 | 145 | ||
148 | for impl_block in impls.lookup_impl_blocks(db, &derefed_ty) { | 146 | for impl_block in impls.lookup_impl_blocks(db, &derefed_ty) { |
149 | let impl_block = impl_block?; | ||
150 | for item in impl_block.items() { | 147 | for item in impl_block.items() { |
151 | match item { | 148 | match item { |
152 | ImplItem::Method(f) => { | 149 | ImplItem::Method(f) => { |
153 | if let Some(result) = callback(f.clone())? { | 150 | if let Some(result) = callback(f.clone()) { |
154 | return Ok(Some(result)); | 151 | return Some(result); |
155 | } | 152 | } |
156 | } | 153 | } |
157 | _ => {} | 154 | _ => {} |
@@ -159,6 +156,6 @@ impl Ty { | |||
159 | } | 156 | } |
160 | } | 157 | } |
161 | } | 158 | } |
162 | Ok(None) | 159 | None |
163 | } | 160 | } |
164 | } | 161 | } |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 498d42d52..5741ca90d 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -2,6 +2,56 @@ use std::fmt; | |||
2 | 2 | ||
3 | use crate::{Name, KnownName}; | 3 | use crate::{Name, KnownName}; |
4 | 4 | ||
5 | #[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] | ||
6 | pub enum UncertainIntTy { | ||
7 | Unknown, | ||
8 | Unsigned(UintTy), | ||
9 | Signed(IntTy), | ||
10 | } | ||
11 | |||
12 | impl UncertainIntTy { | ||
13 | pub fn ty_to_string(&self) -> &'static str { | ||
14 | match *self { | ||
15 | UncertainIntTy::Unknown => "{integer}", | ||
16 | UncertainIntTy::Signed(ty) => ty.ty_to_string(), | ||
17 | UncertainIntTy::Unsigned(ty) => ty.ty_to_string(), | ||
18 | } | ||
19 | } | ||
20 | |||
21 | pub fn from_name(name: &Name) -> Option<UncertainIntTy> { | ||
22 | if let Some(ty) = IntTy::from_name(name) { | ||
23 | Some(UncertainIntTy::Signed(ty)) | ||
24 | } else if let Some(ty) = UintTy::from_name(name) { | ||
25 | Some(UncertainIntTy::Unsigned(ty)) | ||
26 | } else { | ||
27 | None | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | |||
32 | #[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] | ||
33 | pub enum UncertainFloatTy { | ||
34 | Unknown, | ||
35 | Known(FloatTy), | ||
36 | } | ||
37 | |||
38 | impl UncertainFloatTy { | ||
39 | pub fn ty_to_string(&self) -> &'static str { | ||
40 | match *self { | ||
41 | UncertainFloatTy::Unknown => "{float}", | ||
42 | UncertainFloatTy::Known(ty) => ty.ty_to_string(), | ||
43 | } | ||
44 | } | ||
45 | |||
46 | pub fn from_name(name: &Name) -> Option<UncertainFloatTy> { | ||
47 | if let Some(ty) = FloatTy::from_name(name) { | ||
48 | Some(UncertainFloatTy::Known(ty)) | ||
49 | } else { | ||
50 | None | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | |||
5 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] | 55 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] |
6 | pub enum IntTy { | 56 | pub enum IntTy { |
7 | Isize, | 57 | Isize, |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 920188fc9..5d7bc25cc 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -133,6 +133,55 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { | |||
133 | } | 133 | } |
134 | 134 | ||
135 | #[test] | 135 | #[test] |
136 | fn infer_literals() { | ||
137 | check_inference( | ||
138 | r##" | ||
139 | fn test() { | ||
140 | 5i32; | ||
141 | "hello"; | ||
142 | b"bytes"; | ||
143 | 'c'; | ||
144 | b'b'; | ||
145 | 3.14; | ||
146 | 5000; | ||
147 | false; | ||
148 | true; | ||
149 | r#" | ||
150 | //! doc | ||
151 | // non-doc | ||
152 | mod foo {} | ||
153 | "#; | ||
154 | br#"yolo"#; | ||
155 | } | ||
156 | "##, | ||
157 | "literals.txt", | ||
158 | ); | ||
159 | } | ||
160 | |||
161 | #[test] | ||
162 | fn infer_unary_op() { | ||
163 | check_inference( | ||
164 | r#" | ||
165 | enum SomeType {} | ||
166 | |||
167 | fn test(x: SomeType) { | ||
168 | let b = false; | ||
169 | let c = !b; | ||
170 | let a = 100; | ||
171 | let d: i128 = -a; | ||
172 | let e = -100; | ||
173 | let f = !!!true; | ||
174 | -3.14; | ||
175 | -x; | ||
176 | !x; | ||
177 | -"hello"; | ||
178 | } | ||
179 | "#, | ||
180 | "unary_op.txt", | ||
181 | ); | ||
182 | } | ||
183 | |||
184 | #[test] | ||
136 | fn infer_backwards() { | 185 | fn infer_backwards() { |
137 | check_inference( | 186 | check_inference( |
138 | r#" | 187 | r#" |
@@ -180,7 +229,7 @@ fn f(x: bool) -> i32 { | |||
180 | 0i32 | 229 | 0i32 |
181 | } | 230 | } |
182 | 231 | ||
183 | fn test() { | 232 | fn test() -> bool { |
184 | let x = a && b; | 233 | let x = a && b; |
185 | let y = true || false; | 234 | let y = true || false; |
186 | let z = x == y; | 235 | let z = x == y; |
@@ -277,8 +326,6 @@ fn test(x: &str, y: isize) { | |||
277 | let b = (a, x); | 326 | let b = (a, x); |
278 | let c = (y, x); | 327 | let c = (y, x); |
279 | let d = (c, x); | 328 | let d = (c, x); |
280 | |||
281 | // we have not infered these case yet. | ||
282 | let e = (1, "e"); | 329 | let e = (1, "e"); |
283 | let f = (e, "d"); | 330 | let f = (e, "d"); |
284 | } | 331 | } |
@@ -296,11 +343,9 @@ fn infer(content: &str) -> String { | |||
296 | .descendants() | 343 | .descendants() |
297 | .filter_map(ast::FnDef::cast) | 344 | .filter_map(ast::FnDef::cast) |
298 | { | 345 | { |
299 | let func = source_binder::function_from_source(&db, file_id, fn_def) | 346 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); |
300 | .unwrap() | 347 | let inference_result = func.infer(&db); |
301 | .unwrap(); | 348 | let body_syntax_mapping = func.body_syntax_mapping(&db); |
302 | let inference_result = func.infer(&db).unwrap(); | ||
303 | let body_syntax_mapping = func.body_syntax_mapping(&db).unwrap(); | ||
304 | let mut types = Vec::new(); | 349 | let mut types = Vec::new(); |
305 | for (pat, ty) in inference_result.type_of_pat.iter() { | 350 | for (pat, ty) in inference_result.type_of_pat.iter() { |
306 | let syntax_ptr = match body_syntax_mapping.pat_syntax(pat) { | 351 | let syntax_ptr = match body_syntax_mapping.pat_syntax(pat) { |
@@ -380,12 +425,10 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
380 | } | 425 | } |
381 | ", | 426 | ", |
382 | ); | 427 | ); |
383 | let func = source_binder::function_from_position(&db, pos) | 428 | let func = source_binder::function_from_position(&db, pos).unwrap(); |
384 | .unwrap() | ||
385 | .unwrap(); | ||
386 | { | 429 | { |
387 | let events = db.log_executed(|| { | 430 | let events = db.log_executed(|| { |
388 | func.infer(&db).unwrap(); | 431 | func.infer(&db); |
389 | }); | 432 | }); |
390 | assert!(format!("{:?}", events).contains("infer")) | 433 | assert!(format!("{:?}", events).contains("infer")) |
391 | } | 434 | } |
@@ -404,7 +447,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
404 | 447 | ||
405 | { | 448 | { |
406 | let events = db.log_executed(|| { | 449 | let events = db.log_executed(|| { |
407 | func.infer(&db).unwrap(); | 450 | func.infer(&db); |
408 | }); | 451 | }); |
409 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) | 452 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) |
410 | } | 453 | } |
diff --git a/crates/ra_hir/src/ty/tests/data/basics.txt b/crates/ra_hir/src/ty/tests/data/basics.txt index ac7faae0a..e65fe07aa 100644 --- a/crates/ra_hir/src/ty/tests/data/basics.txt +++ b/crates/ra_hir/src/ty/tests/data/basics.txt | |||
@@ -7,7 +7,7 @@ | |||
7 | [55; 56) 'b': isize | 7 | [55; 56) 'b': isize |
8 | [62; 63) 'c': ! | 8 | [62; 63) 'c': ! |
9 | [69; 70) 'd': &str | 9 | [69; 70) 'd': &str |
10 | [76; 82) '1usize': [unknown] | 10 | [76; 82) '1usize': usize |
11 | [88; 94) '1isize': [unknown] | 11 | [88; 94) '1isize': isize |
12 | [100; 106) '"test"': [unknown] | 12 | [100; 106) '"test"': &str |
13 | [112; 118) '1.0f32': [unknown] | 13 | [112; 118) '1.0f32': f32 |
diff --git a/crates/ra_hir/src/ty/tests/data/binary_op.txt b/crates/ra_hir/src/ty/tests/data/binary_op.txt index 8a515ac5e..58a727691 100644 --- a/crates/ra_hir/src/ty/tests/data/binary_op.txt +++ b/crates/ra_hir/src/ty/tests/data/binary_op.txt | |||
@@ -1,46 +1,46 @@ | |||
1 | [6; 7) 'x': bool | 1 | [6; 7) 'x': bool |
2 | [22; 34) '{ 0i32 }': i32 | 2 | [22; 34) '{ 0i32 }': i32 |
3 | [28; 32) '0i32': i32 | 3 | [28; 32) '0i32': i32 |
4 | [46; 342) '{ ... < 3 }': bool | 4 | [54; 350) '{ ... < 3 }': bool |
5 | [56; 57) 'x': bool | 5 | [64; 65) 'x': bool |
6 | [60; 61) 'a': bool | 6 | [68; 69) 'a': bool |
7 | [60; 66) 'a && b': bool | 7 | [68; 74) 'a && b': bool |
8 | [65; 66) 'b': bool | 8 | [73; 74) 'b': bool |
9 | [76; 77) 'y': bool | 9 | [84; 85) 'y': bool |
10 | [80; 84) 'true': bool | 10 | [88; 92) 'true': bool |
11 | [80; 93) 'true || false': bool | 11 | [88; 101) 'true || false': bool |
12 | [88; 93) 'false': bool | 12 | [96; 101) 'false': bool |
13 | [103; 104) 'z': bool | 13 | [111; 112) 'z': bool |
14 | [107; 108) 'x': bool | 14 | [115; 116) 'x': bool |
15 | [107; 113) 'x == y': bool | 15 | [115; 121) 'x == y': bool |
16 | [112; 113) 'y': bool | 16 | [120; 121) 'y': bool |
17 | [123; 134) 'minus_forty': isize | 17 | [131; 142) 'minus_forty': isize |
18 | [144; 152) '-40isize': isize | 18 | [152; 160) '-40isize': isize |
19 | [145; 152) '40isize': [unknown] | 19 | [153; 160) '40isize': isize |
20 | [162; 163) 'h': bool | 20 | [170; 171) 'h': bool |
21 | [166; 177) 'minus_forty': isize | 21 | [174; 185) 'minus_forty': isize |
22 | [166; 188) 'minus_...ONST_2': bool | 22 | [174; 196) 'minus_...ONST_2': bool |
23 | [181; 188) 'CONST_2': isize | 23 | [189; 196) 'CONST_2': isize |
24 | [198; 199) 'c': i32 | 24 | [206; 207) 'c': i32 |
25 | [202; 203) 'f': fn(bool) -> i32 | 25 | [210; 211) 'f': fn(bool) -> i32 |
26 | [202; 211) 'f(z || y)': i32 | 26 | [210; 219) 'f(z || y)': i32 |
27 | [202; 215) 'f(z || y) + 5': i32 | 27 | [210; 223) 'f(z || y) + 5': i32 |
28 | [204; 205) 'z': bool | 28 | [212; 213) 'z': bool |
29 | [204; 210) 'z || y': bool | 29 | [212; 218) 'z || y': bool |
30 | [209; 210) 'y': bool | 30 | [217; 218) 'y': bool |
31 | [214; 215) '5': i32 | 31 | [222; 223) '5': i32 |
32 | [225; 226) 'd': [unknown] | 32 | [233; 234) 'd': [unknown] |
33 | [229; 230) 'b': [unknown] | 33 | [237; 238) 'b': [unknown] |
34 | [240; 241) 'g': () | 34 | [248; 249) 'g': () |
35 | [244; 255) 'minus_forty': isize | 35 | [252; 263) 'minus_forty': isize |
36 | [244; 260) 'minus_...y ^= i': () | 36 | [252; 268) 'minus_...y ^= i': () |
37 | [259; 260) 'i': isize | 37 | [267; 268) 'i': isize |
38 | [270; 273) 'ten': usize | 38 | [278; 281) 'ten': usize |
39 | [283; 285) '10': usize | 39 | [291; 293) '10': usize |
40 | [295; 308) 'ten_is_eleven': bool | 40 | [303; 316) 'ten_is_eleven': bool |
41 | [311; 314) 'ten': usize | 41 | [319; 322) 'ten': usize |
42 | [311; 326) 'ten == some_num': bool | 42 | [319; 334) 'ten == some_num': bool |
43 | [318; 326) 'some_num': usize | 43 | [326; 334) 'some_num': usize |
44 | [333; 336) 'ten': usize | 44 | [341; 344) 'ten': usize |
45 | [333; 340) 'ten < 3': bool | 45 | [341; 348) 'ten < 3': bool |
46 | [339; 340) '3': usize | 46 | [347; 348) '3': usize |
diff --git a/crates/ra_hir/src/ty/tests/data/let.txt b/crates/ra_hir/src/ty/tests/data/let.txt index 30f4a2cf5..8815dba41 100644 --- a/crates/ra_hir/src/ty/tests/data/let.txt +++ b/crates/ra_hir/src/ty/tests/data/let.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | [11; 71) '{ ...= b; }': () | 1 | [11; 71) '{ ...= b; }': () |
2 | [21; 22) 'a': [unknown] | 2 | [21; 22) 'a': isize |
3 | [25; 31) '1isize': [unknown] | 3 | [25; 31) '1isize': isize |
4 | [41; 42) 'b': usize | 4 | [41; 42) 'b': usize |
5 | [52; 53) '1': usize | 5 | [52; 53) '1': usize |
6 | [63; 64) 'c': usize | 6 | [63; 64) 'c': usize |
diff --git a/crates/ra_hir/src/ty/tests/data/literals.txt b/crates/ra_hir/src/ty/tests/data/literals.txt new file mode 100644 index 000000000..84ee2c11b --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/literals.txt | |||
@@ -0,0 +1,12 @@ | |||
1 | [11; 201) '{ ...o"#; }': () | ||
2 | [17; 21) '5i32': i32 | ||
3 | [27; 34) '"hello"': &str | ||
4 | [40; 48) 'b"bytes"': &[u8] | ||
5 | [54; 57) ''c'': char | ||
6 | [63; 67) 'b'b'': u8 | ||
7 | [73; 77) '3.14': f64 | ||
8 | [83; 87) '5000': i32 | ||
9 | [93; 98) 'false': bool | ||
10 | [104; 108) 'true': bool | ||
11 | [114; 182) 'r#" ... "#': &str | ||
12 | [188; 198) 'br#"yolo"#': &[u8] | ||
diff --git a/crates/ra_hir/src/ty/tests/data/struct.txt b/crates/ra_hir/src/ty/tests/data/struct.txt index 7b324c82f..be9e12d02 100644 --- a/crates/ra_hir/src/ty/tests/data/struct.txt +++ b/crates/ra_hir/src/ty/tests/data/struct.txt | |||
@@ -2,14 +2,14 @@ | |||
2 | [82; 83) 'c': [unknown] | 2 | [82; 83) 'c': [unknown] |
3 | [86; 87) 'C': [unknown] | 3 | [86; 87) 'C': [unknown] |
4 | [86; 90) 'C(1)': [unknown] | 4 | [86; 90) 'C(1)': [unknown] |
5 | [88; 89) '1': [unknown] | 5 | [88; 89) '1': i32 |
6 | [96; 97) 'B': [unknown] | 6 | [96; 97) 'B': [unknown] |
7 | [107; 108) 'a': A | 7 | [107; 108) 'a': A |
8 | [114; 133) 'A { b:...C(1) }': A | 8 | [114; 133) 'A { b:...C(1) }': A |
9 | [121; 122) 'B': B | 9 | [121; 122) 'B': B |
10 | [127; 128) 'C': [unknown] | 10 | [127; 128) 'C': [unknown] |
11 | [127; 131) 'C(1)': C | 11 | [127; 131) 'C(1)': C |
12 | [129; 130) '1': [unknown] | 12 | [129; 130) '1': i32 |
13 | [139; 140) 'a': A | 13 | [139; 140) 'a': A |
14 | [139; 142) 'a.b': B | 14 | [139; 142) 'a.b': B |
15 | [148; 149) 'a': A | 15 | [148; 149) 'a': A |
diff --git a/crates/ra_hir/src/ty/tests/data/tuple.txt b/crates/ra_hir/src/ty/tests/data/tuple.txt index 96169180d..a95d3c286 100644 --- a/crates/ra_hir/src/ty/tests/data/tuple.txt +++ b/crates/ra_hir/src/ty/tests/data/tuple.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | [9; 10) 'x': &str | 1 | [9; 10) 'x': &str |
2 | [18; 19) 'y': isize | 2 | [18; 19) 'y': isize |
3 | [28; 214) '{ ...d"); }': () | 3 | [28; 170) '{ ...d"); }': () |
4 | [38; 39) 'a': (u32, &str) | 4 | [38; 39) 'a': (u32, &str) |
5 | [55; 63) '(1, "a")': (u32, &str) | 5 | [55; 63) '(1, "a")': (u32, &str) |
6 | [56; 57) '1': u32 | 6 | [56; 57) '1': u32 |
@@ -17,11 +17,11 @@ | |||
17 | [117; 123) '(c, x)': ((isize, &str), &str) | 17 | [117; 123) '(c, x)': ((isize, &str), &str) |
18 | [118; 119) 'c': (isize, &str) | 18 | [118; 119) 'c': (isize, &str) |
19 | [121; 122) 'x': &str | 19 | [121; 122) 'x': &str |
20 | [177; 178) 'e': ([unknown], [unknown]) | 20 | [133; 134) 'e': (i32, &str) |
21 | [181; 189) '(1, "e")': ([unknown], [unknown]) | 21 | [137; 145) '(1, "e")': (i32, &str) |
22 | [182; 183) '1': [unknown] | 22 | [138; 139) '1': i32 |
23 | [185; 188) '"e"': [unknown] | 23 | [141; 144) '"e"': &str |
24 | [199; 200) 'f': (([unknown], [unknown]), [unknown]) | 24 | [155; 156) 'f': ((i32, &str), &str) |
25 | [203; 211) '(e, "d")': (([unknown], [unknown]), [unknown]) | 25 | [159; 167) '(e, "d")': ((i32, &str), &str) |
26 | [204; 205) 'e': ([unknown], [unknown]) | 26 | [160; 161) 'e': (i32, &str) |
27 | [207; 210) '"d"': [unknown] | 27 | [163; 166) '"d"': &str |
diff --git a/crates/ra_hir/src/ty/tests/data/unary_op.txt b/crates/ra_hir/src/ty/tests/data/unary_op.txt new file mode 100644 index 000000000..203022e82 --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/unary_op.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | [27; 28) 'x': SomeType | ||
2 | [40; 197) '{ ...lo"; }': () | ||
3 | [50; 51) 'b': bool | ||
4 | [54; 59) 'false': bool | ||
5 | [69; 70) 'c': bool | ||
6 | [73; 75) '!b': bool | ||
7 | [74; 75) 'b': bool | ||
8 | [85; 86) 'a': i128 | ||
9 | [89; 92) '100': i128 | ||
10 | [102; 103) 'd': i128 | ||
11 | [112; 114) '-a': i128 | ||
12 | [113; 114) 'a': i128 | ||
13 | [124; 125) 'e': i32 | ||
14 | [128; 132) '-100': i32 | ||
15 | [129; 132) '100': i32 | ||
16 | [142; 143) 'f': bool | ||
17 | [146; 153) '!!!true': bool | ||
18 | [147; 153) '!!true': bool | ||
19 | [148; 153) '!true': bool | ||
20 | [149; 153) 'true': bool | ||
21 | [159; 164) '-3.14': f64 | ||
22 | [160; 164) '3.14': f64 | ||
23 | [170; 172) '-x': [unknown] | ||
24 | [171; 172) 'x': SomeType | ||
25 | [178; 180) '!x': [unknown] | ||
26 | [179; 180) 'x': SomeType | ||
27 | [186; 194) '-"hello"': [unknown] | ||
28 | [187; 194) '"hello"': &str | ||