aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/adt.rs25
-rw-r--r--crates/ra_hir/src/code_model_api.rs13
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs18
-rw-r--r--crates/ra_hir/src/db.rs6
-rw-r--r--crates/ra_hir/src/expr.rs92
-rw-r--r--crates/ra_hir/src/function.rs17
-rw-r--r--crates/ra_hir/src/function/scope.rs24
-rw-r--r--crates/ra_hir/src/ids.rs27
-rw-r--r--crates/ra_hir/src/impl_block.rs22
-rw-r--r--crates/ra_hir/src/macros.rs21
-rw-r--r--crates/ra_hir/src/module_tree.rs40
-rw-r--r--crates/ra_hir/src/name.rs15
-rw-r--r--crates/ra_hir/src/nameres.rs34
-rw-r--r--crates/ra_hir/src/path.rs12
-rw-r--r--crates/ra_hir/src/query_definitions.rs32
-rw-r--r--crates/ra_hir/src/source_binder.rs19
-rw-r--r--crates/ra_hir/src/ty.rs95
-rw-r--r--crates/ra_hir/src/ty/tests.rs13
-rw-r--r--crates/ra_hir/src/ty/tests/data/basics.txt4
-rw-r--r--crates/ra_hir/src/ty/tests/data/binary_op.txt46
-rw-r--r--crates/ra_hir/src/ty/tests/data/boolean_op.txt31
-rw-r--r--crates/ra_hir/src/type_ref.rs8
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
44impl StructData { 44impl 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
89impl EnumData { 89impl 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 @@
1use relative_path::RelativePathBuf; 1use relative_path::RelativePathBuf;
2use ra_db::{CrateId, Cancelable, FileId}; 2use ra_db::{CrateId, Cancelable, FileId};
3use ra_syntax::{ast, SyntaxNode}; 3use ra_syntax::{ast, TreePtr, SyntaxNode};
4 4
5use crate::{Name, db::HirDatabase, DefId, Path, PerNs, nameres::ModuleScope}; 5use crate::{Name, db::HirDatabase, DefId, Path, PerNs, nameres::ModuleScope};
6 6
@@ -36,8 +36,8 @@ pub struct Module {
36} 36}
37 37
38pub enum ModuleSource { 38pub 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 @@
1use ra_db::{Cancelable, SourceRootId, FileId}; 1use ra_db::{Cancelable, SourceRootId, FileId};
2use ra_syntax::{ast, SyntaxNode, AstNode}; 2use ra_syntax::{ast, SyntaxNode, AstNode, TreePtr};
3 3
4use crate::{ 4use 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 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{SyntaxNode, SourceFileNode}; 3use ra_syntax::{SyntaxNode, TreePtr, SourceFile};
4use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; 4use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable};
5 5
6use crate::{ 6use 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
713pub(crate) fn collect_fn_body_syntax(node: ast::FnDef) -> BodySyntaxMapping { 715pub(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
8use ra_db::Cancelable; 8use ra_db::Cancelable;
9use ra_syntax::{ 9use 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
100pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> { 100pub(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
146impl FnSignatureInfo { 145impl 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;
3use rustc_hash::{FxHashMap, FxHashSet}; 3use rustc_hash::{FxHashMap, FxHashSet};
4 4
5use ra_syntax::{ 5use 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
129impl ScopesWithSyntaxMapping { 129impl 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)]
310mod tests { 310mod 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 @@
1use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId}; 1use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId};
2use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast}; 2use ra_syntax::{TreePtr, SyntaxKind, SyntaxNode, SourceFile, AstNode, ast};
3use ra_arena::{Arena, RawId, impl_arena_id}; 3use ra_arena::{Arena, RawId, impl_arena_id};
4 4
5use crate::{HirDatabase, PerNs, ModuleId, Def, Function, Struct, Enum, ImplBlock, Crate}; 5use 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)]
234pub struct SourceFileItems { 237pub 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
239impl SourceFileItems { 242impl 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
12use ra_db::LocalSyntaxPtr; 12use ra_db::LocalSyntaxPtr;
13use ra_syntax::{ 13use 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 {
28impl MacroDef { 28impl 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 {
152impl MacroExpansion { 152impl 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;
5use relative_path::RelativePathBuf; 5use relative_path::RelativePathBuf;
6use ra_db::{FileId, SourceRootId, Cancelable, SourceRoot}; 6use ra_db::{FileId, SourceRootId, Cancelable, SourceRoot};
7use ra_syntax::{ 7use 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};
12use ra_arena::{Arena, RawId, impl_arena_id}; 12use 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
216fn modules<'a>( 212fn 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
74impl AsName for ast::NameRef<'_> { 77impl 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
80impl AsName for ast::Name<'_> { 83impl 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
272impl ModuleItem { 272impl 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
19impl Path { 19impl 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
101fn expand_use_tree( 101fn 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
149fn convert_path(prefix: Option<Path>, path: ast::Path) -> Option<Path> { 149fn 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
6use rustc_hash::FxHashMap; 6use rustc_hash::FxHashMap;
7use ra_syntax::{ 7use ra_syntax::{
8 AstNode, SyntaxNode, 8 AstNode, SyntaxNode, TreePtr,
9 ast::{self, ModuleItemOwner} 9 ast::{self, ModuleItemOwner}
10}; 10};
11use ra_db::{SourceRootId, Cancelable,}; 11use 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
38pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> { 38pub(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
47pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { 46pub(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
54pub(super) fn file_item(db: &impl HirDatabase, source_item_id: SourceItemId) -> SyntaxNode { 52pub(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 @@
8use ra_db::{FileId, FilePosition, Cancelable}; 8use ra_db::{FileId, FilePosition, Cancelable};
9use ra_editor::find_node_at_offset; 9use ra_editor::find_node_at_offset;
10use ra_syntax::{ 10use 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
30pub fn module_from_declaration( 30pub 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(
60fn module_from_inline( 60fn 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(
77pub fn module_from_child_node( 77pub 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(
112pub fn function_from_source( 112pub 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(
122pub fn function_from_module( 122pub 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(
144pub fn function_from_child_node( 144pub 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 536fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
531// always returns a boolean
532fn 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
573fn 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]
160fn infer_boolean_op() { 160fn infer_binary_op() {
161 check_inference( 161 check_inference(
162 r#" 162 r#"
163fn f(x: bool) -> i32 { 163fn 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
57impl TypeRef { 57impl 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 {