diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 25 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 92 | ||||
-rw-r--r-- | crates/ra_hir/src/function.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/function/scope.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 27 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir/src/macros.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir/src/module_tree.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 34 | ||||
-rw-r--r-- | crates/ra_hir/src/path.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/query_definitions.rs | 32 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 95 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/basics.txt | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/binary_op.txt | 46 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/boolean_op.txt | 31 | ||||
-rw-r--r-- | crates/ra_hir/src/type_ref.rs | 8 |
22 files changed, 353 insertions, 261 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index c6463235c..b75adda84 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -42,7 +42,7 @@ pub struct StructData { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | impl StructData { | 44 | impl StructData { |
45 | pub(crate) fn new(struct_def: ast::StructDef) -> StructData { | 45 | pub(crate) fn new(struct_def: &ast::StructDef) -> StructData { |
46 | let name = struct_def.name().map(|n| n.as_name()); | 46 | let name = struct_def.name().map(|n| n.as_name()); |
47 | let variant_data = VariantData::new(struct_def.flavor()); | 47 | let variant_data = VariantData::new(struct_def.flavor()); |
48 | let variant_data = Arc::new(variant_data); | 48 | let variant_data = Arc::new(variant_data); |
@@ -87,7 +87,7 @@ pub struct EnumData { | |||
87 | } | 87 | } |
88 | 88 | ||
89 | impl EnumData { | 89 | impl EnumData { |
90 | pub(crate) fn new(enum_def: ast::EnumDef) -> Self { | 90 | pub(crate) fn new(enum_def: &ast::EnumDef) -> Self { |
91 | let name = enum_def.name().map(|n| n.as_name()); | 91 | let name = enum_def.name().map(|n| n.as_name()); |
92 | let variants = if let Some(evl) = enum_def.variant_list() { | 92 | let variants = if let Some(evl) = enum_def.variant_list() { |
93 | evl.variants() | 93 | evl.variants() |
@@ -171,24 +171,21 @@ impl VariantData { | |||
171 | } | 171 | } |
172 | } | 172 | } |
173 | pub fn is_struct(&self) -> bool { | 173 | pub fn is_struct(&self) -> bool { |
174 | if let VariantData::Struct(..) = *self { | 174 | match self { |
175 | true | 175 | VariantData::Struct(..) => true, |
176 | } else { | 176 | _ => false, |
177 | false | ||
178 | } | 177 | } |
179 | } | 178 | } |
180 | pub fn is_tuple(&self) -> bool { | 179 | pub fn is_tuple(&self) -> bool { |
181 | if let VariantData::Tuple(..) = *self { | 180 | match self { |
182 | true | 181 | VariantData::Tuple(..) => true, |
183 | } else { | 182 | _ => false, |
184 | false | ||
185 | } | 183 | } |
186 | } | 184 | } |
187 | pub fn is_unit(&self) -> bool { | 185 | pub fn is_unit(&self) -> bool { |
188 | if let VariantData::Unit = *self { | 186 | match self { |
189 | true | 187 | VariantData::Unit => true, |
190 | } else { | 188 | _ => false, |
191 | false | ||
192 | } | 189 | } |
193 | } | 190 | } |
194 | } | 191 | } |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 09b532f74..43cddb504 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use relative_path::RelativePathBuf; | 1 | use relative_path::RelativePathBuf; |
2 | use ra_db::{CrateId, Cancelable, FileId}; | 2 | use ra_db::{CrateId, Cancelable, FileId}; |
3 | use ra_syntax::{ast, SyntaxNode}; | 3 | use ra_syntax::{ast, TreePtr, SyntaxNode}; |
4 | 4 | ||
5 | use crate::{Name, db::HirDatabase, DefId, Path, PerNs, nameres::ModuleScope}; | 5 | use crate::{Name, db::HirDatabase, DefId, Path, PerNs, nameres::ModuleScope}; |
6 | 6 | ||
@@ -36,8 +36,8 @@ pub struct Module { | |||
36 | } | 36 | } |
37 | 37 | ||
38 | pub enum ModuleSource { | 38 | pub enum ModuleSource { |
39 | SourceFile(ast::SourceFileNode), | 39 | SourceFile(TreePtr<ast::SourceFile>), |
40 | Module(ast::ModuleNode), | 40 | Module(TreePtr<ast::Module>), |
41 | } | 41 | } |
42 | 42 | ||
43 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] | 43 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] |
@@ -66,7 +66,7 @@ impl Module { | |||
66 | pub fn declaration_source( | 66 | pub fn declaration_source( |
67 | &self, | 67 | &self, |
68 | db: &impl HirDatabase, | 68 | db: &impl HirDatabase, |
69 | ) -> Cancelable<Option<(FileId, ast::ModuleNode)>> { | 69 | ) -> Cancelable<Option<(FileId, TreePtr<ast::Module>)>> { |
70 | self.declaration_source_impl(db) | 70 | self.declaration_source_impl(db) |
71 | } | 71 | } |
72 | 72 | ||
@@ -104,7 +104,10 @@ impl Module { | |||
104 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { | 104 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { |
105 | self.resolve_path_impl(db, path) | 105 | self.resolve_path_impl(db, path) |
106 | } | 106 | } |
107 | pub fn problems(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> { | 107 | pub fn problems( |
108 | &self, | ||
109 | db: &impl HirDatabase, | ||
110 | ) -> Cancelable<Vec<(TreePtr<SyntaxNode>, Problem)>> { | ||
108 | self.problems_impl(db) | 111 | self.problems_impl(db) |
109 | } | 112 | } |
110 | } | 113 | } |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index eb35779f1..0d22c9dbe 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use ra_db::{Cancelable, SourceRootId, FileId}; | 1 | use ra_db::{Cancelable, SourceRootId, FileId}; |
2 | use ra_syntax::{ast, SyntaxNode, AstNode}; | 2 | use ra_syntax::{ast, SyntaxNode, AstNode, TreePtr}; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Problem, | 5 | Module, ModuleSource, Problem, |
@@ -43,12 +43,11 @@ impl Module { | |||
43 | let loc = self.def_id.loc(db); | 43 | let loc = self.def_id.loc(db); |
44 | let file_id = loc.source_item_id.file_id.as_original_file(); | 44 | let file_id = loc.source_item_id.file_id.as_original_file(); |
45 | let syntax_node = db.file_item(loc.source_item_id); | 45 | let syntax_node = db.file_item(loc.source_item_id); |
46 | let syntax_node = syntax_node.borrowed(); | 46 | let module_source = if let Some(source_file) = ast::SourceFile::cast(&syntax_node) { |
47 | let module_source = if let Some(source_file) = ast::SourceFile::cast(syntax_node) { | 47 | ModuleSource::SourceFile(source_file.to_owned()) |
48 | ModuleSource::SourceFile(source_file.owned()) | ||
49 | } else { | 48 | } else { |
50 | let module = ast::Module::cast(syntax_node).unwrap(); | 49 | let module = ast::Module::cast(&syntax_node).unwrap(); |
51 | ModuleSource::Module(module.owned()) | 50 | ModuleSource::Module(module.to_owned()) |
52 | }; | 51 | }; |
53 | Ok((file_id, module_source)) | 52 | Ok((file_id, module_source)) |
54 | } | 53 | } |
@@ -56,7 +55,7 @@ impl Module { | |||
56 | pub fn declaration_source_impl( | 55 | pub fn declaration_source_impl( |
57 | &self, | 56 | &self, |
58 | db: &impl HirDatabase, | 57 | db: &impl HirDatabase, |
59 | ) -> Cancelable<Option<(FileId, ast::ModuleNode)>> { | 58 | ) -> Cancelable<Option<(FileId, TreePtr<ast::Module>)>> { |
60 | let loc = self.def_id.loc(db); | 59 | let loc = self.def_id.loc(db); |
61 | let module_tree = db.module_tree(loc.source_root_id)?; | 60 | let module_tree = db.module_tree(loc.source_root_id)?; |
62 | let link = ctry!(loc.module_id.parent_link(&module_tree)); | 61 | let link = ctry!(loc.module_id.parent_link(&module_tree)); |
@@ -146,7 +145,10 @@ impl Module { | |||
146 | } | 145 | } |
147 | Ok(curr_per_ns) | 146 | Ok(curr_per_ns) |
148 | } | 147 | } |
149 | pub fn problems_impl(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> { | 148 | pub fn problems_impl( |
149 | &self, | ||
150 | db: &impl HirDatabase, | ||
151 | ) -> Cancelable<Vec<(TreePtr<SyntaxNode>, Problem)>> { | ||
150 | let loc = self.def_id.loc(db); | 152 | let loc = self.def_id.loc(db); |
151 | let module_tree = db.module_tree(loc.source_root_id)?; | 153 | let module_tree = db.module_tree(loc.source_root_id)?; |
152 | Ok(loc.module_id.problems(&module_tree, db)) | 154 | Ok(loc.module_id.problems(&module_tree, db)) |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 04249400b..03e65387d 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SyntaxNode, SourceFileNode}; | 3 | use ra_syntax::{SyntaxNode, TreePtr, SourceFile}; |
4 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; | 4 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
@@ -22,7 +22,7 @@ pub trait HirDatabase: SyntaxDatabase | |||
22 | + AsRef<LocationIntener<DefLoc, DefId>> | 22 | + AsRef<LocationIntener<DefLoc, DefId>> |
23 | + AsRef<LocationIntener<MacroCallLoc, MacroCallId>> | 23 | + AsRef<LocationIntener<MacroCallLoc, MacroCallId>> |
24 | { | 24 | { |
25 | fn hir_source_file(file_id: HirFileId) -> SourceFileNode { | 25 | fn hir_source_file(file_id: HirFileId) -> TreePtr<SourceFile> { |
26 | type HirSourceFileQuery; | 26 | type HirSourceFileQuery; |
27 | use fn HirFileId::hir_source_file; | 27 | use fn HirFileId::hir_source_file; |
28 | } | 28 | } |
@@ -66,7 +66,7 @@ pub trait HirDatabase: SyntaxDatabase | |||
66 | use fn query_definitions::file_items; | 66 | use fn query_definitions::file_items; |
67 | } | 67 | } |
68 | 68 | ||
69 | fn file_item(source_item_id: SourceItemId) -> SyntaxNode { | 69 | fn file_item(source_item_id: SourceItemId) -> TreePtr<SyntaxNode> { |
70 | type FileItemQuery; | 70 | type FileItemQuery; |
71 | use fn query_definitions::file_item; | 71 | use fn query_definitions::file_item; |
72 | } | 72 | } |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index b0063cad2..4c54449ef 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -77,7 +77,7 @@ impl BodySyntaxMapping { | |||
77 | pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> { | 77 | pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> { |
78 | self.expr_syntax_mapping.get(&ptr).cloned() | 78 | self.expr_syntax_mapping.get(&ptr).cloned() |
79 | } | 79 | } |
80 | pub fn node_expr(&self, node: ast::Expr) -> Option<ExprId> { | 80 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { |
81 | self.expr_syntax_mapping | 81 | self.expr_syntax_mapping |
82 | .get(&LocalSyntaxPtr::new(node.syntax())) | 82 | .get(&LocalSyntaxPtr::new(node.syntax())) |
83 | .cloned() | 83 | .cloned() |
@@ -88,7 +88,7 @@ impl BodySyntaxMapping { | |||
88 | pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> { | 88 | pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> { |
89 | self.pat_syntax_mapping.get(&ptr).cloned() | 89 | self.pat_syntax_mapping.get(&ptr).cloned() |
90 | } | 90 | } |
91 | pub fn node_pat(&self, node: ast::Pat) -> Option<PatId> { | 91 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
92 | self.pat_syntax_mapping | 92 | self.pat_syntax_mapping |
93 | .get(&LocalSyntaxPtr::new(node.syntax())) | 93 | .get(&LocalSyntaxPtr::new(node.syntax())) |
94 | .cloned() | 94 | .cloned() |
@@ -373,10 +373,10 @@ impl ExprCollector { | |||
373 | self.exprs.alloc(block) | 373 | self.exprs.alloc(block) |
374 | } | 374 | } |
375 | 375 | ||
376 | fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { | 376 | fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId { |
377 | let syntax_ptr = LocalSyntaxPtr::new(expr.syntax()); | 377 | let syntax_ptr = LocalSyntaxPtr::new(expr.syntax()); |
378 | match expr { | 378 | match expr.kind() { |
379 | ast::Expr::IfExpr(e) => { | 379 | ast::ExprKind::IfExpr(e) => { |
380 | if let Some(pat) = e.condition().and_then(|c| c.pat()) { | 380 | if let Some(pat) = e.condition().and_then(|c| c.pat()) { |
381 | // if let -- desugar to match | 381 | // if let -- desugar to match |
382 | let pat = self.collect_pat(pat); | 382 | let pat = self.collect_pat(pat); |
@@ -419,12 +419,12 @@ impl ExprCollector { | |||
419 | ) | 419 | ) |
420 | } | 420 | } |
421 | } | 421 | } |
422 | ast::Expr::BlockExpr(e) => self.collect_block_opt(e.block()), | 422 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), |
423 | ast::Expr::LoopExpr(e) => { | 423 | ast::ExprKind::LoopExpr(e) => { |
424 | let body = self.collect_block_opt(e.loop_body()); | 424 | let body = self.collect_block_opt(e.loop_body()); |
425 | self.alloc_expr(Expr::Loop { body }, syntax_ptr) | 425 | self.alloc_expr(Expr::Loop { body }, syntax_ptr) |
426 | } | 426 | } |
427 | ast::Expr::WhileExpr(e) => { | 427 | ast::ExprKind::WhileExpr(e) => { |
428 | let condition = if let Some(condition) = e.condition() { | 428 | let condition = if let Some(condition) = e.condition() { |
429 | if condition.pat().is_none() { | 429 | if condition.pat().is_none() { |
430 | self.collect_expr_opt(condition.expr()) | 430 | self.collect_expr_opt(condition.expr()) |
@@ -438,7 +438,7 @@ impl ExprCollector { | |||
438 | let body = self.collect_block_opt(e.loop_body()); | 438 | let body = self.collect_block_opt(e.loop_body()); |
439 | self.alloc_expr(Expr::While { condition, body }, syntax_ptr) | 439 | self.alloc_expr(Expr::While { condition, body }, syntax_ptr) |
440 | } | 440 | } |
441 | ast::Expr::ForExpr(e) => { | 441 | ast::ExprKind::ForExpr(e) => { |
442 | let iterable = self.collect_expr_opt(e.iterable()); | 442 | let iterable = self.collect_expr_opt(e.iterable()); |
443 | let pat = self.collect_pat_opt(e.pat()); | 443 | let pat = self.collect_pat_opt(e.pat()); |
444 | let body = self.collect_block_opt(e.loop_body()); | 444 | let body = self.collect_block_opt(e.loop_body()); |
@@ -451,7 +451,7 @@ impl ExprCollector { | |||
451 | syntax_ptr, | 451 | syntax_ptr, |
452 | ) | 452 | ) |
453 | } | 453 | } |
454 | ast::Expr::CallExpr(e) => { | 454 | ast::ExprKind::CallExpr(e) => { |
455 | let callee = self.collect_expr_opt(e.expr()); | 455 | let callee = self.collect_expr_opt(e.expr()); |
456 | let args = if let Some(arg_list) = e.arg_list() { | 456 | let args = if let Some(arg_list) = e.arg_list() { |
457 | arg_list.args().map(|e| self.collect_expr(e)).collect() | 457 | arg_list.args().map(|e| self.collect_expr(e)).collect() |
@@ -460,7 +460,7 @@ impl ExprCollector { | |||
460 | }; | 460 | }; |
461 | self.alloc_expr(Expr::Call { callee, args }, syntax_ptr) | 461 | self.alloc_expr(Expr::Call { callee, args }, syntax_ptr) |
462 | } | 462 | } |
463 | ast::Expr::MethodCallExpr(e) => { | 463 | ast::ExprKind::MethodCallExpr(e) => { |
464 | let receiver = self.collect_expr_opt(e.expr()); | 464 | let receiver = self.collect_expr_opt(e.expr()); |
465 | let args = if let Some(arg_list) = e.arg_list() { | 465 | let args = if let Some(arg_list) = e.arg_list() { |
466 | arg_list.args().map(|e| self.collect_expr(e)).collect() | 466 | arg_list.args().map(|e| self.collect_expr(e)).collect() |
@@ -480,7 +480,7 @@ impl ExprCollector { | |||
480 | syntax_ptr, | 480 | syntax_ptr, |
481 | ) | 481 | ) |
482 | } | 482 | } |
483 | ast::Expr::MatchExpr(e) => { | 483 | ast::ExprKind::MatchExpr(e) => { |
484 | let expr = self.collect_expr_opt(e.expr()); | 484 | let expr = self.collect_expr_opt(e.expr()); |
485 | let arms = if let Some(match_arm_list) = e.match_arm_list() { | 485 | let arms = if let Some(match_arm_list) = e.match_arm_list() { |
486 | match_arm_list | 486 | match_arm_list |
@@ -495,7 +495,7 @@ impl ExprCollector { | |||
495 | }; | 495 | }; |
496 | self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr) | 496 | self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr) |
497 | } | 497 | } |
498 | ast::Expr::PathExpr(e) => { | 498 | ast::ExprKind::PathExpr(e) => { |
499 | let path = e | 499 | let path = e |
500 | .path() | 500 | .path() |
501 | .and_then(Path::from_ast) | 501 | .and_then(Path::from_ast) |
@@ -503,25 +503,25 @@ impl ExprCollector { | |||
503 | .unwrap_or(Expr::Missing); | 503 | .unwrap_or(Expr::Missing); |
504 | self.alloc_expr(path, syntax_ptr) | 504 | self.alloc_expr(path, syntax_ptr) |
505 | } | 505 | } |
506 | ast::Expr::ContinueExpr(_e) => { | 506 | ast::ExprKind::ContinueExpr(_e) => { |
507 | // TODO: labels | 507 | // TODO: labels |
508 | self.alloc_expr(Expr::Continue, syntax_ptr) | 508 | self.alloc_expr(Expr::Continue, syntax_ptr) |
509 | } | 509 | } |
510 | ast::Expr::BreakExpr(e) => { | 510 | ast::ExprKind::BreakExpr(e) => { |
511 | let expr = e.expr().map(|e| self.collect_expr(e)); | 511 | let expr = e.expr().map(|e| self.collect_expr(e)); |
512 | self.alloc_expr(Expr::Break { expr }, syntax_ptr) | 512 | self.alloc_expr(Expr::Break { expr }, syntax_ptr) |
513 | } | 513 | } |
514 | ast::Expr::ParenExpr(e) => { | 514 | ast::ExprKind::ParenExpr(e) => { |
515 | let inner = self.collect_expr_opt(e.expr()); | 515 | let inner = self.collect_expr_opt(e.expr()); |
516 | // make the paren expr point to the inner expression as well | 516 | // make the paren expr point to the inner expression as well |
517 | self.expr_syntax_mapping.insert(syntax_ptr, inner); | 517 | self.expr_syntax_mapping.insert(syntax_ptr, inner); |
518 | inner | 518 | inner |
519 | } | 519 | } |
520 | ast::Expr::ReturnExpr(e) => { | 520 | ast::ExprKind::ReturnExpr(e) => { |
521 | let expr = e.expr().map(|e| self.collect_expr(e)); | 521 | let expr = e.expr().map(|e| self.collect_expr(e)); |
522 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) | 522 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) |
523 | } | 523 | } |
524 | ast::Expr::StructLit(e) => { | 524 | ast::ExprKind::StructLit(e) => { |
525 | let path = e.path().and_then(Path::from_ast); | 525 | let path = e.path().and_then(Path::from_ast); |
526 | let fields = if let Some(nfl) = e.named_field_list() { | 526 | let fields = if let Some(nfl) = e.named_field_list() { |
527 | nfl.fields() | 527 | nfl.fields() |
@@ -558,7 +558,7 @@ impl ExprCollector { | |||
558 | syntax_ptr, | 558 | syntax_ptr, |
559 | ) | 559 | ) |
560 | } | 560 | } |
561 | ast::Expr::FieldExpr(e) => { | 561 | ast::ExprKind::FieldExpr(e) => { |
562 | let expr = self.collect_expr_opt(e.expr()); | 562 | let expr = self.collect_expr_opt(e.expr()); |
563 | let name = e | 563 | let name = e |
564 | .name_ref() | 564 | .name_ref() |
@@ -566,26 +566,26 @@ impl ExprCollector { | |||
566 | .unwrap_or_else(Name::missing); | 566 | .unwrap_or_else(Name::missing); |
567 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) | 567 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) |
568 | } | 568 | } |
569 | ast::Expr::TryExpr(e) => { | 569 | ast::ExprKind::TryExpr(e) => { |
570 | let expr = self.collect_expr_opt(e.expr()); | 570 | let expr = self.collect_expr_opt(e.expr()); |
571 | self.alloc_expr(Expr::Try { expr }, syntax_ptr) | 571 | self.alloc_expr(Expr::Try { expr }, syntax_ptr) |
572 | } | 572 | } |
573 | ast::Expr::CastExpr(e) => { | 573 | ast::ExprKind::CastExpr(e) => { |
574 | let expr = self.collect_expr_opt(e.expr()); | 574 | let expr = self.collect_expr_opt(e.expr()); |
575 | let type_ref = TypeRef::from_ast_opt(e.type_ref()); | 575 | let type_ref = TypeRef::from_ast_opt(e.type_ref()); |
576 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) | 576 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) |
577 | } | 577 | } |
578 | ast::Expr::RefExpr(e) => { | 578 | ast::ExprKind::RefExpr(e) => { |
579 | let expr = self.collect_expr_opt(e.expr()); | 579 | let expr = self.collect_expr_opt(e.expr()); |
580 | let mutability = Mutability::from_mutable(e.is_mut()); | 580 | let mutability = Mutability::from_mutable(e.is_mut()); |
581 | self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) | 581 | self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) |
582 | } | 582 | } |
583 | ast::Expr::PrefixExpr(e) => { | 583 | ast::ExprKind::PrefixExpr(e) => { |
584 | let expr = self.collect_expr_opt(e.expr()); | 584 | let expr = self.collect_expr_opt(e.expr()); |
585 | let op = e.op(); | 585 | let op = e.op(); |
586 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) | 586 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) |
587 | } | 587 | } |
588 | ast::Expr::LambdaExpr(e) => { | 588 | ast::ExprKind::LambdaExpr(e) => { |
589 | let mut args = Vec::new(); | 589 | let mut args = Vec::new(); |
590 | let mut arg_types = Vec::new(); | 590 | let mut arg_types = Vec::new(); |
591 | if let Some(pl) = e.param_list() { | 591 | if let Some(pl) = e.param_list() { |
@@ -606,7 +606,7 @@ impl ExprCollector { | |||
606 | syntax_ptr, | 606 | syntax_ptr, |
607 | ) | 607 | ) |
608 | } | 608 | } |
609 | ast::Expr::BinExpr(e) => { | 609 | ast::ExprKind::BinExpr(e) => { |
610 | let lhs = self.collect_expr_opt(e.lhs()); | 610 | let lhs = self.collect_expr_opt(e.lhs()); |
611 | let rhs = self.collect_expr_opt(e.rhs()); | 611 | let rhs = self.collect_expr_opt(e.rhs()); |
612 | let op = e.op(); | 612 | let op = e.op(); |
@@ -614,16 +614,16 @@ impl ExprCollector { | |||
614 | } | 614 | } |
615 | 615 | ||
616 | // TODO implement HIR for these: | 616 | // TODO implement HIR for these: |
617 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 617 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
618 | ast::Expr::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 618 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
619 | ast::Expr::TupleExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 619 | ast::ExprKind::TupleExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
620 | ast::Expr::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 620 | ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
621 | ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 621 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
622 | ast::Expr::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 622 | ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
623 | } | 623 | } |
624 | } | 624 | } |
625 | 625 | ||
626 | fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { | 626 | fn collect_expr_opt(&mut self, expr: Option<&ast::Expr>) -> ExprId { |
627 | if let Some(expr) = expr { | 627 | if let Some(expr) = expr { |
628 | self.collect_expr(expr) | 628 | self.collect_expr(expr) |
629 | } else { | 629 | } else { |
@@ -631,11 +631,11 @@ impl ExprCollector { | |||
631 | } | 631 | } |
632 | } | 632 | } |
633 | 633 | ||
634 | fn collect_block(&mut self, block: ast::Block) -> ExprId { | 634 | fn collect_block(&mut self, block: &ast::Block) -> ExprId { |
635 | let statements = block | 635 | let statements = block |
636 | .statements() | 636 | .statements() |
637 | .map(|s| match s { | 637 | .map(|s| match s.kind() { |
638 | ast::Stmt::LetStmt(stmt) => { | 638 | ast::StmtKind::LetStmt(stmt) => { |
639 | let pat = self.collect_pat_opt(stmt.pat()); | 639 | let pat = self.collect_pat_opt(stmt.pat()); |
640 | let type_ref = stmt.type_ref().map(TypeRef::from_ast); | 640 | let type_ref = stmt.type_ref().map(TypeRef::from_ast); |
641 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 641 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
@@ -645,7 +645,9 @@ impl ExprCollector { | |||
645 | initializer, | 645 | initializer, |
646 | } | 646 | } |
647 | } | 647 | } |
648 | ast::Stmt::ExprStmt(stmt) => Statement::Expr(self.collect_expr_opt(stmt.expr())), | 648 | ast::StmtKind::ExprStmt(stmt) => { |
649 | Statement::Expr(self.collect_expr_opt(stmt.expr())) | ||
650 | } | ||
649 | }) | 651 | }) |
650 | .collect(); | 652 | .collect(); |
651 | let tail = block.expr().map(|e| self.collect_expr(e)); | 653 | let tail = block.expr().map(|e| self.collect_expr(e)); |
@@ -655,7 +657,7 @@ impl ExprCollector { | |||
655 | ) | 657 | ) |
656 | } | 658 | } |
657 | 659 | ||
658 | fn collect_block_opt(&mut self, block: Option<ast::Block>) -> ExprId { | 660 | fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId { |
659 | if let Some(block) = block { | 661 | if let Some(block) = block { |
660 | self.collect_block(block) | 662 | self.collect_block(block) |
661 | } else { | 663 | } else { |
@@ -663,17 +665,17 @@ impl ExprCollector { | |||
663 | } | 665 | } |
664 | } | 666 | } |
665 | 667 | ||
666 | fn collect_pat(&mut self, pat: ast::Pat) -> PatId { | 668 | fn collect_pat(&mut self, pat: &ast::Pat) -> PatId { |
667 | let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); | 669 | let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); |
668 | match pat { | 670 | match pat.kind() { |
669 | ast::Pat::BindPat(bp) => { | 671 | ast::PatKind::BindPat(bp) => { |
670 | let name = bp | 672 | let name = bp |
671 | .name() | 673 | .name() |
672 | .map(|nr| nr.as_name()) | 674 | .map(|nr| nr.as_name()) |
673 | .unwrap_or_else(Name::missing); | 675 | .unwrap_or_else(Name::missing); |
674 | self.alloc_pat(Pat::Bind { name }, syntax_ptr) | 676 | self.alloc_pat(Pat::Bind { name }, syntax_ptr) |
675 | } | 677 | } |
676 | ast::Pat::TupleStructPat(p) => { | 678 | ast::PatKind::TupleStructPat(p) => { |
677 | let path = p.path().and_then(Path::from_ast); | 679 | let path = p.path().and_then(Path::from_ast); |
678 | let args = p.args().map(|p| self.collect_pat(p)).collect(); | 680 | let args = p.args().map(|p| self.collect_pat(p)).collect(); |
679 | self.alloc_pat(Pat::TupleStruct { path, args }, syntax_ptr) | 681 | self.alloc_pat(Pat::TupleStruct { path, args }, syntax_ptr) |
@@ -685,7 +687,7 @@ impl ExprCollector { | |||
685 | } | 687 | } |
686 | } | 688 | } |
687 | 689 | ||
688 | fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId { | 690 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { |
689 | if let Some(pat) = pat { | 691 | if let Some(pat) = pat { |
690 | self.collect_pat(pat) | 692 | self.collect_pat(pat) |
691 | } else { | 693 | } else { |
@@ -710,7 +712,7 @@ impl ExprCollector { | |||
710 | } | 712 | } |
711 | } | 713 | } |
712 | 714 | ||
713 | pub(crate) fn collect_fn_body_syntax(node: ast::FnDef) -> BodySyntaxMapping { | 715 | pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping { |
714 | let mut collector = ExprCollector::new(); | 716 | let mut collector = ExprCollector::new(); |
715 | 717 | ||
716 | let args = if let Some(param_list) = node.param_list() { | 718 | let args = if let Some(param_list) = node.param_list() { |
@@ -758,9 +760,7 @@ pub(crate) fn body_syntax_mapping( | |||
758 | let body_syntax_mapping = match def { | 760 | let body_syntax_mapping = match def { |
759 | Def::Function(f) => { | 761 | Def::Function(f) => { |
760 | let node = f.syntax(db); | 762 | let node = f.syntax(db); |
761 | let node = node.borrowed(); | 763 | collect_fn_body_syntax(&node) |
762 | |||
763 | collect_fn_body_syntax(node) | ||
764 | } | 764 | } |
765 | // TODO: consts, etc. | 765 | // TODO: consts, etc. |
766 | _ => panic!("Trying to get body for item type without body"), | 766 | _ => panic!("Trying to get body for item type without body"), |
diff --git a/crates/ra_hir/src/function.rs b/crates/ra_hir/src/function.rs index 4627be071..81b790c5f 100644 --- a/crates/ra_hir/src/function.rs +++ b/crates/ra_hir/src/function.rs | |||
@@ -7,7 +7,7 @@ use std::{ | |||
7 | 7 | ||
8 | use ra_db::Cancelable; | 8 | use ra_db::Cancelable; |
9 | use ra_syntax::{ | 9 | use ra_syntax::{ |
10 | TextRange, TextUnit, | 10 | TextRange, TextUnit, TreePtr, |
11 | ast::{self, AstNode, DocCommentsOwner, NameOwner}, | 11 | ast::{self, AstNode, DocCommentsOwner, NameOwner}, |
12 | }; | 12 | }; |
13 | 13 | ||
@@ -29,11 +29,11 @@ impl Function { | |||
29 | self.def_id | 29 | self.def_id |
30 | } | 30 | } |
31 | 31 | ||
32 | pub fn syntax(&self, db: &impl HirDatabase) -> ast::FnDefNode { | 32 | pub fn syntax(&self, db: &impl HirDatabase) -> TreePtr<ast::FnDef> { |
33 | let def_loc = self.def_id.loc(db); | 33 | let def_loc = self.def_id.loc(db); |
34 | assert!(def_loc.kind == DefKind::Function); | 34 | assert!(def_loc.kind == DefKind::Function); |
35 | let syntax = db.file_item(def_loc.source_item_id); | 35 | let syntax = db.file_item(def_loc.source_item_id); |
36 | ast::FnDef::cast(syntax.borrowed()).unwrap().owned() | 36 | ast::FnDef::cast(&syntax).unwrap().to_owned() |
37 | } | 37 | } |
38 | 38 | ||
39 | pub fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> { | 39 | pub fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> { |
@@ -59,7 +59,7 @@ impl Function { | |||
59 | 59 | ||
60 | pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> { | 60 | pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> { |
61 | let syntax = self.syntax(db); | 61 | let syntax = self.syntax(db); |
62 | FnSignatureInfo::new(syntax.borrowed()) | 62 | FnSignatureInfo::new(&syntax) |
63 | } | 63 | } |
64 | 64 | ||
65 | pub fn infer(&self, db: &impl HirDatabase) -> Cancelable<Arc<InferenceResult>> { | 65 | pub fn infer(&self, db: &impl HirDatabase) -> Cancelable<Arc<InferenceResult>> { |
@@ -99,8 +99,7 @@ impl FnSignature { | |||
99 | 99 | ||
100 | pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> { | 100 | pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> { |
101 | let func = Function::new(def_id); | 101 | let func = Function::new(def_id); |
102 | let syntax = func.syntax(db); | 102 | let node = func.syntax(db); |
103 | let node = syntax.borrowed(); | ||
104 | let mut args = Vec::new(); | 103 | let mut args = Vec::new(); |
105 | if let Some(param_list) = node.param_list() { | 104 | if let Some(param_list) = node.param_list() { |
106 | if let Some(self_param) = param_list.self_param() { | 105 | if let Some(self_param) = param_list.self_param() { |
@@ -144,7 +143,7 @@ pub struct FnSignatureInfo { | |||
144 | } | 143 | } |
145 | 144 | ||
146 | impl FnSignatureInfo { | 145 | impl FnSignatureInfo { |
147 | fn new(node: ast::FnDef) -> Option<Self> { | 146 | fn new(node: &ast::FnDef) -> Option<Self> { |
148 | let name = node.name()?.text().to_string(); | 147 | let name = node.name()?.text().to_string(); |
149 | 148 | ||
150 | let mut doc = None; | 149 | let mut doc = None; |
@@ -207,7 +206,7 @@ impl FnSignatureInfo { | |||
207 | }) | 206 | }) |
208 | } | 207 | } |
209 | 208 | ||
210 | fn extract_doc_comments(node: ast::FnDef) -> Option<(TextRange, String)> { | 209 | fn extract_doc_comments(node: &ast::FnDef) -> Option<(TextRange, String)> { |
211 | if node.doc_comments().count() == 0 { | 210 | if node.doc_comments().count() == 0 { |
212 | return None; | 211 | return None; |
213 | } | 212 | } |
@@ -227,7 +226,7 @@ impl FnSignatureInfo { | |||
227 | Some((range, comment_text)) | 226 | Some((range, comment_text)) |
228 | } | 227 | } |
229 | 228 | ||
230 | fn param_list(node: ast::FnDef) -> Vec<String> { | 229 | fn param_list(node: &ast::FnDef) -> Vec<String> { |
231 | let mut res = vec![]; | 230 | let mut res = vec![]; |
232 | if let Some(param_list) = node.param_list() { | 231 | if let Some(param_list) = node.param_list() { |
233 | if let Some(self_param) = param_list.self_param() { | 232 | if let Some(self_param) = param_list.self_param() { |
diff --git a/crates/ra_hir/src/function/scope.rs b/crates/ra_hir/src/function/scope.rs index 0a12f0b35..699784f71 100644 --- a/crates/ra_hir/src/function/scope.rs +++ b/crates/ra_hir/src/function/scope.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | 4 | ||
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | AstNode, SyntaxNodeRef, TextUnit, TextRange, | 6 | AstNode, SyntaxNode, TextUnit, TextRange, |
7 | algo::generate, | 7 | algo::generate, |
8 | ast, | 8 | ast, |
9 | }; | 9 | }; |
@@ -127,7 +127,7 @@ impl ScopeEntryWithSyntax { | |||
127 | } | 127 | } |
128 | 128 | ||
129 | impl ScopesWithSyntaxMapping { | 129 | impl ScopesWithSyntaxMapping { |
130 | pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a { | 130 | pub fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a { |
131 | generate(self.scope_for(node), move |&scope| { | 131 | generate(self.scope_for(node), move |&scope| { |
132 | self.scopes.scopes[scope].parent | 132 | self.scopes.scopes[scope].parent |
133 | }) | 133 | }) |
@@ -178,7 +178,7 @@ impl ScopesWithSyntaxMapping { | |||
178 | .unwrap_or(original_scope) | 178 | .unwrap_or(original_scope) |
179 | } | 179 | } |
180 | 180 | ||
181 | pub fn resolve_local_name(&self, name_ref: ast::NameRef) -> Option<ScopeEntryWithSyntax> { | 181 | pub fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> { |
182 | let mut shadowed = FxHashSet::default(); | 182 | let mut shadowed = FxHashSet::default(); |
183 | let name = name_ref.as_name(); | 183 | let name = name_ref.as_name(); |
184 | let ret = self | 184 | let ret = self |
@@ -195,7 +195,7 @@ impl ScopesWithSyntaxMapping { | |||
195 | }) | 195 | }) |
196 | } | 196 | } |
197 | 197 | ||
198 | pub fn find_all_refs(&self, pat: ast::BindPat) -> Vec<ReferenceDescriptor> { | 198 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |
199 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | 199 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); |
200 | let name_ptr = LocalSyntaxPtr::new(pat.syntax()); | 200 | let name_ptr = LocalSyntaxPtr::new(pat.syntax()); |
201 | fn_def | 201 | fn_def |
@@ -213,7 +213,7 @@ impl ScopesWithSyntaxMapping { | |||
213 | .collect() | 213 | .collect() |
214 | } | 214 | } |
215 | 215 | ||
216 | fn scope_for(&self, node: SyntaxNodeRef) -> Option<ScopeId> { | 216 | fn scope_for(&self, node: &SyntaxNode) -> Option<ScopeId> { |
217 | node.ancestors() | 217 | node.ancestors() |
218 | .map(LocalSyntaxPtr::new) | 218 | .map(LocalSyntaxPtr::new) |
219 | .filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr)) | 219 | .filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr)) |
@@ -309,7 +309,7 @@ pub struct ReferenceDescriptor { | |||
309 | #[cfg(test)] | 309 | #[cfg(test)] |
310 | mod tests { | 310 | mod tests { |
311 | use ra_editor::find_node_at_offset; | 311 | use ra_editor::find_node_at_offset; |
312 | use ra_syntax::SourceFileNode; | 312 | use ra_syntax::SourceFile; |
313 | use test_utils::{extract_offset, assert_eq_text}; | 313 | use test_utils::{extract_offset, assert_eq_text}; |
314 | 314 | ||
315 | use crate::expr; | 315 | use crate::expr; |
@@ -326,9 +326,9 @@ mod tests { | |||
326 | buf.push_str(&code[off..]); | 326 | buf.push_str(&code[off..]); |
327 | buf | 327 | buf |
328 | }; | 328 | }; |
329 | let file = SourceFileNode::parse(&code); | 329 | let file = SourceFile::parse(&code); |
330 | let marker: ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); | 330 | let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); |
331 | let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | 331 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); |
332 | let body_hir = expr::collect_fn_body_syntax(fn_def); | 332 | let body_hir = expr::collect_fn_body_syntax(fn_def); |
333 | let scopes = FnScopes::new(Arc::clone(body_hir.body())); | 333 | let scopes = FnScopes::new(Arc::clone(body_hir.body())); |
334 | let scopes = ScopesWithSyntaxMapping { | 334 | let scopes = ScopesWithSyntaxMapping { |
@@ -422,9 +422,9 @@ mod tests { | |||
422 | 422 | ||
423 | fn do_check_local_name(code: &str, expected_offset: u32) { | 423 | fn do_check_local_name(code: &str, expected_offset: u32) { |
424 | let (off, code) = extract_offset(code); | 424 | let (off, code) = extract_offset(code); |
425 | let file = SourceFileNode::parse(&code); | 425 | let file = SourceFile::parse(&code); |
426 | let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | 426 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); |
427 | let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); | 427 | let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); |
428 | 428 | ||
429 | let body_hir = expr::collect_fn_body_syntax(fn_def); | 429 | let body_hir = expr::collect_fn_body_syntax(fn_def); |
430 | let scopes = FnScopes::new(Arc::clone(body_hir.body())); | 430 | let scopes = FnScopes::new(Arc::clone(body_hir.body())); |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index c7391ee05..730a3e542 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId}; | 1 | use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId}; |
2 | use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast}; | 2 | use ra_syntax::{TreePtr, 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 | ||
5 | use crate::{HirDatabase, PerNs, ModuleId, Def, Function, Struct, Enum, ImplBlock, Crate}; | 5 | use crate::{HirDatabase, PerNs, ModuleId, Def, Function, Struct, Enum, ImplBlock, Crate}; |
@@ -55,7 +55,10 @@ impl HirFileId { | |||
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | pub(crate) fn hir_source_file(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode { | 58 | pub(crate) fn hir_source_file( |
59 | db: &impl HirDatabase, | ||
60 | file_id: HirFileId, | ||
61 | ) -> TreePtr<SourceFile> { | ||
59 | match file_id.0 { | 62 | match file_id.0 { |
60 | HirFileIdRepr::File(file_id) => db.source_file(file_id), | 63 | HirFileIdRepr::File(file_id) => db.source_file(file_id), |
61 | HirFileIdRepr::Macro(m) => { | 64 | HirFileIdRepr::Macro(m) => { |
@@ -63,7 +66,7 @@ impl HirFileId { | |||
63 | return exp.file(); | 66 | return exp.file(); |
64 | } | 67 | } |
65 | // returning an empty string looks fishy... | 68 | // returning an empty string looks fishy... |
66 | SourceFileNode::parse("") | 69 | SourceFile::parse("") |
67 | } | 70 | } |
68 | } | 71 | } |
69 | } | 72 | } |
@@ -233,11 +236,11 @@ pub struct SourceItemId { | |||
233 | #[derive(Debug, PartialEq, Eq)] | 236 | #[derive(Debug, PartialEq, Eq)] |
234 | pub struct SourceFileItems { | 237 | pub struct SourceFileItems { |
235 | file_id: HirFileId, | 238 | file_id: HirFileId, |
236 | arena: Arena<SourceFileItemId, SyntaxNode>, | 239 | arena: Arena<SourceFileItemId, TreePtr<SyntaxNode>>, |
237 | } | 240 | } |
238 | 241 | ||
239 | impl SourceFileItems { | 242 | impl SourceFileItems { |
240 | pub(crate) fn new(file_id: HirFileId, source_file: SourceFile) -> SourceFileItems { | 243 | pub(crate) fn new(file_id: HirFileId, source_file: &SourceFile) -> SourceFileItems { |
241 | let mut res = SourceFileItems { | 244 | let mut res = SourceFileItems { |
242 | file_id, | 245 | file_id, |
243 | arena: Arena::default(), | 246 | arena: Arena::default(), |
@@ -246,20 +249,20 @@ impl SourceFileItems { | |||
246 | res | 249 | res |
247 | } | 250 | } |
248 | 251 | ||
249 | fn init(&mut self, source_file: SourceFile) { | 252 | fn init(&mut self, source_file: &SourceFile) { |
250 | source_file.syntax().descendants().for_each(|it| { | 253 | source_file.syntax().descendants().for_each(|it| { |
251 | if let Some(module_item) = ast::ModuleItem::cast(it) { | 254 | if let Some(module_item) = ast::ModuleItem::cast(it) { |
252 | self.alloc(module_item.syntax().owned()); | 255 | self.alloc(module_item.syntax().to_owned()); |
253 | } else if let Some(macro_call) = ast::MacroCall::cast(it) { | 256 | } else if let Some(macro_call) = ast::MacroCall::cast(it) { |
254 | self.alloc(macro_call.syntax().owned()); | 257 | self.alloc(macro_call.syntax().to_owned()); |
255 | } | 258 | } |
256 | }); | 259 | }); |
257 | } | 260 | } |
258 | 261 | ||
259 | fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId { | 262 | fn alloc(&mut self, item: TreePtr<SyntaxNode>) -> SourceFileItemId { |
260 | self.arena.alloc(item) | 263 | self.arena.alloc(item) |
261 | } | 264 | } |
262 | pub(crate) fn id_of(&self, file_id: HirFileId, item: SyntaxNodeRef) -> SourceFileItemId { | 265 | pub(crate) fn id_of(&self, file_id: HirFileId, item: &SyntaxNode) -> SourceFileItemId { |
263 | assert_eq!( | 266 | assert_eq!( |
264 | self.file_id, file_id, | 267 | self.file_id, file_id, |
265 | "SourceFileItems: wrong file, expected {:?}, got {:?}", | 268 | "SourceFileItems: wrong file, expected {:?}, got {:?}", |
@@ -267,8 +270,8 @@ impl SourceFileItems { | |||
267 | ); | 270 | ); |
268 | self.id_of_unchecked(item) | 271 | self.id_of_unchecked(item) |
269 | } | 272 | } |
270 | pub(crate) fn id_of_unchecked(&self, item: SyntaxNodeRef) -> SourceFileItemId { | 273 | pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId { |
271 | if let Some((id, _)) = self.arena.iter().find(|(_id, i)| i.borrowed() == item) { | 274 | if let Some((id, _)) = self.arena.iter().find(|(_id, i)| *i == item) { |
272 | return id; | 275 | return id; |
273 | } | 276 | } |
274 | // This should not happen. Let's try to give a sensible diagnostics. | 277 | // This should not happen. Let's try to give a sensible diagnostics. |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 7ce8d17e6..bb0ad84e4 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -62,7 +62,7 @@ impl ImplData { | |||
62 | db: &impl AsRef<LocationIntener<DefLoc, DefId>>, | 62 | db: &impl AsRef<LocationIntener<DefLoc, DefId>>, |
63 | file_items: &SourceFileItems, | 63 | file_items: &SourceFileItems, |
64 | module: &Module, | 64 | module: &Module, |
65 | node: ast::ImplBlock, | 65 | node: &ast::ImplBlock, |
66 | ) -> Self { | 66 | ) -> Self { |
67 | let target_trait = node.target_type().map(TypeRef::from_ast); | 67 | let target_trait = node.target_type().map(TypeRef::from_ast); |
68 | let target_type = TypeRef::from_ast_opt(node.target_type()); | 68 | let target_type = TypeRef::from_ast_opt(node.target_type()); |
@@ -71,10 +71,10 @@ impl ImplData { | |||
71 | item_list | 71 | item_list |
72 | .impl_items() | 72 | .impl_items() |
73 | .map(|item_node| { | 73 | .map(|item_node| { |
74 | let kind = match item_node { | 74 | let kind = match item_node.kind() { |
75 | ast::ImplItem::FnDef(..) => DefKind::Function, | 75 | ast::ImplItemKind::FnDef(..) => DefKind::Function, |
76 | ast::ImplItem::ConstDef(..) => DefKind::Item, | 76 | ast::ImplItemKind::ConstDef(..) => DefKind::Item, |
77 | ast::ImplItem::TypeDef(..) => DefKind::Item, | 77 | ast::ImplItemKind::TypeDef(..) => DefKind::Item, |
78 | }; | 78 | }; |
79 | let item_id = file_items.id_of_unchecked(item_node.syntax()); | 79 | let item_id = file_items.id_of_unchecked(item_node.syntax()); |
80 | let source_item_id = SourceItemId { | 80 | let source_item_id = SourceItemId { |
@@ -87,10 +87,10 @@ impl ImplData { | |||
87 | ..module_loc | 87 | ..module_loc |
88 | }; | 88 | }; |
89 | let def_id = def_loc.id(db); | 89 | let def_id = def_loc.id(db); |
90 | match item_node { | 90 | match item_node.kind() { |
91 | ast::ImplItem::FnDef(..) => ImplItem::Method(Function::new(def_id)), | 91 | ast::ImplItemKind::FnDef(..) => ImplItem::Method(Function::new(def_id)), |
92 | ast::ImplItem::ConstDef(..) => ImplItem::Const(def_id), | 92 | ast::ImplItemKind::ConstDef(..) => ImplItem::Const(def_id), |
93 | ast::ImplItem::TypeDef(..) => ImplItem::Type(def_id), | 93 | ast::ImplItemKind::TypeDef(..) => ImplItem::Type(def_id), |
94 | } | 94 | } |
95 | }) | 95 | }) |
96 | .collect() | 96 | .collect() |
@@ -152,8 +152,8 @@ impl ModuleImplBlocks { | |||
152 | fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { | 152 | fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { |
153 | let (file_id, module_source) = module.defenition_source(db)?; | 153 | let (file_id, module_source) = module.defenition_source(db)?; |
154 | let node = match &module_source { | 154 | let node = match &module_source { |
155 | ModuleSource::SourceFile(node) => node.borrowed().syntax(), | 155 | ModuleSource::SourceFile(node) => node.syntax(), |
156 | ModuleSource::Module(node) => node.borrowed().syntax(), | 156 | ModuleSource::Module(node) => node.syntax(), |
157 | }; | 157 | }; |
158 | 158 | ||
159 | let source_file_items = db.file_items(file_id.into()); | 159 | let source_file_items = db.file_items(file_id.into()); |
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs index 1b378c977..eb1c86091 100644 --- a/crates/ra_hir/src/macros.rs +++ b/crates/ra_hir/src/macros.rs | |||
@@ -11,7 +11,7 @@ use std::sync::Arc; | |||
11 | 11 | ||
12 | use ra_db::LocalSyntaxPtr; | 12 | use ra_db::LocalSyntaxPtr; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ |
14 | TextRange, TextUnit, SourceFileNode, AstNode, SyntaxNode, | 14 | TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreePtr, |
15 | ast::{self, NameOwner}, | 15 | ast::{self, NameOwner}, |
16 | }; | 16 | }; |
17 | 17 | ||
@@ -28,14 +28,14 @@ pub enum MacroDef { | |||
28 | impl MacroDef { | 28 | impl MacroDef { |
29 | /// Expands macro call, returning the expansion and offset to be used to | 29 | /// Expands macro call, returning the expansion and offset to be used to |
30 | /// convert ranges between expansion and original source. | 30 | /// convert ranges between expansion and original source. |
31 | pub fn ast_expand(macro_call: ast::MacroCall) -> Option<(TextUnit, MacroExpansion)> { | 31 | pub fn ast_expand(macro_call: &ast::MacroCall) -> Option<(TextUnit, MacroExpansion)> { |
32 | let (def, input) = MacroDef::from_call(macro_call)?; | 32 | let (def, input) = MacroDef::from_call(macro_call)?; |
33 | let exp = def.expand(input)?; | 33 | let exp = def.expand(input)?; |
34 | let off = macro_call.token_tree()?.syntax().range().start(); | 34 | let off = macro_call.token_tree()?.syntax().range().start(); |
35 | Some((off, exp)) | 35 | Some((off, exp)) |
36 | } | 36 | } |
37 | 37 | ||
38 | fn from_call(macro_call: ast::MacroCall) -> Option<(MacroDef, MacroInput)> { | 38 | fn from_call(macro_call: &ast::MacroCall) -> Option<(MacroDef, MacroInput)> { |
39 | let def = { | 39 | let def = { |
40 | let path = macro_call.path()?; | 40 | let path = macro_call.path()?; |
41 | let name_ref = path.segment()?.name_ref()?; | 41 | let name_ref = path.segment()?.name_ref()?; |
@@ -77,7 +77,7 @@ impl MacroDef { | |||
77 | }}", | 77 | }}", |
78 | input.text | 78 | input.text |
79 | ); | 79 | ); |
80 | let file = SourceFileNode::parse(&text); | 80 | let file = SourceFile::parse(&text); |
81 | let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; | 81 | let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; |
82 | let match_arg = match_expr.expr()?; | 82 | let match_arg = match_expr.expr()?; |
83 | let ptr = LocalSyntaxPtr::new(match_arg.syntax()); | 83 | let ptr = LocalSyntaxPtr::new(match_arg.syntax()); |
@@ -92,7 +92,7 @@ impl MacroDef { | |||
92 | } | 92 | } |
93 | fn expand_vec(self, input: MacroInput) -> Option<MacroExpansion> { | 93 | fn expand_vec(self, input: MacroInput) -> Option<MacroExpansion> { |
94 | let text = format!(r"fn dummy() {{ {}; }}", input.text); | 94 | let text = format!(r"fn dummy() {{ {}; }}", input.text); |
95 | let file = SourceFileNode::parse(&text); | 95 | let file = SourceFile::parse(&text); |
96 | let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?; | 96 | let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?; |
97 | let ptr = LocalSyntaxPtr::new(array_expr.syntax()); | 97 | let ptr = LocalSyntaxPtr::new(array_expr.syntax()); |
98 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); | 98 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); |
@@ -116,7 +116,7 @@ impl MacroDef { | |||
116 | } | 116 | } |
117 | let src_range = TextRange::offset_len((pos as u32).into(), TextUnit::of_str(&trait_name)); | 117 | let src_range = TextRange::offset_len((pos as u32).into(), TextUnit::of_str(&trait_name)); |
118 | let text = format!(r"trait {} {{ }}", trait_name); | 118 | let text = format!(r"trait {} {{ }}", trait_name); |
119 | let file = SourceFileNode::parse(&text); | 119 | let file = SourceFile::parse(&text); |
120 | let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?; | 120 | let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?; |
121 | let name = trait_def.name()?; | 121 | let name = trait_def.name()?; |
122 | let ptr = LocalSyntaxPtr::new(trait_def.syntax()); | 122 | let ptr = LocalSyntaxPtr::new(trait_def.syntax()); |
@@ -152,11 +152,11 @@ pub struct MacroExpansion { | |||
152 | impl MacroExpansion { | 152 | impl MacroExpansion { |
153 | // FIXME: does not really make sense, macro expansion is not neccessary a | 153 | // FIXME: does not really make sense, macro expansion is not neccessary a |
154 | // whole file. See `MacroExpansion::ptr` as well. | 154 | // whole file. See `MacroExpansion::ptr` as well. |
155 | pub(crate) fn file(&self) -> SourceFileNode { | 155 | pub(crate) fn file(&self) -> TreePtr<SourceFile> { |
156 | SourceFileNode::parse(&self.text) | 156 | SourceFile::parse(&self.text) |
157 | } | 157 | } |
158 | 158 | ||
159 | pub fn syntax(&self) -> SyntaxNode { | 159 | pub fn syntax(&self) -> TreePtr<SyntaxNode> { |
160 | self.ptr.resolve(&self.file()) | 160 | self.ptr.resolve(&self.file()) |
161 | } | 161 | } |
162 | /// Maps range in the source code to the range in the expanded code. | 162 | /// Maps range in the source code to the range in the expanded code. |
@@ -191,8 +191,7 @@ pub(crate) fn expand_macro_invocation( | |||
191 | ) -> Option<Arc<MacroExpansion>> { | 191 | ) -> Option<Arc<MacroExpansion>> { |
192 | let loc = invoc.loc(db); | 192 | let loc = invoc.loc(db); |
193 | let syntax = db.file_item(loc.source_item_id); | 193 | let syntax = db.file_item(loc.source_item_id); |
194 | let syntax = syntax.borrowed(); | 194 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); |
195 | let macro_call = ast::MacroCall::cast(syntax).unwrap(); | ||
196 | 195 | ||
197 | let (def, input) = MacroDef::from_call(macro_call)?; | 196 | let (def, input) = MacroDef::from_call(macro_call)?; |
198 | def.expand(input).map(Arc::new) | 197 | def.expand(input).map(Arc::new) |
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index c7a442319..91aab5c74 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -5,9 +5,9 @@ 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, Cancelable, SourceRoot}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | SyntaxNode, TreePtr, | ||
8 | algo::generate, | 9 | algo::generate, |
9 | ast::{self, AstNode, NameOwner}, | 10 | ast::{self, AstNode, NameOwner}, |
10 | SyntaxNode, | ||
11 | }; | 11 | }; |
12 | use ra_arena::{Arena, RawId, impl_arena_id}; | 12 | use ra_arena::{Arena, RawId, impl_arena_id}; |
13 | 13 | ||
@@ -19,12 +19,11 @@ impl ModuleSource { | |||
19 | source_item_id: SourceItemId, | 19 | source_item_id: SourceItemId, |
20 | ) -> ModuleSource { | 20 | ) -> ModuleSource { |
21 | let module_syntax = db.file_item(source_item_id); | 21 | let module_syntax = db.file_item(source_item_id); |
22 | let module_syntax = module_syntax.borrowed(); | 22 | if let Some(source_file) = ast::SourceFile::cast(&module_syntax) { |
23 | if let Some(source_file) = ast::SourceFile::cast(module_syntax) { | 23 | ModuleSource::SourceFile(source_file.to_owned()) |
24 | ModuleSource::SourceFile(source_file.owned()) | 24 | } else if let Some(module) = ast::Module::cast(&module_syntax) { |
25 | } else if let Some(module) = ast::Module::cast(module_syntax) { | ||
26 | assert!(module.item_list().is_some(), "expected inline module"); | 25 | assert!(module.item_list().is_some(), "expected inline module"); |
27 | ModuleSource::Module(module.owned()) | 26 | ModuleSource::Module(module.to_owned()) |
28 | } else { | 27 | } else { |
29 | panic!("expected file or inline module") | 28 | panic!("expected file or inline module") |
30 | } | 29 | } |
@@ -49,19 +48,18 @@ impl Submodule { | |||
49 | let module_source = ModuleSource::from_source_item_id(db, source); | 48 | let module_source = ModuleSource::from_source_item_id(db, source); |
50 | let submodules = match module_source { | 49 | let submodules = match module_source { |
51 | ModuleSource::SourceFile(source_file) => { | 50 | ModuleSource::SourceFile(source_file) => { |
52 | collect_submodules(file_id, &file_items, source_file.borrowed()) | 51 | collect_submodules(file_id, &file_items, &*source_file) |
53 | } | 52 | } |
54 | ModuleSource::Module(module) => { | 53 | ModuleSource::Module(module) => { |
55 | let module = module.borrowed(); | ||
56 | collect_submodules(file_id, &file_items, module.item_list().unwrap()) | 54 | collect_submodules(file_id, &file_items, module.item_list().unwrap()) |
57 | } | 55 | } |
58 | }; | 56 | }; |
59 | return Ok(Arc::new(submodules)); | 57 | return Ok(Arc::new(submodules)); |
60 | 58 | ||
61 | fn collect_submodules<'a>( | 59 | fn collect_submodules( |
62 | file_id: HirFileId, | 60 | file_id: HirFileId, |
63 | file_items: &SourceFileItems, | 61 | file_items: &SourceFileItems, |
64 | root: impl ast::ModuleItemOwner<'a>, | 62 | root: &impl ast::ModuleItemOwner, |
65 | ) -> Vec<Submodule> { | 63 | ) -> Vec<Submodule> { |
66 | modules(root) | 64 | modules(root) |
67 | .map(|(name, m)| Submodule { | 65 | .map(|(name, m)| Submodule { |
@@ -120,8 +118,8 @@ impl ModuleTree { | |||
120 | source_root: SourceRootId, | 118 | source_root: SourceRootId, |
121 | ) -> Cancelable<Arc<ModuleTree>> { | 119 | ) -> Cancelable<Arc<ModuleTree>> { |
122 | db.check_canceled()?; | 120 | db.check_canceled()?; |
123 | let res = create_module_tree(db, source_root)?; | 121 | let res = create_module_tree(db, source_root); |
124 | Ok(Arc::new(res)) | 122 | Ok(Arc::new(res?)) |
125 | } | 123 | } |
126 | 124 | ||
127 | 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 { |
@@ -172,14 +170,14 @@ impl ModuleId { | |||
172 | self, | 170 | self, |
173 | tree: &ModuleTree, | 171 | tree: &ModuleTree, |
174 | db: &impl HirDatabase, | 172 | db: &impl HirDatabase, |
175 | ) -> Vec<(SyntaxNode, Problem)> { | 173 | ) -> Vec<(TreePtr<SyntaxNode>, Problem)> { |
176 | tree.mods[self] | 174 | tree.mods[self] |
177 | .children | 175 | .children |
178 | .iter() | 176 | .iter() |
179 | .filter_map(|&link| { | 177 | .filter_map(|&link| { |
180 | let p = tree.links[link].problem.clone()?; | 178 | let p = tree.links[link].problem.clone()?; |
181 | let s = link.source(tree, db); | 179 | let s = link.source(tree, db); |
182 | let s = s.borrowed().name().unwrap().syntax().owned(); | 180 | let s = s.name().unwrap().syntax().to_owned(); |
183 | Some((s, p)) | 181 | Some((s, p)) |
184 | }) | 182 | }) |
185 | .collect() | 183 | .collect() |
@@ -193,11 +191,9 @@ impl LinkId { | |||
193 | pub(crate) fn name(self, tree: &ModuleTree) -> &Name { | 191 | pub(crate) fn name(self, tree: &ModuleTree) -> &Name { |
194 | &tree.links[self].name | 192 | &tree.links[self].name |
195 | } | 193 | } |
196 | pub(crate) fn source(self, tree: &ModuleTree, db: &impl HirDatabase) -> ast::ModuleNode { | 194 | pub(crate) fn source(self, tree: &ModuleTree, db: &impl HirDatabase) -> TreePtr<ast::Module> { |
197 | let syntax_node = db.file_item(tree.links[self].source); | 195 | let syntax_node = db.file_item(tree.links[self].source); |
198 | ast::ModuleNode::cast(syntax_node.borrowed()) | 196 | ast::Module::cast(&syntax_node).unwrap().to_owned() |
199 | .unwrap() | ||
200 | .owned() | ||
201 | } | 197 | } |
202 | } | 198 | } |
203 | 199 | ||
@@ -213,12 +209,10 @@ impl ModuleTree { | |||
213 | } | 209 | } |
214 | } | 210 | } |
215 | 211 | ||
216 | fn modules<'a>( | 212 | fn modules(root: &impl ast::ModuleItemOwner) -> impl Iterator<Item = (Name, &ast::Module)> { |
217 | root: impl ast::ModuleItemOwner<'a>, | ||
218 | ) -> impl Iterator<Item = (Name, ast::Module<'a>)> { | ||
219 | root.items() | 213 | root.items() |
220 | .filter_map(|item| match item { | 214 | .filter_map(|item| match item.kind() { |
221 | ast::ModuleItem::Module(m) => Some(m), | 215 | ast::ModuleItemKind::Module(m) => Some(m), |
222 | _ => None, | 216 | _ => None, |
223 | }) | 217 | }) |
224 | .filter_map(|module| { | 218 | .filter_map(|module| { |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index 90229bc54..3e6ce8b95 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs | |||
@@ -59,6 +59,9 @@ impl Name { | |||
59 | "u128" => KnownName::U128, | 59 | "u128" => KnownName::U128, |
60 | "f32" => KnownName::F32, | 60 | "f32" => KnownName::F32, |
61 | "f64" => KnownName::F64, | 61 | "f64" => KnownName::F64, |
62 | "bool" => KnownName::Bool, | ||
63 | "char" => KnownName::Char, | ||
64 | "str" => KnownName::Str, | ||
62 | "Self" => KnownName::SelfType, | 65 | "Self" => KnownName::SelfType, |
63 | "self" => KnownName::SelfParam, | 66 | "self" => KnownName::SelfParam, |
64 | _ => return None, | 67 | _ => return None, |
@@ -71,15 +74,15 @@ pub(crate) trait AsName { | |||
71 | fn as_name(&self) -> Name; | 74 | fn as_name(&self) -> Name; |
72 | } | 75 | } |
73 | 76 | ||
74 | impl AsName for ast::NameRef<'_> { | 77 | impl AsName for ast::NameRef { |
75 | fn as_name(&self) -> Name { | 78 | fn as_name(&self) -> Name { |
76 | Name::new(self.text()) | 79 | Name::new(self.text().clone()) |
77 | } | 80 | } |
78 | } | 81 | } |
79 | 82 | ||
80 | impl AsName for ast::Name<'_> { | 83 | impl AsName for ast::Name { |
81 | fn as_name(&self) -> Name { | 84 | fn as_name(&self) -> Name { |
82 | Name::new(self.text()) | 85 | Name::new(self.text().clone()) |
83 | } | 86 | } |
84 | } | 87 | } |
85 | 88 | ||
@@ -113,6 +116,10 @@ pub(crate) enum KnownName { | |||
113 | F32, | 116 | F32, |
114 | F64, | 117 | F64, |
115 | 118 | ||
119 | Bool, | ||
120 | Char, | ||
121 | Str, | ||
122 | |||
116 | SelfType, | 123 | SelfType, |
117 | SelfParam, | 124 | SelfParam, |
118 | } | 125 | } |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index bd66b5d2c..4181bf4b8 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -103,7 +103,7 @@ impl NamedImport { | |||
103 | item_id: Some(self.file_item_id), | 103 | item_id: Some(self.file_item_id), |
104 | }; | 104 | }; |
105 | let syntax = db.file_item(source_item_id); | 105 | let syntax = db.file_item(source_item_id); |
106 | let offset = syntax.borrowed().range().start(); | 106 | let offset = syntax.range().start(); |
107 | self.relative_range + offset | 107 | self.relative_range + offset |
108 | } | 108 | } |
109 | } | 109 | } |
@@ -215,45 +215,45 @@ impl InputModuleItems { | |||
215 | &mut self, | 215 | &mut self, |
216 | file_id: HirFileId, | 216 | file_id: HirFileId, |
217 | file_items: &SourceFileItems, | 217 | file_items: &SourceFileItems, |
218 | item: ast::ModuleItem, | 218 | item: &ast::ModuleItem, |
219 | ) -> Option<()> { | 219 | ) -> Option<()> { |
220 | match item { | 220 | match item.kind() { |
221 | ast::ModuleItem::StructDef(it) => { | 221 | ast::ModuleItemKind::StructDef(it) => { |
222 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 222 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
223 | } | 223 | } |
224 | ast::ModuleItem::EnumDef(it) => { | 224 | ast::ModuleItemKind::EnumDef(it) => { |
225 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 225 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
226 | } | 226 | } |
227 | ast::ModuleItem::FnDef(it) => { | 227 | ast::ModuleItemKind::FnDef(it) => { |
228 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 228 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
229 | } | 229 | } |
230 | ast::ModuleItem::TraitDef(it) => { | 230 | ast::ModuleItemKind::TraitDef(it) => { |
231 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 231 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
232 | } | 232 | } |
233 | ast::ModuleItem::TypeDef(it) => { | 233 | ast::ModuleItemKind::TypeDef(it) => { |
234 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 234 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
235 | } | 235 | } |
236 | ast::ModuleItem::ImplBlock(_) => { | 236 | ast::ModuleItemKind::ImplBlock(_) => { |
237 | // impls don't define items | 237 | // impls don't define items |
238 | } | 238 | } |
239 | ast::ModuleItem::UseItem(it) => self.add_use_item(file_items, it), | 239 | ast::ModuleItemKind::UseItem(it) => self.add_use_item(file_items, it), |
240 | ast::ModuleItem::ExternCrateItem(_) => { | 240 | ast::ModuleItemKind::ExternCrateItem(_) => { |
241 | // TODO | 241 | // TODO |
242 | } | 242 | } |
243 | ast::ModuleItem::ConstDef(it) => { | 243 | ast::ModuleItemKind::ConstDef(it) => { |
244 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 244 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
245 | } | 245 | } |
246 | ast::ModuleItem::StaticDef(it) => { | 246 | ast::ModuleItemKind::StaticDef(it) => { |
247 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 247 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
248 | } | 248 | } |
249 | ast::ModuleItem::Module(it) => { | 249 | ast::ModuleItemKind::Module(it) => { |
250 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 250 | self.items.push(ModuleItem::new(file_id, file_items, it)?) |
251 | } | 251 | } |
252 | } | 252 | } |
253 | Some(()) | 253 | Some(()) |
254 | } | 254 | } |
255 | 255 | ||
256 | fn add_use_item(&mut self, file_items: &SourceFileItems, item: ast::UseItem) { | 256 | fn add_use_item(&mut self, file_items: &SourceFileItems, item: &ast::UseItem) { |
257 | let file_item_id = file_items.id_of_unchecked(item.syntax()); | 257 | let file_item_id = file_items.id_of_unchecked(item.syntax()); |
258 | let start_offset = item.syntax().range().start(); | 258 | let start_offset = item.syntax().range().start(); |
259 | Path::expand_use_item(item, |path, range| { | 259 | Path::expand_use_item(item, |path, range| { |
@@ -270,10 +270,10 @@ impl InputModuleItems { | |||
270 | } | 270 | } |
271 | 271 | ||
272 | impl ModuleItem { | 272 | impl ModuleItem { |
273 | fn new<'a>( | 273 | fn new( |
274 | file_id: HirFileId, | 274 | file_id: HirFileId, |
275 | file_items: &SourceFileItems, | 275 | file_items: &SourceFileItems, |
276 | item: impl ast::NameOwner<'a>, | 276 | item: &impl ast::NameOwner, |
277 | ) -> Option<ModuleItem> { | 277 | ) -> Option<ModuleItem> { |
278 | let name = item.name()?.as_name(); | 278 | let name = item.name()?.as_name(); |
279 | let kind = item.syntax().kind(); | 279 | let kind = item.syntax().kind(); |
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index dcf4cf8b6..6f0b0da97 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -18,14 +18,14 @@ pub enum PathKind { | |||
18 | 18 | ||
19 | impl Path { | 19 | impl Path { |
20 | /// Calls `cb` with all paths, represented by this use item. | 20 | /// Calls `cb` with all paths, represented by this use item. |
21 | pub fn expand_use_item(item: ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) { | 21 | pub fn expand_use_item(item: &ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) { |
22 | if let Some(tree) = item.use_tree() { | 22 | if let Some(tree) = item.use_tree() { |
23 | expand_use_tree(None, tree, &mut cb); | 23 | expand_use_tree(None, tree, &mut cb); |
24 | } | 24 | } |
25 | } | 25 | } |
26 | 26 | ||
27 | /// Converts an `ast::Path` to `Path`. Works with use trees. | 27 | /// Converts an `ast::Path` to `Path`. Works with use trees. |
28 | pub fn from_ast(mut path: ast::Path) -> Option<Path> { | 28 | pub fn from_ast(mut path: &ast::Path) -> Option<Path> { |
29 | let mut kind = PathKind::Plain; | 29 | let mut kind = PathKind::Plain; |
30 | let mut segments = Vec::new(); | 30 | let mut segments = Vec::new(); |
31 | loop { | 31 | loop { |
@@ -53,7 +53,7 @@ impl Path { | |||
53 | segments.reverse(); | 53 | segments.reverse(); |
54 | return Some(Path { kind, segments }); | 54 | return Some(Path { kind, segments }); |
55 | 55 | ||
56 | fn qualifier(path: ast::Path) -> Option<ast::Path> { | 56 | fn qualifier(path: &ast::Path) -> Option<&ast::Path> { |
57 | if let Some(q) = path.qualifier() { | 57 | if let Some(q) = path.qualifier() { |
58 | return Some(q); | 58 | return Some(q); |
59 | } | 59 | } |
@@ -66,7 +66,7 @@ impl Path { | |||
66 | } | 66 | } |
67 | 67 | ||
68 | /// Converts an `ast::NameRef` into a single-identifier `Path`. | 68 | /// Converts an `ast::NameRef` into a single-identifier `Path`. |
69 | pub fn from_name_ref(name_ref: ast::NameRef) -> Path { | 69 | pub fn from_name_ref(name_ref: &ast::NameRef) -> Path { |
70 | name_ref.as_name().into() | 70 | name_ref.as_name().into() |
71 | } | 71 | } |
72 | 72 | ||
@@ -100,7 +100,7 @@ impl From<Name> for Path { | |||
100 | 100 | ||
101 | fn expand_use_tree( | 101 | fn expand_use_tree( |
102 | prefix: Option<Path>, | 102 | prefix: Option<Path>, |
103 | tree: ast::UseTree, | 103 | tree: &ast::UseTree, |
104 | cb: &mut impl FnMut(Path, Option<TextRange>), | 104 | cb: &mut impl FnMut(Path, Option<TextRange>), |
105 | ) { | 105 | ) { |
106 | if let Some(use_tree_list) = tree.use_tree_list() { | 106 | if let Some(use_tree_list) = tree.use_tree_list() { |
@@ -146,7 +146,7 @@ fn expand_use_tree( | |||
146 | } | 146 | } |
147 | } | 147 | } |
148 | 148 | ||
149 | fn convert_path(prefix: Option<Path>, path: ast::Path) -> Option<Path> { | 149 | fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> { |
150 | let prefix = if let Some(qual) = path.qualifier() { | 150 | let prefix = if let Some(qual) = path.qualifier() { |
151 | Some(convert_path(prefix, qual)?) | 151 | Some(convert_path(prefix, qual)?) |
152 | } else { | 152 | } else { |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index 8f2c40669..380ea5410 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -5,7 +5,7 @@ use std::{ | |||
5 | 5 | ||
6 | use rustc_hash::FxHashMap; | 6 | use rustc_hash::FxHashMap; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | AstNode, SyntaxNode, | 8 | AstNode, SyntaxNode, TreePtr, |
9 | ast::{self, ModuleItemOwner} | 9 | ast::{self, ModuleItemOwner} |
10 | }; | 10 | }; |
11 | use ra_db::{SourceRootId, Cancelable,}; | 11 | use ra_db::{SourceRootId, Cancelable,}; |
@@ -31,30 +31,34 @@ pub(super) fn struct_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ar | |||
31 | assert!(def_loc.kind == DefKind::Struct); | 31 | assert!(def_loc.kind == DefKind::Struct); |
32 | let syntax = db.file_item(def_loc.source_item_id); | 32 | let syntax = db.file_item(def_loc.source_item_id); |
33 | let struct_def = | 33 | let struct_def = |
34 | ast::StructDef::cast(syntax.borrowed()).expect("struct def should point to StructDef node"); | 34 | ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node"); |
35 | Ok(Arc::new(StructData::new(struct_def.borrowed()))) | 35 | Ok(Arc::new(StructData::new(struct_def))) |
36 | } | 36 | } |
37 | 37 | ||
38 | pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> { | 38 | pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> { |
39 | let def_loc = def_id.loc(db); | 39 | let def_loc = def_id.loc(db); |
40 | assert!(def_loc.kind == DefKind::Enum); | 40 | assert!(def_loc.kind == DefKind::Enum); |
41 | let syntax = db.file_item(def_loc.source_item_id); | 41 | let syntax = db.file_item(def_loc.source_item_id); |
42 | let enum_def = | 42 | let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node"); |
43 | ast::EnumDef::cast(syntax.borrowed()).expect("enum def should point to EnumDef node"); | 43 | Ok(Arc::new(EnumData::new(enum_def))) |
44 | Ok(Arc::new(EnumData::new(enum_def.borrowed()))) | ||
45 | } | 44 | } |
46 | 45 | ||
47 | pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { | 46 | pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { |
48 | let source_file = db.hir_source_file(file_id); | 47 | let source_file = db.hir_source_file(file_id); |
49 | let source_file = source_file.borrowed(); | 48 | let res = SourceFileItems::new(file_id, &source_file); |
50 | let res = SourceFileItems::new(file_id, source_file); | ||
51 | Arc::new(res) | 49 | Arc::new(res) |
52 | } | 50 | } |
53 | 51 | ||
54 | pub(super) fn file_item(db: &impl HirDatabase, source_item_id: SourceItemId) -> SyntaxNode { | 52 | pub(super) fn file_item( |
53 | db: &impl HirDatabase, | ||
54 | source_item_id: SourceItemId, | ||
55 | ) -> TreePtr<SyntaxNode> { | ||
55 | match source_item_id.item_id { | 56 | match source_item_id.item_id { |
56 | Some(id) => db.file_items(source_item_id.file_id)[id].clone(), | 57 | Some(id) => db.file_items(source_item_id.file_id)[id].to_owned(), |
57 | None => db.hir_source_file(source_item_id.file_id).syntax().owned(), | 58 | None => db |
59 | .hir_source_file(source_item_id.file_id) | ||
60 | .syntax() | ||
61 | .to_owned(), | ||
58 | } | 62 | } |
59 | } | 63 | } |
60 | 64 | ||
@@ -88,7 +92,7 @@ pub(super) fn input_module_items( | |||
88 | let file_id = HirFileId::from(id); | 92 | let file_id = HirFileId::from(id); |
89 | let file_items = db.file_items(file_id); | 93 | let file_items = db.file_items(file_id); |
90 | //FIXME: expand recursively | 94 | //FIXME: expand recursively |
91 | for item in db.hir_source_file(file_id).borrowed().items() { | 95 | for item in db.hir_source_file(file_id).items() { |
92 | acc.add_item(file_id, &file_items, item); | 96 | acc.add_item(file_id, &file_items, item); |
93 | } | 97 | } |
94 | } | 98 | } |
@@ -98,9 +102,9 @@ pub(super) fn input_module_items( | |||
98 | 102 | ||
99 | let mut res = InputModuleItems::default(); | 103 | let mut res = InputModuleItems::default(); |
100 | match source { | 104 | match source { |
101 | ModuleSource::SourceFile(it) => fill(&mut res, &mut it.borrowed().items_with_macros()), | 105 | ModuleSource::SourceFile(it) => fill(&mut res, &mut it.items_with_macros()), |
102 | ModuleSource::Module(it) => { | 106 | ModuleSource::Module(it) => { |
103 | if let Some(item_list) = it.borrowed().item_list() { | 107 | if let Some(item_list) = it.item_list() { |
104 | fill(&mut res, &mut item_list.items_with_macros()) | 108 | fill(&mut res, &mut item_list.items_with_macros()) |
105 | } | 109 | } |
106 | } | 110 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 4c14650c0..59a803761 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -8,7 +8,7 @@ | |||
8 | use ra_db::{FileId, FilePosition, Cancelable}; | 8 | use ra_db::{FileId, FilePosition, Cancelable}; |
9 | use ra_editor::find_node_at_offset; | 9 | use ra_editor::find_node_at_offset; |
10 | use ra_syntax::{ | 10 | use ra_syntax::{ |
11 | SmolStr, TextRange, SyntaxNodeRef, | 11 | SmolStr, TextRange, SyntaxNode, |
12 | ast::{self, AstNode, NameOwner}, | 12 | ast::{self, AstNode, NameOwner}, |
13 | }; | 13 | }; |
14 | 14 | ||
@@ -30,7 +30,7 @@ pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable | |||
30 | pub fn module_from_declaration( | 30 | 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 | ) -> Cancelable<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(); |
@@ -60,7 +60,7 @@ pub fn module_from_position( | |||
60 | fn module_from_inline( | 60 | fn module_from_inline( |
61 | db: &impl HirDatabase, | 61 | db: &impl HirDatabase, |
62 | file_id: FileId, | 62 | file_id: FileId, |
63 | module: ast::Module, | 63 | module: &ast::Module, |
64 | ) -> Cancelable<Option<Module>> { | 64 | ) -> Cancelable<Option<Module>> { |
65 | assert!(!module.has_semi()); | 65 | assert!(!module.has_semi()); |
66 | let file_id = file_id.into(); | 66 | let file_id = file_id.into(); |
@@ -77,7 +77,7 @@ fn module_from_inline( | |||
77 | pub fn module_from_child_node( | 77 | pub fn module_from_child_node( |
78 | db: &impl HirDatabase, | 78 | db: &impl HirDatabase, |
79 | file_id: FileId, | 79 | file_id: FileId, |
80 | child: SyntaxNodeRef, | 80 | child: &SyntaxNode, |
81 | ) -> Cancelable<Option<Module>> { | 81 | ) -> Cancelable<Option<Module>> { |
82 | if let Some(m) = child | 82 | if let Some(m) = child |
83 | .ancestors() | 83 | .ancestors() |
@@ -112,7 +112,7 @@ pub fn function_from_position( | |||
112 | pub fn function_from_source( | 112 | pub fn function_from_source( |
113 | db: &impl HirDatabase, | 113 | db: &impl HirDatabase, |
114 | file_id: FileId, | 114 | file_id: FileId, |
115 | fn_def: ast::FnDef, | 115 | fn_def: &ast::FnDef, |
116 | ) -> Cancelable<Option<Function>> { | 116 | ) -> Cancelable<Option<Function>> { |
117 | let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?); | 117 | let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?); |
118 | let res = function_from_module(db, &module, fn_def); | 118 | let res = function_from_module(db, &module, fn_def); |
@@ -122,7 +122,7 @@ pub fn function_from_source( | |||
122 | pub fn function_from_module( | 122 | pub fn function_from_module( |
123 | db: &impl HirDatabase, | 123 | db: &impl HirDatabase, |
124 | module: &Module, | 124 | module: &Module, |
125 | fn_def: ast::FnDef, | 125 | fn_def: &ast::FnDef, |
126 | ) -> Function { | 126 | ) -> Function { |
127 | let loc = module.def_id.loc(db); | 127 | let loc = module.def_id.loc(db); |
128 | let file_id = loc.source_item_id.file_id; | 128 | let file_id = loc.source_item_id.file_id; |
@@ -144,7 +144,7 @@ pub fn function_from_module( | |||
144 | pub fn function_from_child_node( | 144 | pub fn function_from_child_node( |
145 | db: &impl HirDatabase, | 145 | db: &impl HirDatabase, |
146 | file_id: FileId, | 146 | file_id: FileId, |
147 | node: SyntaxNodeRef, | 147 | node: &SyntaxNode, |
148 | ) -> Cancelable<Option<Function>> { | 148 | ) -> Cancelable<Option<Function>> { |
149 | let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast)); | 149 | let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast)); |
150 | function_from_source(db, file_id, fn_def) | 150 | function_from_source(db, file_id, fn_def) |
@@ -170,15 +170,14 @@ pub fn macro_symbols( | |||
170 | if let Some(exp) = db.expand_macro_invocation(macro_call_id) { | 170 | if let Some(exp) = db.expand_macro_invocation(macro_call_id) { |
171 | let loc = macro_call_id.loc(db); | 171 | let loc = macro_call_id.loc(db); |
172 | let syntax = db.file_item(loc.source_item_id); | 172 | let syntax = db.file_item(loc.source_item_id); |
173 | let syntax = syntax.borrowed(); | 173 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); |
174 | let macro_call = ast::MacroCall::cast(syntax).unwrap(); | ||
175 | let off = macro_call.token_tree().unwrap().syntax().range().start(); | 174 | let off = macro_call.token_tree().unwrap().syntax().range().start(); |
176 | let file = exp.file(); | 175 | let file = exp.file(); |
177 | for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) { | 176 | for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) { |
178 | if let Some(name) = trait_def.name() { | 177 | if let Some(name) = trait_def.name() { |
179 | let dst_range = name.syntax().range(); | 178 | let dst_range = name.syntax().range(); |
180 | if let Some(src_range) = exp.map_range_back(dst_range) { | 179 | if let Some(src_range) = exp.map_range_back(dst_range) { |
181 | res.push((name.text(), src_range + off)) | 180 | res.push((name.text().clone(), src_range + off)) |
182 | } | 181 | } |
183 | } | 182 | } |
184 | } | 183 | } |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index bba8527b7..8adeedddb 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -308,7 +308,13 @@ impl Ty { | |||
308 | path: &Path, | 308 | path: &Path, |
309 | ) -> Cancelable<Self> { | 309 | ) -> Cancelable<Self> { |
310 | if let Some(name) = path.as_ident() { | 310 | if let Some(name) = path.as_ident() { |
311 | if let Some(int_ty) = primitive::IntTy::from_name(name) { | 311 | if let Some(KnownName::Bool) = name.as_known_name() { |
312 | return Ok(Ty::Bool); | ||
313 | } else if let Some(KnownName::Char) = name.as_known_name() { | ||
314 | return Ok(Ty::Char); | ||
315 | } else if let Some(KnownName::Str) = name.as_known_name() { | ||
316 | return Ok(Ty::Str); | ||
317 | } else if let Some(int_ty) = primitive::IntTy::from_name(name) { | ||
312 | return Ok(Ty::Int(int_ty)); | 318 | return Ok(Ty::Int(int_ty)); |
313 | } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { | 319 | } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { |
314 | return Ok(Ty::Uint(uint_ty)); | 320 | return Ok(Ty::Uint(uint_ty)); |
@@ -527,9 +533,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
527 | return_ty: Ty, | 533 | return_ty: Ty, |
528 | } | 534 | } |
529 | 535 | ||
530 | // helper function that determines whether a binary operator | 536 | fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { |
531 | // always returns a boolean | ||
532 | fn is_boolean_operator(op: BinaryOp) -> bool { | ||
533 | match op { | 537 | match op { |
534 | BinaryOp::BooleanOr | 538 | BinaryOp::BooleanOr |
535 | | BinaryOp::BooleanAnd | 539 | | BinaryOp::BooleanAnd |
@@ -537,7 +541,70 @@ fn is_boolean_operator(op: BinaryOp) -> bool { | |||
537 | | BinaryOp::LesserEqualTest | 541 | | BinaryOp::LesserEqualTest |
538 | | BinaryOp::GreaterEqualTest | 542 | | BinaryOp::GreaterEqualTest |
539 | | BinaryOp::LesserTest | 543 | | BinaryOp::LesserTest |
540 | | BinaryOp::GreaterTest => true, | 544 | | BinaryOp::GreaterTest => Ty::Bool, |
545 | BinaryOp::Assignment | ||
546 | | BinaryOp::AddAssign | ||
547 | | BinaryOp::SubAssign | ||
548 | | BinaryOp::DivAssign | ||
549 | | BinaryOp::MulAssign | ||
550 | | BinaryOp::RemAssign | ||
551 | | BinaryOp::ShrAssign | ||
552 | | BinaryOp::ShlAssign | ||
553 | | BinaryOp::BitAndAssign | ||
554 | | BinaryOp::BitOrAssign | ||
555 | | BinaryOp::BitXorAssign => Ty::unit(), | ||
556 | BinaryOp::Addition | ||
557 | | BinaryOp::Subtraction | ||
558 | | BinaryOp::Multiplication | ||
559 | | BinaryOp::Division | ||
560 | | BinaryOp::Remainder | ||
561 | | BinaryOp::LeftShift | ||
562 | | BinaryOp::RightShift | ||
563 | | BinaryOp::BitwiseAnd | ||
564 | | BinaryOp::BitwiseOr | ||
565 | | BinaryOp::BitwiseXor => match rhs_ty { | ||
566 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => rhs_ty, | ||
567 | _ => Ty::Unknown, | ||
568 | }, | ||
569 | BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, | ||
570 | } | ||
571 | } | ||
572 | |||
573 | fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | ||
574 | match op { | ||
575 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, | ||
576 | BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { | ||
577 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, | ||
578 | _ => Ty::Unknown, | ||
579 | }, | ||
580 | BinaryOp::LesserEqualTest | ||
581 | | BinaryOp::GreaterEqualTest | ||
582 | | BinaryOp::LesserTest | ||
583 | | BinaryOp::GreaterTest | ||
584 | | BinaryOp::AddAssign | ||
585 | | BinaryOp::SubAssign | ||
586 | | BinaryOp::DivAssign | ||
587 | | BinaryOp::MulAssign | ||
588 | | BinaryOp::RemAssign | ||
589 | | BinaryOp::ShrAssign | ||
590 | | BinaryOp::ShlAssign | ||
591 | | BinaryOp::BitAndAssign | ||
592 | | BinaryOp::BitOrAssign | ||
593 | | BinaryOp::BitXorAssign | ||
594 | | BinaryOp::Addition | ||
595 | | BinaryOp::Subtraction | ||
596 | | BinaryOp::Multiplication | ||
597 | | BinaryOp::Division | ||
598 | | BinaryOp::Remainder | ||
599 | | BinaryOp::LeftShift | ||
600 | | BinaryOp::RightShift | ||
601 | | BinaryOp::BitwiseAnd | ||
602 | | BinaryOp::BitwiseOr | ||
603 | | BinaryOp::BitwiseXor => match lhs_ty { | ||
604 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty, | ||
605 | _ => Ty::Unknown, | ||
606 | }, | ||
607 | _ => Ty::Unknown, | ||
541 | } | 608 | } |
542 | } | 609 | } |
543 | 610 | ||
@@ -889,20 +956,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
889 | } | 956 | } |
890 | Expr::BinaryOp { lhs, rhs, op } => match op { | 957 | Expr::BinaryOp { lhs, rhs, op } => match op { |
891 | Some(op) => { | 958 | Some(op) => { |
892 | let subtype_expectation = match op { | 959 | let lhs_expectation = match op { |
893 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { | 960 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { |
894 | Expectation::has_type(Ty::Bool) | 961 | Expectation::has_type(Ty::Bool) |
895 | } | 962 | } |
896 | _ => Expectation::none(), | 963 | _ => Expectation::none(), |
897 | }; | 964 | }; |
898 | let _lhs_ty = self.infer_expr(*lhs, &subtype_expectation)?; | 965 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?; |
899 | let _rhs_ty = self.infer_expr(*rhs, &subtype_expectation)?; | 966 | // TODO: find implementation of trait corresponding to operation |
900 | 967 | // symbol and resolve associated `Output` type | |
901 | if is_boolean_operator(*op) { | 968 | let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); |
902 | Ty::Bool | 969 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?; |
903 | } else { | 970 | |
904 | Ty::Unknown | 971 | // TODO: similar as above, return ty is often associated trait type |
905 | } | 972 | binary_op_return_ty(*op, rhs_ty) |
906 | } | 973 | } |
907 | _ => Ty::Unknown, | 974 | _ => Ty::Unknown, |
908 | }, | 975 | }, |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index e6c7e225b..2749d740c 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -157,7 +157,7 @@ impl S { | |||
157 | } | 157 | } |
158 | 158 | ||
159 | #[test] | 159 | #[test] |
160 | fn infer_boolean_op() { | 160 | fn infer_binary_op() { |
161 | check_inference( | 161 | check_inference( |
162 | r#" | 162 | r#" |
163 | fn f(x: bool) -> i32 { | 163 | fn f(x: bool) -> i32 { |
@@ -168,15 +168,18 @@ fn test() { | |||
168 | let x = a && b; | 168 | let x = a && b; |
169 | let y = true || false; | 169 | let y = true || false; |
170 | let z = x == y; | 170 | let z = x == y; |
171 | let h = CONST_1 <= CONST_2; | 171 | let minus_forty: isize = -40isize; |
172 | let h = minus_forty <= CONST_2; | ||
172 | let c = f(z || y) + 5; | 173 | let c = f(z || y) + 5; |
173 | let d = b; | 174 | let d = b; |
174 | let e = 3i32 && "hello world"; | 175 | let g = minus_forty ^= i; |
176 | let ten: usize = 10; | ||
177 | let ten_is_eleven = ten == some_num; | ||
175 | 178 | ||
176 | 10 < 3 | 179 | ten < 3 |
177 | } | 180 | } |
178 | "#, | 181 | "#, |
179 | "boolean_op.txt", | 182 | "binary_op.txt", |
180 | ); | 183 | ); |
181 | } | 184 | } |
182 | 185 | ||
diff --git a/crates/ra_hir/src/ty/tests/data/basics.txt b/crates/ra_hir/src/ty/tests/data/basics.txt index 8ea244ba8..ac7faae0a 100644 --- a/crates/ra_hir/src/ty/tests/data/basics.txt +++ b/crates/ra_hir/src/ty/tests/data/basics.txt | |||
@@ -1,12 +1,12 @@ | |||
1 | [9; 10) 'a': u32 | 1 | [9; 10) 'a': u32 |
2 | [17; 18) 'b': isize | 2 | [17; 18) 'b': isize |
3 | [27; 28) 'c': ! | 3 | [27; 28) 'c': ! |
4 | [33; 34) 'd': &[unknown] | 4 | [33; 34) 'd': &str |
5 | [42; 121) '{ ...f32; }': () | 5 | [42; 121) '{ ...f32; }': () |
6 | [48; 49) 'a': u32 | 6 | [48; 49) 'a': u32 |
7 | [55; 56) 'b': isize | 7 | [55; 56) 'b': isize |
8 | [62; 63) 'c': ! | 8 | [62; 63) 'c': ! |
9 | [69; 70) 'd': &[unknown] | 9 | [69; 70) 'd': &str |
10 | [76; 82) '1usize': [unknown] | 10 | [76; 82) '1usize': [unknown] |
11 | [88; 94) '1isize': [unknown] | 11 | [88; 94) '1isize': [unknown] |
12 | [100; 106) '"test"': [unknown] | 12 | [100; 106) '"test"': [unknown] |
diff --git a/crates/ra_hir/src/ty/tests/data/binary_op.txt b/crates/ra_hir/src/ty/tests/data/binary_op.txt new file mode 100644 index 000000000..0fb9dc097 --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/binary_op.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | [6; 7) 'x': bool | ||
2 | [22; 34) '{ 0i32 }': i32 | ||
3 | [28; 32) '0i32': i32 | ||
4 | [46; 342) '{ ... < 3 }': bool | ||
5 | [56; 57) 'x': bool | ||
6 | [60; 61) 'a': bool | ||
7 | [60; 66) 'a && b': bool | ||
8 | [65; 66) 'b': bool | ||
9 | [76; 77) 'y': bool | ||
10 | [80; 84) 'true': bool | ||
11 | [80; 93) 'true || false': bool | ||
12 | [88; 93) 'false': bool | ||
13 | [103; 104) 'z': bool | ||
14 | [107; 108) 'x': bool | ||
15 | [107; 113) 'x == y': bool | ||
16 | [112; 113) 'y': bool | ||
17 | [123; 134) 'minus_forty': isize | ||
18 | [144; 152) '-40isize': isize | ||
19 | [145; 152) '40isize': [unknown] | ||
20 | [162; 163) 'h': bool | ||
21 | [166; 177) 'minus_forty': isize | ||
22 | [166; 188) 'minus_...ONST_2': bool | ||
23 | [181; 188) 'CONST_2': isize | ||
24 | [198; 199) 'c': i32 | ||
25 | [202; 203) 'f': fn(bool,) -> i32 | ||
26 | [202; 211) 'f(z || y)': i32 | ||
27 | [202; 215) 'f(z || y) + 5': i32 | ||
28 | [204; 205) 'z': bool | ||
29 | [204; 210) 'z || y': bool | ||
30 | [209; 210) 'y': bool | ||
31 | [214; 215) '5': i32 | ||
32 | [225; 226) 'd': [unknown] | ||
33 | [229; 230) 'b': [unknown] | ||
34 | [240; 241) 'g': () | ||
35 | [244; 255) 'minus_forty': isize | ||
36 | [244; 260) 'minus_...y ^= i': () | ||
37 | [259; 260) 'i': isize | ||
38 | [270; 273) 'ten': usize | ||
39 | [283; 285) '10': usize | ||
40 | [295; 308) 'ten_is_eleven': bool | ||
41 | [311; 314) 'ten': usize | ||
42 | [311; 326) 'ten == some_num': bool | ||
43 | [318; 326) 'some_num': usize | ||
44 | [333; 336) 'ten': usize | ||
45 | [333; 340) 'ten < 3': bool | ||
46 | [339; 340) '3': usize | ||
diff --git a/crates/ra_hir/src/ty/tests/data/boolean_op.txt b/crates/ra_hir/src/ty/tests/data/boolean_op.txt deleted file mode 100644 index cce8d68fb..000000000 --- a/crates/ra_hir/src/ty/tests/data/boolean_op.txt +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [6; 7) 'x': [unknown] | ||
2 | [22; 34) '{ 0i32 }': i32 | ||
3 | [28; 32) '0i32': i32 | ||
4 | [46; 237) '{ ... < 3 }': bool | ||
5 | [56; 57) 'x': bool | ||
6 | [60; 61) 'a': bool | ||
7 | [60; 66) 'a && b': bool | ||
8 | [65; 66) 'b': bool | ||
9 | [76; 77) 'y': bool | ||
10 | [80; 84) 'true': bool | ||
11 | [80; 93) 'true || false': bool | ||
12 | [88; 93) 'false': bool | ||
13 | [103; 104) 'z': bool | ||
14 | [107; 108) 'x': bool | ||
15 | [107; 113) 'x == y': bool | ||
16 | [112; 113) 'y': bool | ||
17 | [123; 124) 'h': bool | ||
18 | [127; 134) 'CONST_1': [unknown] | ||
19 | [127; 145) 'CONST_...ONST_2': bool | ||
20 | [138; 145) 'CONST_2': [unknown] | ||
21 | [155; 156) 'c': [unknown] | ||
22 | [159; 172) 'f(z || y) + 5': [unknown] | ||
23 | [182; 183) 'd': [unknown] | ||
24 | [186; 187) 'b': [unknown] | ||
25 | [197; 198) 'e': bool | ||
26 | [201; 205) '3i32': bool | ||
27 | [201; 222) '3i32 &...world"': bool | ||
28 | [209; 222) '"hello world"': bool | ||
29 | [229; 231) '10': [unknown] | ||
30 | [229; 235) '10 < 3': bool | ||
31 | [234; 235) '3': [unknown] | ||
diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs index 859f330c2..c9db4e0a5 100644 --- a/crates/ra_hir/src/type_ref.rs +++ b/crates/ra_hir/src/type_ref.rs | |||
@@ -56,9 +56,9 @@ pub enum TypeRef { | |||
56 | 56 | ||
57 | impl TypeRef { | 57 | impl TypeRef { |
58 | /// Converts an `ast::TypeRef` to a `hir::TypeRef`. | 58 | /// Converts an `ast::TypeRef` to a `hir::TypeRef`. |
59 | pub(crate) fn from_ast(node: ast::TypeRef) -> Self { | 59 | pub(crate) fn from_ast(node: &ast::TypeRef) -> Self { |
60 | use ra_syntax::ast::TypeRef::*; | 60 | use ra_syntax::ast::TypeRefKind::*; |
61 | match node { | 61 | match node.kind() { |
62 | ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), | 62 | ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), |
63 | TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()), | 63 | TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()), |
64 | NeverType(..) => TypeRef::Never, | 64 | NeverType(..) => TypeRef::Never, |
@@ -100,7 +100,7 @@ impl TypeRef { | |||
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
103 | pub(crate) fn from_ast_opt(node: Option<ast::TypeRef>) -> Self { | 103 | pub(crate) fn from_ast_opt(node: Option<&ast::TypeRef>) -> Self { |
104 | if let Some(node) = node { | 104 | if let Some(node) = node { |
105 | TypeRef::from_ast(node) | 105 | TypeRef::from_ast(node) |
106 | } else { | 106 | } else { |