aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model_api.rs26
-rw-r--r--crates/ra_hir/src/code_model_impl/function.rs4
-rw-r--r--crates/ra_hir/src/code_model_impl/krate.rs13
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs15
-rw-r--r--crates/ra_hir/src/db.rs25
-rw-r--r--crates/ra_hir/src/expr.rs12
-rw-r--r--crates/ra_hir/src/expr/scope.rs (renamed from crates/ra_hir/src/code_model_impl/function/scope.rs)31
-rw-r--r--crates/ra_hir/src/impl_block.rs57
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/module_tree.rs11
-rw-r--r--crates/ra_hir/src/nameres.rs33
-rw-r--r--crates/ra_hir/src/nameres/tests.rs14
-rw-r--r--crates/ra_hir/src/query_definitions.rs42
-rw-r--r--crates/ra_hir/src/source_binder.rs29
-rw-r--r--crates/ra_hir/src/ty.rs24
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs8
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap23
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_array.snap14
-rw-r--r--crates/ra_hir/src/ty/tests.rs4
19 files changed, 253 insertions, 134 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index e4008058c..9405aa8ad 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -10,12 +10,13 @@ use crate::{
10 nameres::{ModuleScope, lower::ImportId}, 10 nameres::{ModuleScope, lower::ImportId},
11 db::HirDatabase, 11 db::HirDatabase,
12 expr::BodySyntaxMapping, 12 expr::BodySyntaxMapping,
13 ty::InferenceResult, 13 ty::{InferenceResult},
14 adt::{EnumVariantId, StructFieldId, VariantDef}, 14 adt::{EnumVariantId, StructFieldId, VariantDef},
15 generics::GenericParams, 15 generics::GenericParams,
16 docs::{Documentation, Docs, docs_from_ast}, 16 docs::{Documentation, Docs, docs_from_ast},
17 module_tree::ModuleId, 17 module_tree::ModuleId,
18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, 18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
19 impl_block::ImplId,
19}; 20};
20 21
21/// hir::Crate describes a single crate. It's the main interface with which 22/// hir::Crate describes a single crate. It's the main interface with which
@@ -51,7 +52,7 @@ pub enum Def {
51 52
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 53#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53pub struct Module { 54pub struct Module {
54 pub(crate) krate: CrateId, 55 pub(crate) krate: Crate,
55 pub(crate) module_id: ModuleId, 56 pub(crate) module_id: ModuleId,
56} 57}
57 58
@@ -126,9 +127,14 @@ impl Module {
126 self.import_source_impl(db, import) 127 self.import_source_impl(db, import)
127 } 128 }
128 129
130 /// Returns the syntax of the impl block in this module
131 pub fn impl_source(&self, db: &impl HirDatabase, impl_id: ImplId) -> TreeArc<ast::ImplBlock> {
132 self.impl_source_impl(db, impl_id)
133 }
134
129 /// Returns the crate this module is part of. 135 /// Returns the crate this module is part of.
130 pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { 136 pub fn krate(&self, _db: &impl HirDatabase) -> Option<Crate> {
131 self.krate_impl(db) 137 Some(self.krate)
132 } 138 }
133 139
134 /// Topmost parent of this module. Every module has a `crate_root`, but some 140 /// Topmost parent of this module. Every module has a `crate_root`, but some
@@ -272,6 +278,10 @@ impl Struct {
272 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { 278 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
273 db.generic_params((*self).into()) 279 db.generic_params((*self).into())
274 } 280 }
281
282 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
283 db.type_for_def((*self).into())
284 }
275} 285}
276 286
277impl Docs for Struct { 287impl Docs for Struct {
@@ -317,6 +327,10 @@ impl Enum {
317 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { 327 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
318 db.generic_params((*self).into()) 328 db.generic_params((*self).into())
319 } 329 }
330
331 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
332 db.type_for_def((*self).into())
333 }
320} 334}
321 335
322impl Docs for Enum { 336impl Docs for Enum {
@@ -382,7 +396,7 @@ pub struct Function {
382 pub(crate) id: FunctionId, 396 pub(crate) id: FunctionId,
383} 397}
384 398
385pub use crate::code_model_impl::function::ScopeEntryWithSyntax; 399pub use crate::expr::ScopeEntryWithSyntax;
386 400
387/// The declared signature of a function. 401/// The declared signature of a function.
388#[derive(Debug, Clone, PartialEq, Eq)] 402#[derive(Debug, Clone, PartialEq, Eq)]
@@ -433,7 +447,7 @@ impl Function {
433 } 447 }
434 448
435 pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { 449 pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping {
436 let scopes = db.fn_scopes(*self); 450 let scopes = db.expr_scopes(*self);
437 let syntax_mapping = db.body_syntax_mapping(*self); 451 let syntax_mapping = db.body_syntax_mapping(*self);
438 ScopesWithSyntaxMapping { 452 ScopesWithSyntaxMapping {
439 scopes, 453 scopes,
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs
index e0dd4d629..422643996 100644
--- a/crates/ra_hir/src/code_model_impl/function.rs
+++ b/crates/ra_hir/src/code_model_impl/function.rs
@@ -1,5 +1,3 @@
1mod scope;
2
3use std::sync::Arc; 1use std::sync::Arc;
4 2
5use ra_syntax::ast::{self, NameOwner}; 3use ra_syntax::ast::{self, NameOwner};
@@ -11,8 +9,6 @@ use crate::{
11 impl_block::ImplBlock, 9 impl_block::ImplBlock,
12}; 10};
13 11
14pub use self::scope::{FnScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax};
15
16impl Function { 12impl Function {
17 pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> { 13 pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
18 db.body_hir(*self) 14 db.body_hir(*self)
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs
index cdd30b402..86f29d959 100644
--- a/crates/ra_hir/src/code_model_impl/krate.rs
+++ b/crates/ra_hir/src/code_model_impl/krate.rs
@@ -1,31 +1,28 @@
1use ra_db::CrateId;
2
3use crate::{ 1use crate::{
4 Crate, CrateDependency, AsName, Module, 2 Crate, CrateDependency, AsName, Module,
5 db::HirDatabase, 3 db::HirDatabase,
6}; 4};
7 5
8impl Crate { 6impl Crate {
9 pub(crate) fn new(crate_id: CrateId) -> Crate {
10 Crate { crate_id }
11 }
12 pub(crate) fn dependencies_impl(&self, db: &impl HirDatabase) -> Vec<CrateDependency> { 7 pub(crate) fn dependencies_impl(&self, db: &impl HirDatabase) -> Vec<CrateDependency> {
13 let crate_graph = db.crate_graph(); 8 let crate_graph = db.crate_graph();
14 crate_graph 9 crate_graph
15 .dependencies(self.crate_id) 10 .dependencies(self.crate_id)
16 .map(|dep| { 11 .map(|dep| {
17 let krate = Crate::new(dep.crate_id()); 12 let krate = Crate {
13 crate_id: dep.crate_id(),
14 };
18 let name = dep.as_name(); 15 let name = dep.as_name();
19 CrateDependency { krate, name } 16 CrateDependency { krate, name }
20 }) 17 })
21 .collect() 18 .collect()
22 } 19 }
23 pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { 20 pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> {
24 let module_tree = db.module_tree(self.crate_id); 21 let module_tree = db.module_tree(*self);
25 let module_id = module_tree.modules().next()?; 22 let module_id = module_tree.modules().next()?;
26 23
27 let module = Module { 24 let module = Module {
28 krate: self.crate_id, 25 krate: *self,
29 module_id, 26 module_id,
30 }; 27 };
31 Some(module) 28 Some(module)
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 418d59c91..4a3901b8b 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -3,8 +3,9 @@ use ra_syntax::{ast, SyntaxNode, TreeArc};
3 3
4use crate::{ 4use crate::{
5 Module, ModuleSource, Problem, 5 Module, ModuleSource, Problem,
6 Crate, Name, 6 Name,
7 module_tree::ModuleId, 7 module_tree::ModuleId,
8 impl_block::ImplId,
8 nameres::{lower::ImportId}, 9 nameres::{lower::ImportId},
9 db::HirDatabase, 10 db::HirDatabase,
10}; 11};
@@ -51,13 +52,19 @@ impl Module {
51 db: &impl HirDatabase, 52 db: &impl HirDatabase,
52 import: ImportId, 53 import: ImportId,
53 ) -> TreeArc<ast::PathSegment> { 54 ) -> TreeArc<ast::PathSegment> {
54 let source_map = db.lower_module_source_map(self.clone()); 55 let source_map = db.lower_module_source_map(*self);
55 let (_, source) = self.definition_source(db); 56 let (_, source) = self.definition_source(db);
56 source_map.get(&source, import) 57 source_map.get(&source, import)
57 } 58 }
58 59
59 pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> { 60 pub(crate) fn impl_source_impl(
60 Some(Crate::new(self.krate)) 61 &self,
62 db: &impl HirDatabase,
63 impl_id: ImplId,
64 ) -> TreeArc<ast::ImplBlock> {
65 let source_map = db.impls_in_module_source_map(*self);
66 let (_, source) = self.definition_source(db);
67 source_map.get(&source, impl_id)
61 } 68 }
62 69
63 pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module { 70 pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 3f76b769d..189649841 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -1,20 +1,20 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; 3use ra_syntax::{SyntaxNode, TreeArc, SourceFile};
4use ra_db::{SourceDatabase, CrateId, salsa}; 4use ra_db::{SourceDatabase, salsa};
5 5
6use crate::{ 6use crate::{
7 MacroCallId, HirFileId, 7 MacroCallId, HirFileId,
8 SourceFileItems, SourceItemId, Crate, Module, HirInterner, 8 SourceFileItems, SourceItemId, Crate, Module, HirInterner,
9 query_definitions, 9 query_definitions,
10 Function, FnSignature, FnScopes, 10 Function, FnSignature, ExprScopes,
11 Struct, Enum, StructField, 11 Struct, Enum, StructField,
12 macros::MacroExpansion, 12 macros::MacroExpansion,
13 module_tree::ModuleTree, 13 module_tree::ModuleTree,
14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, 14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
15 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef}, 15 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef},
16 adt::{StructData, EnumData}, 16 adt::{StructData, EnumData},
17 impl_block::ModuleImplBlocks, 17 impl_block::{ModuleImplBlocks, ImplSourceMap},
18 generics::{GenericParams, GenericDef}, 18 generics::{GenericParams, GenericDef},
19 ids::SourceFileItemId, 19 ids::SourceFileItemId,
20}; 20};
@@ -27,8 +27,8 @@ pub trait HirDatabase: SourceDatabase + AsRef<HirInterner> {
27 #[salsa::invoke(crate::macros::expand_macro_invocation)] 27 #[salsa::invoke(crate::macros::expand_macro_invocation)]
28 fn expand_macro_invocation(&self, invoc: MacroCallId) -> Option<Arc<MacroExpansion>>; 28 fn expand_macro_invocation(&self, invoc: MacroCallId) -> Option<Arc<MacroExpansion>>;
29 29
30 #[salsa::invoke(query_definitions::fn_scopes)] 30 #[salsa::invoke(ExprScopes::expr_scopes_query)]
31 fn fn_scopes(&self, func: Function) -> Arc<FnScopes>; 31 fn expr_scopes(&self, func: Function) -> Arc<ExprScopes>;
32 32
33 #[salsa::invoke(crate::adt::StructData::struct_data_query)] 33 #[salsa::invoke(crate::adt::StructData::struct_data_query)]
34 fn struct_data(&self, s: Struct) -> Arc<StructData>; 34 fn struct_data(&self, s: Struct) -> Arc<StructData>;
@@ -67,15 +67,24 @@ pub trait HirDatabase: SourceDatabase + AsRef<HirInterner> {
67 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)] 67 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)]
68 fn lower_module_source_map(&self, module: Module) -> Arc<ImportSourceMap>; 68 fn lower_module_source_map(&self, module: Module) -> Arc<ImportSourceMap>;
69 69
70 #[salsa::invoke(query_definitions::item_map)] 70 #[salsa::invoke(crate::nameres::ItemMap::item_map_query)]
71 fn item_map(&self, crate_id: CrateId) -> Arc<ItemMap>; 71 fn item_map(&self, krate: Crate) -> Arc<ItemMap>;
72 72
73 #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)] 73 #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)]
74 fn module_tree(&self, crate_id: CrateId) -> Arc<ModuleTree>; 74 fn module_tree(&self, krate: Crate) -> Arc<ModuleTree>;
75
76 #[salsa::invoke(crate::impl_block::impls_in_module_with_source_map_query)]
77 fn impls_in_module_with_source_map(
78 &self,
79 module: Module,
80 ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>);
75 81
76 #[salsa::invoke(crate::impl_block::impls_in_module)] 82 #[salsa::invoke(crate::impl_block::impls_in_module)]
77 fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>; 83 fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>;
78 84
85 #[salsa::invoke(crate::impl_block::impls_in_module_source_map_query)]
86 fn impls_in_module_source_map(&self, module: Module) -> Arc<ImplSourceMap>;
87
79 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] 88 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
80 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; 89 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
81 90
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 60d997bbe..37aa24677 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -16,6 +16,10 @@ use crate::{
16}; 16};
17use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; 17use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
18 18
19pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax};
20
21mod scope;
22
19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub struct ExprId(RawId); 24pub struct ExprId(RawId);
21impl_arena_id!(ExprId); 25impl_arena_id!(ExprId);
@@ -215,7 +219,7 @@ pub use ra_syntax::ast::BinOp as BinaryOp;
215#[derive(Debug, Clone, Eq, PartialEq)] 219#[derive(Debug, Clone, Eq, PartialEq)]
216pub struct MatchArm { 220pub struct MatchArm {
217 pub pats: Vec<PatId>, 221 pub pats: Vec<PatId>,
218 // guard: Option<ExprId>, // TODO 222 pub guard: Option<ExprId>,
219 pub expr: ExprId, 223 pub expr: ExprId,
220} 224}
221 225
@@ -511,10 +515,12 @@ impl ExprCollector {
511 MatchArm { 515 MatchArm {
512 pats: vec![pat], 516 pats: vec![pat],
513 expr: then_branch, 517 expr: then_branch,
518 guard: None,
514 }, 519 },
515 MatchArm { 520 MatchArm {
516 pats: vec![placeholder_pat], 521 pats: vec![placeholder_pat],
517 expr: else_branch, 522 expr: else_branch,
523 guard: None,
518 }, 524 },
519 ]; 525 ];
520 self.alloc_expr( 526 self.alloc_expr(
@@ -613,6 +619,10 @@ impl ExprCollector {
613 .map(|arm| MatchArm { 619 .map(|arm| MatchArm {
614 pats: arm.pats().map(|p| self.collect_pat(p)).collect(), 620 pats: arm.pats().map(|p| self.collect_pat(p)).collect(),
615 expr: self.collect_expr_opt(arm.expr()), 621 expr: self.collect_expr_opt(arm.expr()),
622 guard: arm
623 .guard()
624 .and_then(|guard| guard.expr())
625 .map(|e| self.collect_expr(e)),
616 }) 626 })
617 .collect() 627 .collect()
618 } else { 628 } else {
diff --git a/crates/ra_hir/src/code_model_impl/function/scope.rs b/crates/ra_hir/src/expr/scope.rs
index c5d1de5eb..f8b5ba581 100644
--- a/crates/ra_hir/src/code_model_impl/function/scope.rs
+++ b/crates/ra_hir/src/expr/scope.rs
@@ -9,14 +9,18 @@ use ra_syntax::{
9}; 9};
10use ra_arena::{Arena, RawId, impl_arena_id}; 10use ra_arena::{Arena, RawId, impl_arena_id};
11 11
12use crate::{Name, AsName, expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySyntaxMapping}}; 12use crate::{
13 Name, AsName, Function,
14 expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySyntaxMapping},
15 db::HirDatabase,
16};
13 17
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 18#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct ScopeId(RawId); 19pub struct ScopeId(RawId);
16impl_arena_id!(ScopeId); 20impl_arena_id!(ScopeId);
17 21
18#[derive(Debug, PartialEq, Eq)] 22#[derive(Debug, PartialEq, Eq)]
19pub struct FnScopes { 23pub struct ExprScopes {
20 body: Arc<Body>, 24 body: Arc<Body>,
21 scopes: Arena<ScopeId, ScopeData>, 25 scopes: Arena<ScopeId, ScopeData>,
22 scope_for: FxHashMap<ExprId, ScopeId>, 26 scope_for: FxHashMap<ExprId, ScopeId>,
@@ -34,9 +38,16 @@ pub struct ScopeData {
34 entries: Vec<ScopeEntry>, 38 entries: Vec<ScopeEntry>,
35} 39}
36 40
37impl FnScopes { 41impl ExprScopes {
38 pub(crate) fn new(body: Arc<Body>) -> FnScopes { 42 // TODO: This should take something more general than Function
39 let mut scopes = FnScopes { 43 pub(crate) fn expr_scopes_query(db: &impl HirDatabase, function: Function) -> Arc<ExprScopes> {
44 let body = db.body_hir(function);
45 let res = ExprScopes::new(body);
46 Arc::new(res)
47 }
48
49 fn new(body: Arc<Body>) -> ExprScopes {
50 let mut scopes = ExprScopes {
40 body: body.clone(), 51 body: body.clone(),
41 scopes: Arena::default(), 52 scopes: Arena::default(),
42 scope_for: FxHashMap::default(), 53 scope_for: FxHashMap::default(),
@@ -119,7 +130,7 @@ impl FnScopes {
119#[derive(Debug, Clone, PartialEq, Eq)] 130#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct ScopesWithSyntaxMapping { 131pub struct ScopesWithSyntaxMapping {
121 pub syntax_mapping: Arc<BodySyntaxMapping>, 132 pub syntax_mapping: Arc<BodySyntaxMapping>,
122 pub scopes: Arc<FnScopes>, 133 pub scopes: Arc<ExprScopes>,
123} 134}
124 135
125#[derive(Debug, Clone, PartialEq, Eq)] 136#[derive(Debug, Clone, PartialEq, Eq)]
@@ -249,7 +260,7 @@ fn compute_block_scopes(
249 statements: &[Statement], 260 statements: &[Statement],
250 tail: Option<ExprId>, 261 tail: Option<ExprId>,
251 body: &Body, 262 body: &Body,
252 scopes: &mut FnScopes, 263 scopes: &mut ExprScopes,
253 mut scope: ScopeId, 264 mut scope: ScopeId,
254) { 265) {
255 for stmt in statements { 266 for stmt in statements {
@@ -275,7 +286,7 @@ fn compute_block_scopes(
275 } 286 }
276} 287}
277 288
278fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut FnScopes, scope: ScopeId) { 289fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) {
279 scopes.set_scope(expr, scope); 290 scopes.set_scope(expr, scope);
280 match &body[expr] { 291 match &body[expr] {
281 Expr::Block { statements, tail } => { 292 Expr::Block { statements, tail } => {
@@ -344,7 +355,7 @@ mod tests {
344 let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); 355 let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap();
345 let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); 356 let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
346 let body_hir = expr::collect_fn_body_syntax(fn_def); 357 let body_hir = expr::collect_fn_body_syntax(fn_def);
347 let scopes = FnScopes::new(Arc::clone(body_hir.body())); 358 let scopes = ExprScopes::new(Arc::clone(body_hir.body()));
348 let scopes = ScopesWithSyntaxMapping { 359 let scopes = ScopesWithSyntaxMapping {
349 scopes: Arc::new(scopes), 360 scopes: Arc::new(scopes),
350 syntax_mapping: Arc::new(body_hir), 361 syntax_mapping: Arc::new(body_hir),
@@ -444,7 +455,7 @@ mod tests {
444 let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); 455 let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
445 456
446 let body_hir = expr::collect_fn_body_syntax(fn_def); 457 let body_hir = expr::collect_fn_body_syntax(fn_def);
447 let scopes = FnScopes::new(Arc::clone(body_hir.body())); 458 let scopes = ExprScopes::new(Arc::clone(body_hir.body()));
448 let scopes = ScopesWithSyntaxMapping { 459 let scopes = ScopesWithSyntaxMapping {
449 scopes: Arc::new(scopes), 460 scopes: Arc::new(scopes),
450 syntax_mapping: Arc::new(body_hir), 461 syntax_mapping: Arc::new(body_hir),
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 222e47349..5fc26324a 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -1,8 +1,10 @@
1use std::sync::Arc; 1use std::sync::Arc;
2use rustc_hash::FxHashMap; 2use rustc_hash::FxHashMap;
3 3
4use ra_arena::{Arena, RawId, impl_arena_id}; 4use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::{
6 AstPtr, SourceFile, TreeArc,
7ast::{self, AstNode}};
6 8
7use crate::{ 9use crate::{
8 Const, Type, 10 Const, Type,
@@ -14,6 +16,26 @@ use crate::{
14 16
15use crate::code_model_api::{Module, ModuleSource}; 17use crate::code_model_api::{Module, ModuleSource};
16 18
19#[derive(Debug, Default, PartialEq, Eq)]
20pub struct ImplSourceMap {
21 map: ArenaMap<ImplId, AstPtr<ast::ImplBlock>>,
22}
23
24impl ImplSourceMap {
25 fn insert(&mut self, impl_id: ImplId, impl_block: &ast::ImplBlock) {
26 self.map.insert(impl_id, AstPtr::new(impl_block))
27 }
28
29 pub fn get(&self, source: &ModuleSource, impl_id: ImplId) -> TreeArc<ast::ImplBlock> {
30 let file = match source {
31 ModuleSource::SourceFile(file) => &*file,
32 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
33 };
34
35 self.map[impl_id].to_node(file).to_owned()
36 }
37}
38
17#[derive(Debug, Clone, PartialEq, Eq)] 39#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct ImplBlock { 40pub struct ImplBlock {
19 module_impl_blocks: Arc<ModuleImplBlocks>, 41 module_impl_blocks: Arc<ModuleImplBlocks>,
@@ -39,6 +61,10 @@ impl ImplBlock {
39 } 61 }
40 } 62 }
41 63
64 pub fn id(&self) -> ImplId {
65 self.impl_id
66 }
67
42 fn impl_data(&self) -> &ImplData { 68 fn impl_data(&self) -> &ImplData {
43 &self.module_impl_blocks.impls[self.impl_id] 69 &self.module_impl_blocks.impls[self.impl_id]
44 } 70 }
@@ -148,7 +174,7 @@ impl ModuleImplBlocks {
148 } 174 }
149 } 175 }
150 176
151 fn collect(&mut self, db: &impl HirDatabase, module: Module) { 177 fn collect(&mut self, db: &impl HirDatabase, module: Module, source_map: &mut ImplSourceMap) {
152 let (file_id, module_source) = module.definition_source(db); 178 let (file_id, module_source) = module.definition_source(db);
153 let file_id: HirFileId = file_id.into(); 179 let file_id: HirFileId = file_id.into();
154 let node = match &module_source { 180 let node = match &module_source {
@@ -165,12 +191,31 @@ impl ModuleImplBlocks {
165 for &impl_item in &self.impls[id].items { 191 for &impl_item in &self.impls[id].items {
166 self.impls_by_def.insert(impl_item, id); 192 self.impls_by_def.insert(impl_item, id);
167 } 193 }
194
195 source_map.insert(id, impl_block_ast);
168 } 196 }
169 } 197 }
170} 198}
171 199
172pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> { 200pub(crate) fn impls_in_module_with_source_map_query(
201 db: &impl HirDatabase,
202 module: Module,
203) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) {
204 let mut source_map = ImplSourceMap::default();
205
173 let mut result = ModuleImplBlocks::new(); 206 let mut result = ModuleImplBlocks::new();
174 result.collect(db, module); 207 result.collect(db, module, &mut source_map);
175 Arc::new(result) 208
209 (Arc::new(result), Arc::new(source_map))
210}
211
212pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> {
213 db.impls_in_module_with_source_map(module).0
214}
215
216pub(crate) fn impls_in_module_source_map_query(
217 db: &impl HirDatabase,
218 module: Module,
219) -> Arc<ImplSourceMap> {
220 db.impls_in_module_with_source_map(module).1
176} 221}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index eaf8565ee..0b9ee63bf 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -57,9 +57,9 @@ pub use self::{
57 nameres::{ItemMap, PerNs, Namespace, Resolution}, 57 nameres::{ItemMap, PerNs, Namespace, Resolution},
58 ty::Ty, 58 ty::Ty,
59 impl_block::{ImplBlock, ImplItem}, 59 impl_block::{ImplBlock, ImplItem},
60 code_model_impl::function::{FnScopes, ScopesWithSyntaxMapping},
61 docs::{Docs, Documentation}, 60 docs::{Docs, Documentation},
62 adt::AdtDef, 61 adt::AdtDef,
62 expr::{ExprScopes, ScopesWithSyntaxMapping},
63}; 63};
64 64
65pub use self::code_model_api::{ 65pub use self::code_model_api::{
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs
index 893c375b5..1f327eeb2 100644
--- a/crates/ra_hir/src/module_tree.rs
+++ b/crates/ra_hir/src/module_tree.rs
@@ -2,7 +2,7 @@ use std::sync::Arc;
2 2
3use arrayvec::ArrayVec; 3use arrayvec::ArrayVec;
4use relative_path::RelativePathBuf; 4use relative_path::RelativePathBuf;
5use ra_db::{FileId, SourceRoot, CrateId}; 5use ra_db::{FileId, SourceRoot};
6use ra_syntax::{ 6use ra_syntax::{
7 SyntaxNode, TreeArc, 7 SyntaxNode, TreeArc,
8 algo::generate, 8 algo::generate,
@@ -13,6 +13,7 @@ use test_utils::tested_by;
13 13
14use crate::{ 14use crate::{
15 Name, AsName, HirDatabase, SourceItemId, HirFileId, Problem, SourceFileItems, ModuleSource, 15 Name, AsName, HirDatabase, SourceItemId, HirFileId, Problem, SourceFileItems, ModuleSource,
16 Crate,
16 ids::SourceFileItemId, 17 ids::SourceFileItemId,
17}; 18};
18 19
@@ -132,10 +133,10 @@ struct LinkData {
132} 133}
133 134
134impl ModuleTree { 135impl ModuleTree {
135 pub(crate) fn module_tree_query(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ModuleTree> { 136 pub(crate) fn module_tree_query(db: &impl HirDatabase, krate: Crate) -> Arc<ModuleTree> {
136 db.check_canceled(); 137 db.check_canceled();
137 let mut res = ModuleTree::default(); 138 let mut res = ModuleTree::default();
138 res.init_crate(db, crate_id); 139 res.init_crate(db, krate);
139 Arc::new(res) 140 Arc::new(res)
140 } 141 }
141 142
@@ -155,9 +156,9 @@ impl ModuleTree {
155 Some(res) 156 Some(res)
156 } 157 }
157 158
158 fn init_crate(&mut self, db: &impl HirDatabase, crate_id: CrateId) { 159 fn init_crate(&mut self, db: &impl HirDatabase, krate: Crate) {
159 let crate_graph = db.crate_graph(); 160 let crate_graph = db.crate_graph();
160 let file_id = crate_graph.crate_root(crate_id); 161 let file_id = crate_graph.crate_root(krate.crate_id);
161 let source_root_id = db.file_source_root(file_id); 162 let source_root_id = db.file_source_root(file_id);
162 163
163 let source_root = db.source_root(source_root_id); 164 let source_root = db.source_root(source_root_id);
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 97ce6c946..4573a72ba 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -16,9 +16,8 @@
16//! structure itself is modified. 16//! structure itself is modified.
17pub(crate) mod lower; 17pub(crate) mod lower;
18 18
19use std::sync::Arc; 19use std::{time, sync::Arc};
20 20
21use ra_db::CrateId;
22use ra_arena::map::ArenaMap; 21use ra_arena::map::ArenaMap;
23use test_utils::tested_by; 22use test_utils::tested_by;
24use rustc_hash::{FxHashMap, FxHashSet}; 23use rustc_hash::{FxHashMap, FxHashSet};
@@ -156,10 +155,10 @@ impl<T> PerNs<T> {
156 } 155 }
157} 156}
158 157
159pub(crate) struct Resolver<'a, DB> { 158struct Resolver<'a, DB> {
160 db: &'a DB, 159 db: &'a DB,
161 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>, 160 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
162 krate: CrateId, 161 krate: Crate,
163 module_tree: Arc<ModuleTree>, 162 module_tree: Arc<ModuleTree>,
164 processed_imports: FxHashSet<(ModuleId, ImportId)>, 163 processed_imports: FxHashSet<(ModuleId, ImportId)>,
165 result: ItemMap, 164 result: ItemMap,
@@ -169,10 +168,10 @@ impl<'a, DB> Resolver<'a, DB>
169where 168where
170 DB: HirDatabase, 169 DB: HirDatabase,
171{ 170{
172 pub(crate) fn new( 171 fn new(
173 db: &'a DB, 172 db: &'a DB,
174 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>, 173 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
175 krate: CrateId, 174 krate: Crate,
176 ) -> Resolver<'a, DB> { 175 ) -> Resolver<'a, DB> {
177 let module_tree = db.module_tree(krate); 176 let module_tree = db.module_tree(krate);
178 Resolver { 177 Resolver {
@@ -219,7 +218,7 @@ where
219 let crate_graph = self.db.crate_graph(); 218 let crate_graph = self.db.crate_graph();
220 if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file()) 219 if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file())
221 { 220 {
222 let krate = Crate::new(crate_id); 221 let krate = Crate { crate_id };
223 for dep in krate.dependencies(self.db) { 222 for dep in krate.dependencies(self.db) {
224 if let Some(module) = dep.krate.root_module(self.db) { 223 if let Some(module) = dep.krate.root_module(self.db) {
225 let def = module.into(); 224 let def = module.into();
@@ -331,6 +330,26 @@ enum ReachedFixedPoint {
331} 330}
332 331
333impl ItemMap { 332impl ItemMap {
333 pub(crate) fn item_map_query(db: &impl HirDatabase, krate: Crate) -> Arc<ItemMap> {
334 let start = time::Instant::now();
335 let module_tree = db.module_tree(krate);
336 let input = module_tree
337 .modules()
338 .map(|module_id| {
339 (
340 module_id,
341 db.lower_module_module(Module { krate, module_id }),
342 )
343 })
344 .collect::<FxHashMap<_, _>>();
345
346 let resolver = Resolver::new(db, &input, krate);
347 let res = resolver.resolve();
348 let elapsed = start.elapsed();
349 log::info!("item_map: {:?}", elapsed);
350 Arc::new(res)
351 }
352
334 pub(crate) fn resolve_path( 353 pub(crate) fn resolve_path(
335 &self, 354 &self,
336 db: &impl HirDatabase, 355 db: &impl HirDatabase,
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 3d420467c..9c5ca097e 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -16,7 +16,7 @@ fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
16 let module = crate::source_binder::module_from_position(&db, pos).unwrap(); 16 let module = crate::source_binder::module_from_position(&db, pos).unwrap();
17 let krate = module.krate(&db).unwrap(); 17 let krate = module.krate(&db).unwrap();
18 let module_id = module.module_id; 18 let module_id = module.module_id;
19 (db.item_map(krate.crate_id), module_id) 19 (db.item_map(krate), module_id)
20} 20}
21 21
22/// Sets the crate root to the file of the cursor marker 22/// Sets the crate root to the file of the cursor marker
@@ -30,7 +30,7 @@ fn item_map_custom_crate_root(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
30 let module = crate::source_binder::module_from_position(&db, pos).unwrap(); 30 let module = crate::source_binder::module_from_position(&db, pos).unwrap();
31 let krate = module.krate(&db).unwrap(); 31 let krate = module.krate(&db).unwrap();
32 let module_id = module.module_id; 32 let module_id = module.module_id;
33 (db.item_map(krate.crate_id), module_id) 33 (db.item_map(krate), module_id)
34} 34}
35 35
36fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { 36fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) {
@@ -297,7 +297,7 @@ fn item_map_across_crates() {
297 297
298 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); 298 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
299 let krate = module.krate(&db).unwrap(); 299 let krate = module.krate(&db).unwrap();
300 let item_map = db.item_map(krate.crate_id); 300 let item_map = db.item_map(krate);
301 301
302 check_module_item_map( 302 check_module_item_map(
303 &item_map, 303 &item_map,
@@ -349,7 +349,7 @@ fn import_across_source_roots() {
349 349
350 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); 350 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
351 let krate = module.krate(&db).unwrap(); 351 let krate = module.krate(&db).unwrap();
352 let item_map = db.item_map(krate.crate_id); 352 let item_map = db.item_map(krate);
353 353
354 check_module_item_map( 354 check_module_item_map(
355 &item_map, 355 &item_map,
@@ -391,7 +391,7 @@ fn reexport_across_crates() {
391 391
392 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); 392 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
393 let krate = module.krate(&db).unwrap(); 393 let krate = module.krate(&db).unwrap();
394 let item_map = db.item_map(krate.crate_id); 394 let item_map = db.item_map(krate);
395 395
396 check_module_item_map( 396 check_module_item_map(
397 &item_map, 397 &item_map,
@@ -409,7 +409,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
409 let krate = module.krate(&db).unwrap(); 409 let krate = module.krate(&db).unwrap();
410 { 410 {
411 let events = db.log_executed(|| { 411 let events = db.log_executed(|| {
412 db.item_map(krate.crate_id); 412 db.item_map(krate);
413 }); 413 });
414 assert!(format!("{:?}", events).contains("item_map")) 414 assert!(format!("{:?}", events).contains("item_map"))
415 } 415 }
@@ -417,7 +417,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
417 417
418 { 418 {
419 let events = db.log_executed(|| { 419 let events = db.log_executed(|| {
420 db.item_map(krate.crate_id); 420 db.item_map(krate);
421 }); 421 });
422 assert!( 422 assert!(
423 !format!("{:?}", events).contains("item_map"), 423 !format!("{:?}", events).contains("item_map"),
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs
index bf9ac0dfb..734a98282 100644
--- a/crates/ra_hir/src/query_definitions.rs
+++ b/crates/ra_hir/src/query_definitions.rs
@@ -1,25 +1,14 @@
1use std::{ 1use std::sync::Arc;
2 sync::Arc,
3 time::Instant,
4};
5 2
6use rustc_hash::FxHashMap; 3use ra_syntax::{
7use ra_syntax::{SyntaxNode, TreeArc}; 4 SyntaxNode, TreeArc,
8use ra_db::{CrateId}; 5};
9 6
10use crate::{ 7use crate::{
11 SourceFileItems, SourceItemId, HirFileId, 8 SourceFileItems, SourceItemId, HirFileId,
12 Function, FnScopes, Module,
13 db::HirDatabase, 9 db::HirDatabase,
14 nameres::{ItemMap, Resolver},
15}; 10};
16 11
17pub(super) fn fn_scopes(db: &impl HirDatabase, func: Function) -> Arc<FnScopes> {
18 let body = db.body_hir(func);
19 let res = FnScopes::new(body);
20 Arc::new(res)
21}
22
23pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { 12pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> {
24 let source_file = db.hir_parse(file_id); 13 let source_file = db.hir_parse(file_id);
25 let res = SourceFileItems::new(file_id, &source_file); 14 let res = SourceFileItems::new(file_id, &source_file);
@@ -35,26 +24,3 @@ pub(super) fn file_item(
35 .to_node(&source_file) 24 .to_node(&source_file)
36 .to_owned() 25 .to_owned()
37} 26}
38
39pub(super) fn item_map(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ItemMap> {
40 let start = Instant::now();
41 let module_tree = db.module_tree(crate_id);
42 let input = module_tree
43 .modules()
44 .map(|module_id| {
45 (
46 module_id,
47 db.lower_module_module(Module {
48 krate: crate_id,
49 module_id,
50 }),
51 )
52 })
53 .collect::<FxHashMap<_, _>>();
54
55 let resolver = Resolver::new(db, &input, crate_id);
56 let res = resolver.resolve();
57 let elapsed = start.elapsed();
58 log::info!("item_map: {:?}", elapsed);
59 Arc::new(res)
60}
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index f523f0647..d1eaccf23 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -13,8 +13,8 @@ use ra_syntax::{
13}; 13};
14 14
15use crate::{ 15use crate::{
16 HirDatabase, Function, ModuleDef, 16 HirDatabase, Function, ModuleDef, Struct, Enum,
17 AsName, Module, HirFileId, 17 AsName, Module, HirFileId, Crate,
18 ids::{LocationCtx, SourceFileItemId}, 18 ids::{LocationCtx, SourceFileItemId},
19}; 19};
20 20
@@ -83,7 +83,8 @@ fn module_from_source(
83 let source_root_id = db.file_source_root(file_id.as_original_file()); 83 let source_root_id = db.file_source_root(file_id.as_original_file());
84 db.source_root_crates(source_root_id) 84 db.source_root_crates(source_root_id)
85 .iter() 85 .iter()
86 .find_map(|&krate| { 86 .map(|&crate_id| Crate { crate_id })
87 .find_map(|krate| {
87 let module_tree = db.module_tree(krate); 88 let module_tree = db.module_tree(krate);
88 let module_id = module_tree.find_module_by_source(file_id, decl_id)?; 89 let module_id = module_tree.find_module_by_source(file_id, decl_id)?;
89 Some(Module { krate, module_id }) 90 Some(Module { krate, module_id })
@@ -128,6 +129,28 @@ pub fn function_from_child_node(
128 function_from_source(db, file_id, fn_def) 129 function_from_source(db, file_id, fn_def)
129} 130}
130 131
132pub fn struct_from_module(
133 db: &impl HirDatabase,
134 module: Module,
135 struct_def: &ast::StructDef,
136) -> Struct {
137 let (file_id, _) = module.definition_source(db);
138 let file_id = file_id.into();
139 let ctx = LocationCtx::new(db, module, file_id);
140 Struct {
141 id: ctx.to_def(struct_def),
142 }
143}
144
145pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum {
146 let (file_id, _) = module.definition_source(db);
147 let file_id = file_id.into();
148 let ctx = LocationCtx::new(db, module, file_id);
149 Enum {
150 id: ctx.to_def(enum_def),
151 }
152}
153
131pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { 154pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> {
132 let module = match module_from_file_id(db, file_id) { 155 let module = match module_from_file_id(db, file_id) {
133 Some(it) => it, 156 Some(it) => it,
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 7a5485698..60c231e82 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -34,7 +34,7 @@ use test_utils::tested_by;
34 34
35use crate::{ 35use crate::{
36 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, 36 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
37 FnSignature, FnScopes, ModuleDef, AdtDef, 37 FnSignature, ExprScopes, ModuleDef, AdtDef,
38 db::HirDatabase, 38 db::HirDatabase,
39 type_ref::{TypeRef, Mutability}, 39 type_ref::{TypeRef, Mutability},
40 name::KnownName, 40 name::KnownName,
@@ -814,7 +814,7 @@ impl Index<PatId> for InferenceResult {
814struct InferenceContext<'a, D: HirDatabase> { 814struct InferenceContext<'a, D: HirDatabase> {
815 db: &'a D, 815 db: &'a D,
816 body: Arc<Body>, 816 body: Arc<Body>,
817 scopes: Arc<FnScopes>, 817 scopes: Arc<ExprScopes>,
818 module: Module, 818 module: Module,
819 impl_block: Option<ImplBlock>, 819 impl_block: Option<ImplBlock>,
820 var_unification_table: InPlaceUnificationTable<TypeVarId>, 820 var_unification_table: InPlaceUnificationTable<TypeVarId>,
@@ -908,7 +908,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
908 fn new( 908 fn new(
909 db: &'a D, 909 db: &'a D,
910 body: Arc<Body>, 910 body: Arc<Body>,
911 scopes: Arc<FnScopes>, 911 scopes: Arc<ExprScopes>,
912 module: Module, 912 module: Module,
913 impl_block: Option<ImplBlock>, 913 impl_block: Option<ImplBlock>,
914 ) -> Self { 914 ) -> Self {
@@ -1488,7 +1488,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1488 for &pat in &arm.pats { 1488 for &pat in &arm.pats {
1489 let _pat_ty = self.infer_pat(pat, &input_ty); 1489 let _pat_ty = self.infer_pat(pat, &input_ty);
1490 } 1490 }
1491 // TODO type the guard 1491 if let Some(guard_expr) = arm.guard {
1492 self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool));
1493 }
1492 self.infer_expr(arm.expr, &expected); 1494 self.infer_expr(arm.expr, &expected);
1493 } 1495 }
1494 1496
@@ -1561,9 +1563,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1561 cast_ty 1563 cast_ty
1562 } 1564 }
1563 Expr::Ref { expr, mutability } => { 1565 Expr::Ref { expr, mutability } => {
1564 // TODO pass the expectation down 1566 let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty {
1565 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 1567 if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared {
1568 // TODO: throw type error - expected mut reference but found shared ref,
1569 // which cannot be coerced
1570 }
1571 Expectation::has_type((**subty).clone())
1572 } else {
1573 Expectation::none()
1574 };
1566 // TODO reference coercions etc. 1575 // TODO reference coercions etc.
1576 let inner_ty = self.infer_expr(*expr, &expectation);
1567 Ty::Ref(Arc::new(inner_ty), *mutability) 1577 Ty::Ref(Arc::new(inner_ty), *mutability)
1568 } 1578 }
1569 Expr::UnaryOp { expr, op } => { 1579 Expr::UnaryOp { expr, op } => {
@@ -1720,7 +1730,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1720pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { 1730pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
1721 db.check_canceled(); 1731 db.check_canceled();
1722 let body = func.body(db); 1732 let body = func.body(db);
1723 let scopes = db.fn_scopes(func); 1733 let scopes = db.expr_scopes(func);
1724 let module = func.module(db); 1734 let module = func.module(db);
1725 let impl_block = func.impl_block(db); 1735 let impl_block = func.impl_block(db);
1726 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); 1736 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 9a571c2aa..37bc3f38c 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -44,7 +44,7 @@ impl CrateImplBlocks {
44 &'a self, 44 &'a self,
45 db: &'a impl HirDatabase, 45 db: &'a impl HirDatabase,
46 ty: &Ty, 46 ty: &Ty,
47 ) -> impl Iterator<Item = ImplBlock> + 'a { 47 ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a {
48 let fingerprint = TyFingerprint::for_impl(ty); 48 let fingerprint = TyFingerprint::for_impl(ty);
49 fingerprint 49 fingerprint
50 .and_then(|f| self.impls.get(&f)) 50 .and_then(|f| self.impls.get(&f))
@@ -52,11 +52,11 @@ impl CrateImplBlocks {
52 .flat_map(|i| i.iter()) 52 .flat_map(|i| i.iter())
53 .map(move |(module_id, impl_id)| { 53 .map(move |(module_id, impl_id)| {
54 let module = Module { 54 let module = Module {
55 krate: self.krate.crate_id, 55 krate: self.krate,
56 module_id: *module_id, 56 module_id: *module_id,
57 }; 57 };
58 let module_impl_blocks = db.impls_in_module(module); 58 let module_impl_blocks = db.impls_in_module(module);
59 ImplBlock::from_id(module_impl_blocks, *impl_id) 59 (module, ImplBlock::from_id(module_impl_blocks, *impl_id))
60 }) 60 })
61 } 61 }
62 62
@@ -152,7 +152,7 @@ impl Ty {
152 }; 152 };
153 let impls = db.impls_in_crate(krate); 153 let impls = db.impls_in_crate(krate);
154 154
155 for impl_block in impls.lookup_impl_blocks(db, &derefed_ty) { 155 for (_, impl_block) in impls.lookup_impl_blocks(db, &derefed_ty) {
156 for item in impl_block.items() { 156 for item in impl_block.items() {
157 match item { 157 match item {
158 ImplItem::Method(f) => { 158 ImplItem::Method(f) => {
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
index 2719f592e..48c83cbb2 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
@@ -1,10 +1,10 @@
1--- 1---
2created: "2019-01-22T14:44:59.880187500+00:00" 2created: "2019-01-28T21:58:55.559331849+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: crates/ra_hir/src/ty/tests.rs
6--- 6---
7[68; 262) '{ ... d; }': () 7[68; 289) '{ ... d; }': ()
8[78; 79) 'e': E 8[78; 79) 'e': E
9[82; 95) 'E::A { x: 3 }': E 9[82; 95) 'E::A { x: 3 }': E
10[92; 93) '3': usize 10[92; 93) '3': usize
@@ -15,15 +15,18 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs"
15[129; 148) 'E::A {..._var }': E 15[129; 148) 'E::A {..._var }': E
16[139; 146) 'new_var': usize 16[139; 146) 'new_var': usize
17[151; 152) 'e': E 17[151; 152) 'e': E
18[159; 218) 'match ... }': usize 18[159; 245) 'match ... }': usize
19[165; 166) 'e': E 19[165; 166) 'e': E
20[177; 187) 'E::A { x }': E 20[177; 187) 'E::A { x }': E
21[184; 185) 'x': usize 21[184; 185) 'x': usize
22[191; 192) 'x': usize 22[191; 192) 'x': usize
23[202; 206) 'E::B': E 23[202; 206) 'E::B': E
24[210; 211) '1': usize 24[210; 213) 'foo': bool
25[229; 248) 'ref d ...{ .. }': &E 25[217; 218) '1': usize
26[237; 248) 'E::A { .. }': E 26[228; 232) 'E::B': E
27[251; 252) 'e': E 27[236; 238) '10': usize
28[258; 259) 'd': &E 28[256; 275) 'ref d ...{ .. }': &E
29[264; 275) 'E::A { .. }': E
30[278; 279) 'e': E
31[285; 286) 'd': &E
29 32
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap
index 3f2faa598..042248c35 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap
@@ -1,12 +1,12 @@
1--- 1---
2created: "2019-01-22T14:44:59.880187500+00:00" 2created: "2019-01-30T20:08:05.185312835+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: crates/ra_hir/src/ty/tests.rs
6--- 6---
7[9; 10) 'x': &str 7[9; 10) 'x': &str
8[18; 19) 'y': isize 8[18; 19) 'y': isize
9[28; 293) '{ ... []; }': () 9[28; 324) '{ ... 3]; }': ()
10[38; 39) 'a': [&str] 10[38; 39) 'a': [&str]
11[42; 45) '[x]': [&str] 11[42; 45) '[x]': [&str]
12[43; 44) 'x': &str 12[43; 44) 'x': &str
@@ -56,4 +56,10 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs"
56[260; 263) '"b"': &str 56[260; 263) '"b"': &str
57[275; 276) 'x': [u8] 57[275; 276) 'x': [u8]
58[288; 290) '[]': [u8] 58[288; 290) '[]': [u8]
59[300; 301) 'z': &[u8]
60[311; 321) '&[1, 2, 3]': &[u8]
61[312; 321) '[1, 2, 3]': [u8]
62[313; 314) '1': u8
63[316; 317) '2': u8
64[319; 320) '3': u8
59 65
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index b36e6ec47..cb8d6351d 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -371,6 +371,7 @@ fn test(x: &str, y: isize) {
371 371
372 let b = [a, ["b"]]; 372 let b = [a, ["b"]];
373 let x: [u8; 0] = []; 373 let x: [u8; 0] = [];
374 let z: &[u8] = &[1, 2, 3];
374} 375}
375"#, 376"#,
376 ); 377 );
@@ -426,7 +427,8 @@ fn test() {
426 427
427 match e { 428 match e {
428 E::A { x } => x, 429 E::A { x } => x,
429 E::B => 1, 430 E::B if foo => 1,
431 E::B => 10,
430 }; 432 };
431 433
432 let ref d @ E::A { .. } = e; 434 let ref d @ E::A { .. } = e;