aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/expr.rs26
-rw-r--r--crates/ra_hir/src/resolve.rs31
-rw-r--r--crates/ra_hir/src/source_binder.rs6
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs5
4 files changed, 35 insertions, 33 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 8c4c63fda..3ca0a4de5 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -13,7 +13,7 @@ use crate::{
13 diagnostics::{MissingFields, MissingOkInTailExpr}, 13 diagnostics::{MissingFields, MissingOkInTailExpr},
14 resolve::HasResolver, 14 resolve::HasResolver,
15 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, 15 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
16 Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, 16 Adt, Function, Name, Path,
17}; 17};
18 18
19pub use hir_def::{ 19pub use hir_def::{
@@ -27,30 +27,6 @@ pub use hir_def::{
27 }, 27 },
28}; 28};
29 29
30// needs arbitrary_self_types to be a method... or maybe move to the def?
31pub(crate) fn resolver_for_expr(
32 db: &impl HirDatabase,
33 owner: DefWithBody,
34 expr_id: ExprId,
35) -> Resolver {
36 let scopes = owner.expr_scopes(db);
37 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
38}
39
40pub(crate) fn resolver_for_scope(
41 db: &impl HirDatabase,
42 owner: DefWithBody,
43 scope_id: Option<ScopeId>,
44) -> Resolver {
45 let mut r = owner.resolver(db);
46 let scopes = owner.expr_scopes(db);
47 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
48 for scope in scope_chain.into_iter().rev() {
49 r = r.push_expr_scope(owner.into(), Arc::clone(&scopes), scope);
50 }
51 r
52}
53
54pub(crate) struct ExprValidator<'a, 'b: 'a> { 30pub(crate) struct ExprValidator<'a, 'b: 'a> {
55 func: Function, 31 func: Function,
56 infer: Arc<InferenceResult>, 32 infer: Arc<InferenceResult>,
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index f4165babd..899959532 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -4,6 +4,7 @@ use std::sync::Arc;
4use hir_def::{ 4use hir_def::{
5 builtin_type::BuiltinType, 5 builtin_type::BuiltinType,
6 db::DefDatabase2, 6 db::DefDatabase2,
7 expr::ExprId,
7 generics::GenericParams, 8 generics::GenericParams,
8 nameres::CrateDefMap, 9 nameres::CrateDefMap,
9 path::{Path, PathKind}, 10 path::{Path, PathKind},
@@ -15,10 +16,10 @@ use rustc_hash::FxHashSet;
15 16
16use crate::{ 17use crate::{
17 code_model::Crate, 18 code_model::Crate,
18 db::DefDatabase, 19 db::{DefDatabase, HirDatabase},
19 expr::{ExprScopes, PatId, ScopeId}, 20 expr::{ExprScopes, PatId, ScopeId},
20 Adt, Const, Container, DefWithBody, EnumVariant, Function, GenericDef, ImplBlock, Local, 21 Adt, Const, Container, DefWithBody, EnumVariant, Function, GenericDef, HasBody, ImplBlock,
21 MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, 22 Local, MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias,
22}; 23};
23 24
24#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -492,6 +493,30 @@ impl Scope {
492 } 493 }
493} 494}
494 495
496// needs arbitrary_self_types to be a method... or maybe move to the def?
497pub(crate) fn resolver_for_expr(
498 db: &impl HirDatabase,
499 owner: DefWithBody,
500 expr_id: ExprId,
501) -> Resolver {
502 let scopes = owner.expr_scopes(db);
503 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
504}
505
506pub(crate) fn resolver_for_scope(
507 db: &impl HirDatabase,
508 owner: DefWithBody,
509 scope_id: Option<ScopeId>,
510) -> Resolver {
511 let mut r = owner.resolver(db);
512 let scopes = owner.expr_scopes(db);
513 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
514 for scope in scope_chain.into_iter().rev() {
515 r = r.push_expr_scope(owner.into(), Arc::clone(&scopes), scope);
516 }
517 r
518}
519
495pub(crate) trait HasResolver { 520pub(crate) trait HasResolver {
496 /// Builds a resolver for type references inside this def. 521 /// Builds a resolver for type references inside this def.
497 fn resolver(self, db: &impl DefDatabase) -> Resolver; 522 fn resolver(self, db: &impl DefDatabase) -> Resolver;
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 5abb8d693..29c928d51 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -21,9 +21,9 @@ use ra_syntax::{
21 21
22use crate::{ 22use crate::{
23 db::HirDatabase, 23 db::HirDatabase,
24 expr::{self, BodySourceMap, ExprScopes, ScopeId}, 24 expr::{BodySourceMap, ExprScopes, ScopeId},
25 ids::LocationCtx, 25 ids::LocationCtx,
26 resolve::{HasResolver, ScopeDef, TypeNs, ValueNs}, 26 resolve::{resolver_for_scope, HasResolver, ScopeDef, TypeNs, ValueNs},
27 ty::method_resolution::{self, implements_trait}, 27 ty::method_resolution::{self, implements_trait},
28 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, 28 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
29 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, 29 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static,
@@ -160,7 +160,7 @@ impl SourceAnalyzer {
160 None => scope_for(&scopes, &source_map, node), 160 None => scope_for(&scopes, &source_map, node),
161 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), 161 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
162 }; 162 };
163 let resolver = expr::resolver_for_scope(db, def, scope); 163 let resolver = resolver_for_scope(db, def, scope);
164 SourceAnalyzer { 164 SourceAnalyzer {
165 resolver, 165 resolver,
166 body_owner: Some(def), 166 body_owner: Some(def),
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index 5e68a1678..414b06ba1 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -12,8 +12,9 @@ use hir_expand::name;
12use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 12use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
13use crate::{ 13use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 expr::{self, Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 15 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
16 generics::{GenericParams, HasGenericParams}, 16 generics::{GenericParams, HasGenericParams},
17 resolve::resolver_for_expr,
17 ty::{ 18 ty::{
18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, 19 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace,
19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 20 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
@@ -186,7 +187,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
186 } 187 }
187 Expr::Path(p) => { 188 Expr::Path(p) => {
188 // FIXME this could be more efficient... 189 // FIXME this could be more efficient...
189 let resolver = expr::resolver_for_expr(self.db, self.owner, tgt_expr); 190 let resolver = resolver_for_expr(self.db, self.owner, tgt_expr);
190 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 191 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
191 } 192 }
192 Expr::Continue => Ty::simple(TypeCtor::Never), 193 Expr::Continue => Ty::simple(TypeCtor::Never),