aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/Cargo.toml2
-rw-r--r--crates/ra_hir/src/code_model.rs179
-rw-r--r--crates/ra_hir/src/db.rs10
-rw-r--r--crates/ra_hir/src/diagnostics.rs8
-rw-r--r--crates/ra_hir/src/has_source.rs42
-rw-r--r--crates/ra_hir/src/lib.rs32
-rw-r--r--crates/ra_hir/src/semantics.rs381
-rw-r--r--crates/ra_hir/src/semantics/source_to_def.rs81
-rw-r--r--crates/ra_hir/src/source_analyzer.rs41
9 files changed, 522 insertions, 254 deletions
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index ba7b39a19..c260bb193 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -3,6 +3,7 @@ edition = "2018"
3name = "ra_hir" 3name = "ra_hir"
4version = "0.1.0" 4version = "0.1.0"
5authors = ["rust-analyzer developers"] 5authors = ["rust-analyzer developers"]
6license = "MIT OR Apache-2.0"
6 7
7[lib] 8[lib]
8doctest = false 9doctest = false
@@ -15,6 +16,7 @@ arrayvec = "0.5.1"
15 16
16itertools = "0.9.0" 17itertools = "0.9.0"
17 18
19stdx = { path = "../stdx" }
18ra_syntax = { path = "../ra_syntax" } 20ra_syntax = { path = "../ra_syntax" }
19ra_db = { path = "../ra_db" } 21ra_db = { path = "../ra_db" }
20ra_prof = { path = "../ra_prof" } 22ra_prof = { path = "../ra_prof" }
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 8c5e1b746..5d88c5c64 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1,5 +1,5 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use std::sync::Arc; 2use std::{iter, sync::Arc};
3 3
4use arrayvec::ArrayVec; 4use arrayvec::ArrayVec;
5use either::Either; 5use either::Either;
@@ -12,6 +12,7 @@ use hir_def::{
12 import_map, 12 import_map,
13 per_ns::PerNs, 13 per_ns::PerNs,
14 resolver::{HasResolver, Resolver}, 14 resolver::{HasResolver, Resolver},
15 src::HasSource as _,
15 type_ref::{Mutability, TypeRef}, 16 type_ref::{Mutability, TypeRef},
16 AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, 17 AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule,
17 ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, StructId, 18 ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, StructId,
@@ -25,21 +26,22 @@ use hir_expand::{
25use hir_ty::{ 26use hir_ty::{
26 autoderef, 27 autoderef,
27 display::{HirDisplayError, HirFormatter}, 28 display::{HirDisplayError, HirFormatter},
28 expr::ExprValidator, 29 method_resolution, ApplicationTy, CallableDefId, Canonical, FnSig, GenericPredicate,
29 method_resolution, 30 InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor,
30 unsafe_validation::UnsafeValidator,
31 ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs, TraitEnvironment, Ty,
32 TyDefId, TypeCtor,
33}; 31};
34use ra_db::{CrateId, CrateName, Edition, FileId}; 32use ra_db::{CrateId, Edition, FileId};
35use ra_prof::profile; 33use ra_prof::profile;
36use ra_syntax::ast::{self, AttrsOwner, NameOwner}; 34use ra_syntax::{
35 ast::{self, AttrsOwner, NameOwner},
36 AstNode,
37};
37use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::impl_from;
38 40
39use crate::{ 41use crate::{
40 db::{DefDatabase, HirDatabase}, 42 db::{DefDatabase, HirDatabase},
41 has_source::HasSource, 43 has_source::HasSource,
42 CallableDef, HirDisplay, InFile, Name, 44 HirDisplay, InFile, Name,
43}; 45};
44 46
45/// hir::Crate describes a single crate. It's the main interface with which 47/// hir::Crate describes a single crate. It's the main interface with which
@@ -94,8 +96,8 @@ impl Crate {
94 db.crate_graph()[self.id].edition 96 db.crate_graph()[self.id].edition
95 } 97 }
96 98
97 pub fn display_name(self, db: &dyn HirDatabase) -> Option<CrateName> { 99 pub fn display_name(self, db: &dyn HirDatabase) -> Option<String> {
98 db.crate_graph()[self.id].display_name.as_ref().cloned() 100 db.crate_graph()[self.id].display_name.clone()
99 } 101 }
100 102
101 pub fn query_external_importables( 103 pub fn query_external_importables(
@@ -139,8 +141,8 @@ pub enum ModuleDef {
139 TypeAlias(TypeAlias), 141 TypeAlias(TypeAlias),
140 BuiltinType(BuiltinType), 142 BuiltinType(BuiltinType),
141} 143}
142impl_froms!( 144impl_from!(
143 ModuleDef: Module, 145 Module,
144 Function, 146 Function,
145 Adt(Struct, Enum, Union), 147 Adt(Struct, Enum, Union),
146 EnumVariant, 148 EnumVariant,
@@ -149,6 +151,7 @@ impl_froms!(
149 Trait, 151 Trait,
150 TypeAlias, 152 TypeAlias,
151 BuiltinType 153 BuiltinType
154 for ModuleDef
152); 155);
153 156
154impl ModuleDef { 157impl ModuleDef {
@@ -376,8 +379,8 @@ pub struct Field {
376 379
377#[derive(Debug, PartialEq, Eq)] 380#[derive(Debug, PartialEq, Eq)]
378pub enum FieldSource { 381pub enum FieldSource {
379 Named(ast::RecordFieldDef), 382 Named(ast::RecordField),
380 Pos(ast::TupleFieldDef), 383 Pos(ast::TupleField),
381} 384}
382 385
383impl Field { 386impl Field {
@@ -556,7 +559,7 @@ pub enum Adt {
556 Union(Union), 559 Union(Union),
557 Enum(Enum), 560 Enum(Enum),
558} 561}
559impl_froms!(Adt: Struct, Union, Enum); 562impl_from!(Struct, Union, Enum for Adt);
560 563
561impl Adt { 564impl Adt {
562 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 565 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
@@ -599,7 +602,7 @@ pub enum VariantDef {
599 Union(Union), 602 Union(Union),
600 EnumVariant(EnumVariant), 603 EnumVariant(EnumVariant),
601} 604}
602impl_froms!(VariantDef: Struct, Union, EnumVariant); 605impl_from!(Struct, Union, EnumVariant for VariantDef);
603 606
604impl VariantDef { 607impl VariantDef {
605 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { 608 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
@@ -642,8 +645,7 @@ pub enum DefWithBody {
642 Static(Static), 645 Static(Static),
643 Const(Const), 646 Const(Const),
644} 647}
645 648impl_from!(Function, Const, Static for DefWithBody);
646impl_froms!(DefWithBody: Function, Const, Static);
647 649
648impl DefWithBody { 650impl DefWithBody {
649 pub fn module(self, db: &dyn HirDatabase) -> Module { 651 pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -694,13 +696,7 @@ impl Function {
694 } 696 }
695 697
696 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 698 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
697 let _p = profile("Function::diagnostics"); 699 hir_ty::diagnostics::validate_body(db, self.id.into(), sink)
698 let infer = db.infer(self.id.into());
699 infer.add_diagnostics(db, self.id, sink);
700 let mut validator = ExprValidator::new(self.id, infer.clone(), sink);
701 validator.validate_body(db);
702 let mut validator = UnsafeValidator::new(self.id, infer, sink);
703 validator.validate_body(db);
704 } 700 }
705} 701}
706 702
@@ -945,14 +941,15 @@ pub enum GenericDef {
945 // consts can have type parameters from their parents (i.e. associated consts of traits) 941 // consts can have type parameters from their parents (i.e. associated consts of traits)
946 Const(Const), 942 Const(Const),
947} 943}
948impl_froms!( 944impl_from!(
949 GenericDef: Function, 945 Function,
950 Adt(Struct, Enum, Union), 946 Adt(Struct, Enum, Union),
951 Trait, 947 Trait,
952 TypeAlias, 948 TypeAlias,
953 ImplDef, 949 ImplDef,
954 EnumVariant, 950 EnumVariant,
955 Const 951 Const
952 for GenericDef
956); 953);
957 954
958impl GenericDef { 955impl GenericDef {
@@ -973,6 +970,16 @@ pub struct Local {
973} 970}
974 971
975impl Local { 972impl Local {
973 pub fn is_param(self, db: &dyn HirDatabase) -> bool {
974 let src = self.source(db);
975 match src.value {
976 Either::Left(bind_pat) => {
977 bind_pat.syntax().ancestors().any(|it| ast::Param::can_cast(it.kind()))
978 }
979 Either::Right(_self_param) => true,
980 }
981 }
982
976 // FIXME: why is this an option? It shouldn't be? 983 // FIXME: why is this an option? It shouldn't be?
977 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 984 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
978 let body = db.body(self.parent.into()); 985 let body = db.body(self.parent.into());
@@ -1071,12 +1078,14 @@ pub struct ImplDef {
1071 1078
1072impl ImplDef { 1079impl ImplDef {
1073 pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<ImplDef> { 1080 pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<ImplDef> {
1074 let impls = db.impls_in_crate(krate.id); 1081 let inherent = db.inherent_impls_in_crate(krate.id);
1075 impls.all_impls().map(Self::from).collect() 1082 let trait_ = db.trait_impls_in_crate(krate.id);
1083
1084 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1076 } 1085 }
1077 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplDef> { 1086 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplDef> {
1078 let impls = db.impls_in_crate(krate.id); 1087 let impls = db.trait_impls_in_crate(krate.id);
1079 impls.lookup_impl_defs_for_trait(trait_.id).map(Self::from).collect() 1088 impls.for_trait(trait_.id).map(Self::from).collect()
1080 } 1089 }
1081 1090
1082 pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1091 pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
@@ -1178,6 +1187,12 @@ impl Type {
1178 Type::new(db, krate, def, ty) 1187 Type::new(db, krate, def, ty)
1179 } 1188 }
1180 1189
1190 pub fn is_unit(&self) -> bool {
1191 matches!(
1192 self.ty.value,
1193 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. })
1194 )
1195 }
1181 pub fn is_bool(&self) -> bool { 1196 pub fn is_bool(&self) -> bool {
1182 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) 1197 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }))
1183 } 1198 }
@@ -1205,7 +1220,7 @@ impl Type {
1205 None => return false, 1220 None => return false,
1206 }; 1221 };
1207 1222
1208 let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1223 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1209 method_resolution::implements_trait( 1224 method_resolution::implements_trait(
1210 &canonical_ty, 1225 &canonical_ty,
1211 db, 1226 db,
@@ -1229,15 +1244,20 @@ impl Type {
1229 self.ty.environment.clone(), 1244 self.ty.environment.clone(),
1230 hir_ty::Obligation::Trait(trait_ref), 1245 hir_ty::Obligation::Trait(trait_ref),
1231 ), 1246 ),
1232 num_vars: 0, 1247 kinds: Arc::new([]),
1233 }; 1248 };
1234 1249
1235 db.trait_solve(self.krate, goal).is_some() 1250 db.trait_solve(self.krate, goal).is_some()
1236 } 1251 }
1237 1252
1238 // FIXME: this method is broken, as it doesn't take closures into account. 1253 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1239 pub fn as_callable(&self) -> Option<CallableDef> { 1254 let def = match self.ty.value {
1240 Some(self.ty.value.as_callable()?.0) 1255 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def),
1256 _ => None,
1257 };
1258
1259 let sig = self.ty.value.callable_sig(db)?;
1260 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1241 } 1261 }
1242 1262
1243 pub fn is_closure(&self) -> bool { 1263 pub fn is_closure(&self) -> bool {
@@ -1304,7 +1324,7 @@ impl Type {
1304 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1324 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
1305 // There should be no inference vars in types passed here 1325 // There should be no inference vars in types passed here
1306 // FIXME check that? 1326 // FIXME check that?
1307 let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1327 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1308 let environment = self.ty.environment.clone(); 1328 let environment = self.ty.environment.clone();
1309 let ty = InEnvironment { value: canonical, environment }; 1329 let ty = InEnvironment { value: canonical, environment };
1310 autoderef(db, Some(self.krate), ty) 1330 autoderef(db, Some(self.krate), ty)
@@ -1321,10 +1341,10 @@ impl Type {
1321 mut callback: impl FnMut(AssocItem) -> Option<T>, 1341 mut callback: impl FnMut(AssocItem) -> Option<T>,
1322 ) -> Option<T> { 1342 ) -> Option<T> {
1323 for krate in self.ty.value.def_crates(db, krate.id)? { 1343 for krate in self.ty.value.def_crates(db, krate.id)? {
1324 let impls = db.impls_in_crate(krate); 1344 let impls = db.inherent_impls_in_crate(krate);
1325 1345
1326 for impl_def in impls.lookup_impl_defs(&self.ty.value) { 1346 for impl_def in impls.for_self_ty(&self.ty.value) {
1327 for &item in db.impl_data(impl_def).items.iter() { 1347 for &item in db.impl_data(*impl_def).items.iter() {
1328 if let Some(result) = callback(item.into()) { 1348 if let Some(result) = callback(item.into()) {
1329 return Some(result); 1349 return Some(result);
1330 } 1350 }
@@ -1345,7 +1365,7 @@ impl Type {
1345 // There should be no inference vars in types passed here 1365 // There should be no inference vars in types passed here
1346 // FIXME check that? 1366 // FIXME check that?
1347 // FIXME replace Unknown by bound vars here 1367 // FIXME replace Unknown by bound vars here
1348 let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1368 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1349 1369
1350 let env = self.ty.environment.clone(); 1370 let env = self.ty.environment.clone();
1351 let krate = krate.id; 1371 let krate = krate.id;
@@ -1376,7 +1396,7 @@ impl Type {
1376 // There should be no inference vars in types passed here 1396 // There should be no inference vars in types passed here
1377 // FIXME check that? 1397 // FIXME check that?
1378 // FIXME replace Unknown by bound vars here 1398 // FIXME replace Unknown by bound vars here
1379 let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1399 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1380 1400
1381 let env = self.ty.environment.clone(); 1401 let env = self.ty.environment.clone();
1382 let krate = krate.id; 1402 let krate = krate.id;
@@ -1522,6 +1542,74 @@ impl HirDisplay for Type {
1522 } 1542 }
1523} 1543}
1524 1544
1545// FIXME: closures
1546#[derive(Debug)]
1547pub struct Callable {
1548 ty: Type,
1549 sig: FnSig,
1550 def: Option<CallableDefId>,
1551 pub(crate) is_bound_method: bool,
1552}
1553
1554pub enum CallableKind {
1555 Function(Function),
1556 TupleStruct(Struct),
1557 TupleEnumVariant(EnumVariant),
1558 Closure,
1559}
1560
1561impl Callable {
1562 pub fn kind(&self) -> CallableKind {
1563 match self.def {
1564 Some(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()),
1565 Some(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()),
1566 Some(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()),
1567 None => CallableKind::Closure,
1568 }
1569 }
1570 pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<ast::SelfParam> {
1571 let func = match self.def {
1572 Some(CallableDefId::FunctionId(it)) if self.is_bound_method => it,
1573 _ => return None,
1574 };
1575 let src = func.lookup(db.upcast()).source(db.upcast());
1576 let param_list = src.value.param_list()?;
1577 param_list.self_param()
1578 }
1579 pub fn n_params(&self) -> usize {
1580 self.sig.params().len() - if self.is_bound_method { 1 } else { 0 }
1581 }
1582 pub fn params(
1583 &self,
1584 db: &dyn HirDatabase,
1585 ) -> Vec<(Option<Either<ast::SelfParam, ast::Pat>>, Type)> {
1586 let types = self
1587 .sig
1588 .params()
1589 .iter()
1590 .skip(if self.is_bound_method { 1 } else { 0 })
1591 .map(|ty| self.ty.derived(ty.clone()));
1592 let patterns = match self.def {
1593 Some(CallableDefId::FunctionId(func)) => {
1594 let src = func.lookup(db.upcast()).source(db.upcast());
1595 src.value.param_list().map(|param_list| {
1596 param_list
1597 .self_param()
1598 .map(|it| Some(Either::Left(it)))
1599 .filter(|_| !self.is_bound_method)
1600 .into_iter()
1601 .chain(param_list.params().map(|it| it.pat().map(Either::Right)))
1602 })
1603 }
1604 _ => None,
1605 };
1606 patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect()
1607 }
1608 pub fn return_type(&self) -> Type {
1609 self.ty.derived(self.sig.ret().clone())
1610 }
1611}
1612
1525/// For IDE only 1613/// For IDE only
1526#[derive(Debug)] 1614#[derive(Debug)]
1527pub enum ScopeDef { 1615pub enum ScopeDef {
@@ -1581,8 +1669,8 @@ pub enum AttrDef {
1581 MacroDef(MacroDef), 1669 MacroDef(MacroDef),
1582} 1670}
1583 1671
1584impl_froms!( 1672impl_from!(
1585 AttrDef: Module, 1673 Module,
1586 Field, 1674 Field,
1587 Adt(Struct, Enum, Union), 1675 Adt(Struct, Enum, Union),
1588 EnumVariant, 1676 EnumVariant,
@@ -1592,6 +1680,7 @@ impl_froms!(
1592 Trait, 1680 Trait,
1593 TypeAlias, 1681 TypeAlias,
1594 MacroDef 1682 MacroDef
1683 for AttrDef
1595); 1684);
1596 1685
1597pub trait HasAttrs { 1686pub trait HasAttrs {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index bb67952de..a2b9f3e35 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -11,15 +11,15 @@ pub use hir_def::db::{
11}; 11};
12pub use hir_expand::db::{ 12pub use hir_expand::db::{
13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery, 13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,
14 MacroArgQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery, 14 MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery,
15}; 15};
16pub use hir_ty::db::{ 16pub use hir_ty::db::{
17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery, 17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery,
18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase, 18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase,
19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, ImplsFromDepsQuery, 19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, InferQueryQuery,
20 ImplsInCrateQuery, InferQueryQuery, InternAssocTyValueQuery, InternChalkImplQuery, 20 InherentImplsInCrateQuery, InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery,
21 InternTypeCtorQuery, InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery, 21 TraitDatumQuery, TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery,
22 TraitDatumQuery, TraitSolveQuery, TyQuery, ValueTyQuery, 22 ValueTyQuery,
23}; 23};
24 24
25#[test] 25#[test]
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs
index c82883d0c..266b513dc 100644
--- a/crates/ra_hir/src/diagnostics.rs
+++ b/crates/ra_hir/src/diagnostics.rs
@@ -1,4 +1,8 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2pub use hir_def::diagnostics::UnresolvedModule; 2pub use hir_def::diagnostics::UnresolvedModule;
3pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; 3pub use hir_expand::diagnostics::{
4pub use hir_ty::diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField}; 4 AstDiagnostic, Diagnostic, DiagnosticSink, DiagnosticSinkBuilder,
5};
6pub use hir_ty::diagnostics::{
7 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField,
8};
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs
index 76c32fc17..1c691d961 100644
--- a/crates/ra_hir/src/has_source.rs
+++ b/crates/ra_hir/src/has_source.rs
@@ -57,56 +57,56 @@ impl HasSource for Field {
57 } 57 }
58} 58}
59impl HasSource for Struct { 59impl HasSource for Struct {
60 type Ast = ast::StructDef; 60 type Ast = ast::Struct;
61 fn source(self, db: &dyn HirDatabase) -> InFile<ast::StructDef> { 61 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Struct> {
62 self.id.lookup(db.upcast()).source(db.upcast()) 62 self.id.lookup(db.upcast()).source(db.upcast())
63 } 63 }
64} 64}
65impl HasSource for Union { 65impl HasSource for Union {
66 type Ast = ast::UnionDef; 66 type Ast = ast::Union;
67 fn source(self, db: &dyn HirDatabase) -> InFile<ast::UnionDef> { 67 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Union> {
68 self.id.lookup(db.upcast()).source(db.upcast()) 68 self.id.lookup(db.upcast()).source(db.upcast())
69 } 69 }
70} 70}
71impl HasSource for Enum { 71impl HasSource for Enum {
72 type Ast = ast::EnumDef; 72 type Ast = ast::Enum;
73 fn source(self, db: &dyn HirDatabase) -> InFile<ast::EnumDef> { 73 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Enum> {
74 self.id.lookup(db.upcast()).source(db.upcast()) 74 self.id.lookup(db.upcast()).source(db.upcast())
75 } 75 }
76} 76}
77impl HasSource for EnumVariant { 77impl HasSource for EnumVariant {
78 type Ast = ast::EnumVariant; 78 type Ast = ast::Variant;
79 fn source(self, db: &dyn HirDatabase) -> InFile<ast::EnumVariant> { 79 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> {
80 self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone()) 80 self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone())
81 } 81 }
82} 82}
83impl HasSource for Function { 83impl HasSource for Function {
84 type Ast = ast::FnDef; 84 type Ast = ast::Fn;
85 fn source(self, db: &dyn HirDatabase) -> InFile<ast::FnDef> { 85 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Fn> {
86 self.id.lookup(db.upcast()).source(db.upcast()) 86 self.id.lookup(db.upcast()).source(db.upcast())
87 } 87 }
88} 88}
89impl HasSource for Const { 89impl HasSource for Const {
90 type Ast = ast::ConstDef; 90 type Ast = ast::Const;
91 fn source(self, db: &dyn HirDatabase) -> InFile<ast::ConstDef> { 91 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Const> {
92 self.id.lookup(db.upcast()).source(db.upcast()) 92 self.id.lookup(db.upcast()).source(db.upcast())
93 } 93 }
94} 94}
95impl HasSource for Static { 95impl HasSource for Static {
96 type Ast = ast::StaticDef; 96 type Ast = ast::Static;
97 fn source(self, db: &dyn HirDatabase) -> InFile<ast::StaticDef> { 97 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Static> {
98 self.id.lookup(db.upcast()).source(db.upcast()) 98 self.id.lookup(db.upcast()).source(db.upcast())
99 } 99 }
100} 100}
101impl HasSource for Trait { 101impl HasSource for Trait {
102 type Ast = ast::TraitDef; 102 type Ast = ast::Trait;
103 fn source(self, db: &dyn HirDatabase) -> InFile<ast::TraitDef> { 103 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Trait> {
104 self.id.lookup(db.upcast()).source(db.upcast()) 104 self.id.lookup(db.upcast()).source(db.upcast())
105 } 105 }
106} 106}
107impl HasSource for TypeAlias { 107impl HasSource for TypeAlias {
108 type Ast = ast::TypeAliasDef; 108 type Ast = ast::TypeAlias;
109 fn source(self, db: &dyn HirDatabase) -> InFile<ast::TypeAliasDef> { 109 fn source(self, db: &dyn HirDatabase) -> InFile<ast::TypeAlias> {
110 self.id.lookup(db.upcast()).source(db.upcast()) 110 self.id.lookup(db.upcast()).source(db.upcast())
111 } 111 }
112} 112}
@@ -120,14 +120,14 @@ impl HasSource for MacroDef {
120 } 120 }
121} 121}
122impl HasSource for ImplDef { 122impl HasSource for ImplDef {
123 type Ast = ast::ImplDef; 123 type Ast = ast::Impl;
124 fn source(self, db: &dyn HirDatabase) -> InFile<ast::ImplDef> { 124 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Impl> {
125 self.id.lookup(db.upcast()).source(db.upcast()) 125 self.id.lookup(db.upcast()).source(db.upcast())
126 } 126 }
127} 127}
128 128
129impl HasSource for TypeParam { 129impl HasSource for TypeParam {
130 type Ast = Either<ast::TraitDef, ast::TypeParam>; 130 type Ast = Either<ast::Trait, ast::TypeParam>;
131 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> { 131 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
132 let child_source = self.id.parent.child_source(db.upcast()); 132 let child_source = self.id.parent.child_source(db.upcast());
133 child_source.map(|it| it[self.id.local_id].clone()) 133 child_source.map(|it| it[self.id.local_id].clone())
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index fe34b30bc..e2d13dbfd 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -19,25 +19,6 @@
19 19
20#![recursion_limit = "512"] 20#![recursion_limit = "512"]
21 21
22macro_rules! impl_froms {
23 ($e:ident: $($v:ident $(($($sv:ident),*))?),*$(,)?) => {
24 $(
25 impl From<$v> for $e {
26 fn from(it: $v) -> $e {
27 $e::$v(it)
28 }
29 }
30 $($(
31 impl From<$sv> for $e {
32 fn from(it: $sv) -> $e {
33 $e::$v($v::$sv(it))
34 }
35 }
36 )*)?
37 )*
38 }
39}
40
41mod semantics; 22mod semantics;
42pub mod db; 23pub mod db;
43mod source_analyzer; 24mod source_analyzer;
@@ -51,10 +32,10 @@ mod has_source;
51 32
52pub use crate::{ 33pub use crate::{
53 code_model::{ 34 code_model::{
54 Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Const, Crate, CrateDependency, 35 Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Callable, CallableKind, Const,
55 DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, Function, GenericDef, HasAttrs, 36 Crate, CrateDependency, DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, Function,
56 HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, 37 GenericDef, HasAttrs, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef,
57 Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, 38 Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility,
58 }, 39 },
59 has_source::HasSource, 40 has_source::HasSource,
60 semantics::{original_range, PathResolution, Semantics, SemanticsScope}, 41 semantics::{original_range, PathResolution, Semantics, SemanticsScope},
@@ -74,6 +55,7 @@ pub use hir_def::{
74pub use hir_expand::{ 55pub use hir_expand::{
75 hygiene::Hygiene, 56 hygiene::Hygiene,
76 name::{AsName, Name}, 57 name::{AsName, Name},
77 HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, 58 HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, /* FIXME */
59 MacroFile, Origin,
78}; 60};
79pub use hir_ty::{display::HirDisplay, CallableDef}; 61pub use hir_ty::display::HirDisplay;
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 6a49c424a..6f3b3dc9a 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -6,7 +6,7 @@ use std::{cell::RefCell, fmt, iter::successors};
6 6
7use hir_def::{ 7use hir_def::{
8 resolver::{self, HasResolver, Resolver}, 8 resolver::{self, HasResolver, Resolver},
9 AsMacroCall, TraitId, VariantId, 9 AsMacroCall, FunctionId, TraitId, VariantId,
10}; 10};
11use hir_expand::{diagnostics::AstDiagnostic, hygiene::Hygiene, ExpansionInfo}; 11use hir_expand::{diagnostics::AstDiagnostic, hygiene::Hygiene, ExpansionInfo};
12use hir_ty::associated_type_shorthand_candidates; 12use hir_ty::associated_type_shorthand_candidates;
@@ -24,8 +24,8 @@ use crate::{
24 diagnostics::Diagnostic, 24 diagnostics::Diagnostic,
25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
26 source_analyzer::{resolve_hir_path, resolve_hir_path_qualifier, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, resolve_hir_path_qualifier, SourceAnalyzer},
27 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, 27 AssocItem, Callable, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module,
28 Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, 28 ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef,
29}; 29};
30use resolver::TypeNs; 30use resolver::TypeNs;
31 31
@@ -83,7 +83,13 @@ impl PathResolution {
83/// Primary API to get semantic information, like types, from syntax trees. 83/// Primary API to get semantic information, like types, from syntax trees.
84pub struct Semantics<'db, DB> { 84pub struct Semantics<'db, DB> {
85 pub db: &'db DB, 85 pub db: &'db DB,
86 imp: SemanticsImpl<'db>,
87}
88
89pub struct SemanticsImpl<'db> {
90 pub db: &'db dyn HirDatabase,
86 s2d_cache: RefCell<SourceToDefCache>, 91 s2d_cache: RefCell<SourceToDefCache>,
92 expansion_info_cache: RefCell<FxHashMap<HirFileId, Option<ExpansionInfo>>>,
87 cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>, 93 cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
88} 94}
89 95
@@ -95,23 +101,199 @@ impl<DB> fmt::Debug for Semantics<'_, DB> {
95 101
96impl<'db, DB: HirDatabase> Semantics<'db, DB> { 102impl<'db, DB: HirDatabase> Semantics<'db, DB> {
97 pub fn new(db: &DB) -> Semantics<DB> { 103 pub fn new(db: &DB) -> Semantics<DB> {
98 Semantics { db, s2d_cache: Default::default(), cache: Default::default() } 104 let impl_ = SemanticsImpl::new(db);
105 Semantics { db, imp: impl_ }
99 } 106 }
100 107
101 pub fn parse(&self, file_id: FileId) -> ast::SourceFile { 108 pub fn parse(&self, file_id: FileId) -> ast::SourceFile {
102 let tree = self.db.parse(file_id).tree(); 109 self.imp.parse(file_id)
103 self.cache(tree.syntax().clone(), file_id.into());
104 tree
105 } 110 }
106 111
107 pub fn ast<T: AstDiagnostic + Diagnostic>(&self, d: &T) -> <T as AstDiagnostic>::AST { 112 pub fn ast<T: AstDiagnostic + Diagnostic>(&self, d: &T) -> <T as AstDiagnostic>::AST {
108 let file_id = d.source().file_id; 113 let file_id = d.source().file_id;
109 let root = self.db.parse_or_expand(file_id).unwrap(); 114 let root = self.db.parse_or_expand(file_id).unwrap();
110 self.cache(root, file_id); 115 self.imp.cache(root, file_id);
111 d.ast(self.db) 116 d.ast(self.db.upcast())
112 } 117 }
113 118
114 pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { 119 pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
120 self.imp.expand(macro_call)
121 }
122
123 pub fn expand_hypothetical(
124 &self,
125 actual_macro_call: &ast::MacroCall,
126 hypothetical_args: &ast::TokenTree,
127 token_to_map: SyntaxToken,
128 ) -> Option<(SyntaxNode, SyntaxToken)> {
129 self.imp.expand_hypothetical(actual_macro_call, hypothetical_args, token_to_map)
130 }
131
132 pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken {
133 self.imp.descend_into_macros(token)
134 }
135
136 pub fn descend_node_at_offset<N: ast::AstNode>(
137 &self,
138 node: &SyntaxNode,
139 offset: TextSize,
140 ) -> Option<N> {
141 self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
142 }
143
144 pub fn original_range(&self, node: &SyntaxNode) -> FileRange {
145 self.imp.original_range(node)
146 }
147
148 pub fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange {
149 self.imp.diagnostics_range(diagnostics)
150 }
151
152 pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
153 self.imp.ancestors_with_macros(node)
154 }
155
156 pub fn ancestors_at_offset_with_macros(
157 &self,
158 node: &SyntaxNode,
159 offset: TextSize,
160 ) -> impl Iterator<Item = SyntaxNode> + '_ {
161 self.imp.ancestors_at_offset_with_macros(node, offset)
162 }
163
164 /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
165 /// search up until it is of the target AstNode type
166 pub fn find_node_at_offset_with_macros<N: AstNode>(
167 &self,
168 node: &SyntaxNode,
169 offset: TextSize,
170 ) -> Option<N> {
171 self.imp.ancestors_at_offset_with_macros(node, offset).find_map(N::cast)
172 }
173
174 /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*,
175 /// descend it and find again
176 pub fn find_node_at_offset_with_descend<N: AstNode>(
177 &self,
178 node: &SyntaxNode,
179 offset: TextSize,
180 ) -> Option<N> {
181 if let Some(it) = find_node_at_offset(&node, offset) {
182 return Some(it);
183 }
184
185 self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
186 }
187
188 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
189 self.imp.type_of_expr(expr)
190 }
191
192 pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
193 self.imp.type_of_pat(pat)
194 }
195
196 pub fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
197 self.imp.type_of_self(param)
198 }
199
200 pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
201 self.imp.resolve_method_call(call).map(Function::from)
202 }
203
204 pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
205 self.imp.resolve_method_call_as_callable(call)
206 }
207
208 pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
209 self.imp.resolve_field(field)
210 }
211
212 pub fn resolve_record_field(
213 &self,
214 field: &ast::RecordExprField,
215 ) -> Option<(Field, Option<Local>)> {
216 self.imp.resolve_record_field(field)
217 }
218
219 pub fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> {
220 self.imp.resolve_record_field_pat(field)
221 }
222
223 pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> {
224 self.imp.resolve_macro_call(macro_call)
225 }
226
227 pub fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
228 self.imp.resolve_path(path)
229 }
230
231 pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantDef> {
232 self.imp.resolve_variant(record_lit).map(VariantDef::from)
233 }
234
235 pub fn lower_path(&self, path: &ast::Path) -> Option<Path> {
236 self.imp.lower_path(path)
237 }
238
239 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
240 self.imp.resolve_bind_pat_to_const(pat)
241 }
242
243 // FIXME: use this instead?
244 // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
245
246 pub fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> {
247 self.imp.record_literal_missing_fields(literal)
248 }
249
250 pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> {
251 self.imp.record_pattern_missing_fields(pattern)
252 }
253
254 pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
255 let src = self.imp.find_file(src.syntax().clone()).with_value(src).cloned();
256 T::to_def(&self.imp, src)
257 }
258
259 pub fn to_module_def(&self, file: FileId) -> Option<Module> {
260 self.imp.to_module_def(file)
261 }
262
263 pub fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
264 self.imp.scope(node)
265 }
266
267 pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> {
268 self.imp.scope_at_offset(node, offset)
269 }
270
271 pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
272 self.imp.scope_for_def(def)
273 }
274
275 pub fn assert_contains_node(&self, node: &SyntaxNode) {
276 self.imp.assert_contains_node(node)
277 }
278}
279
280impl<'db> SemanticsImpl<'db> {
281 fn new(db: &'db dyn HirDatabase) -> Self {
282 SemanticsImpl {
283 db,
284 s2d_cache: Default::default(),
285 cache: Default::default(),
286 expansion_info_cache: Default::default(),
287 }
288 }
289
290 fn parse(&self, file_id: FileId) -> ast::SourceFile {
291 let tree = self.db.parse(file_id).tree();
292 self.cache(tree.syntax().clone(), file_id.into());
293 tree
294 }
295
296 fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
115 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); 297 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call);
116 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); 298 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None);
117 let file_id = sa.expand(self.db, macro_call)?; 299 let file_id = sa.expand(self.db, macro_call)?;
@@ -120,7 +302,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
120 Some(node) 302 Some(node)
121 } 303 }
122 304
123 pub fn expand_hypothetical( 305 fn expand_hypothetical(
124 &self, 306 &self,
125 actual_macro_call: &ast::MacroCall, 307 actual_macro_call: &ast::MacroCall,
126 hypothetical_args: &ast::TokenTree, 308 hypothetical_args: &ast::TokenTree,
@@ -130,24 +312,38 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
130 self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call); 312 self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call);
131 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); 313 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None);
132 let krate = sa.resolver.krate()?; 314 let krate = sa.resolver.krate()?;
133 let macro_call_id = macro_call 315 let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
134 .as_call_id(self.db, krate, |path| sa.resolver.resolve_path_as_macro(self.db, &path))?; 316 sa.resolver.resolve_path_as_macro(self.db.upcast(), &path)
135 hir_expand::db::expand_hypothetical(self.db, macro_call_id, hypothetical_args, token_to_map) 317 })?;
136 } 318 hir_expand::db::expand_hypothetical(
137 319 self.db.upcast(),
138 pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { 320 macro_call_id,
321 hypothetical_args,
322 token_to_map,
323 )
324 }
325
326 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken {
327 let _p = profile("descend_into_macros");
139 let parent = token.parent(); 328 let parent = token.parent();
140 let parent = self.find_file(parent); 329 let parent = self.find_file(parent);
141 let sa = self.analyze2(parent.as_ref(), None); 330 let sa = self.analyze2(parent.as_ref(), None);
142 331
143 let token = successors(Some(parent.with_value(token)), |token| { 332 let token = successors(Some(parent.with_value(token)), |token| {
333 self.db.check_canceled();
144 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; 334 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
145 let tt = macro_call.token_tree()?; 335 let tt = macro_call.token_tree()?;
146 if !tt.syntax().text_range().contains_range(token.value.text_range()) { 336 if !tt.syntax().text_range().contains_range(token.value.text_range()) {
147 return None; 337 return None;
148 } 338 }
149 let file_id = sa.expand(self.db, token.with_value(&macro_call))?; 339 let file_id = sa.expand(self.db, token.with_value(&macro_call))?;
150 let token = file_id.expansion_info(self.db)?.map_token_down(token.as_ref())?; 340 let token = self
341 .expansion_info_cache
342 .borrow_mut()
343 .entry(file_id)
344 .or_insert_with(|| file_id.expansion_info(self.db.upcast()))
345 .as_ref()?
346 .map_token_down(token.as_ref())?;
151 347
152 self.cache(find_root(&token.value.parent()), token.file_id); 348 self.cache(find_root(&token.value.parent()), token.file_id);
153 349
@@ -159,35 +355,36 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
159 token.value 355 token.value
160 } 356 }
161 357
162 pub fn descend_node_at_offset<N: ast::AstNode>( 358 fn descend_node_at_offset(
163 &self, 359 &self,
164 node: &SyntaxNode, 360 node: &SyntaxNode,
165 offset: TextSize, 361 offset: TextSize,
166 ) -> Option<N> { 362 ) -> impl Iterator<Item = SyntaxNode> + '_ {
167 // Handle macro token cases 363 // Handle macro token cases
168 node.token_at_offset(offset) 364 node.token_at_offset(offset)
169 .map(|token| self.descend_into_macros(token)) 365 .map(|token| self.descend_into_macros(token))
170 .find_map(|it| self.ancestors_with_macros(it.parent()).find_map(N::cast)) 366 .map(|it| self.ancestors_with_macros(it.parent()))
367 .flatten()
171 } 368 }
172 369
173 pub fn original_range(&self, node: &SyntaxNode) -> FileRange { 370 fn original_range(&self, node: &SyntaxNode) -> FileRange {
174 let node = self.find_file(node.clone()); 371 let node = self.find_file(node.clone());
175 original_range(self.db, node.as_ref()) 372 original_range(self.db, node.as_ref())
176 } 373 }
177 374
178 pub fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { 375 fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange {
179 let src = diagnostics.source(); 376 let src = diagnostics.source();
180 let root = self.db.parse_or_expand(src.file_id).unwrap(); 377 let root = self.db.parse_or_expand(src.file_id).unwrap();
181 let node = src.value.to_node(&root); 378 let node = src.value.to_node(&root);
182 original_range(self.db, src.with_value(&node)) 379 original_range(self.db, src.with_value(&node))
183 } 380 }
184 381
185 pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { 382 fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
186 let node = self.find_file(node); 383 let node = self.find_file(node);
187 node.ancestors_with_macros(self.db).map(|it| it.value) 384 node.ancestors_with_macros(self.db.upcast()).map(|it| it.value)
188 } 385 }
189 386
190 pub fn ancestors_at_offset_with_macros( 387 fn ancestors_at_offset_with_macros(
191 &self, 388 &self,
192 node: &SyntaxNode, 389 node: &SyntaxNode,
193 offset: TextSize, 390 offset: TextSize,
@@ -197,120 +394,104 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
197 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) 394 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
198 } 395 }
199 396
200 /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, 397 fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
201 /// search up until it is of the target AstNode type 398 self.analyze(expr.syntax()).type_of_expr(self.db, &expr)
202 pub fn find_node_at_offset_with_macros<N: AstNode>(
203 &self,
204 node: &SyntaxNode,
205 offset: TextSize,
206 ) -> Option<N> {
207 self.ancestors_at_offset_with_macros(node, offset).find_map(N::cast)
208 } 399 }
209 400
210 /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*, 401 fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
211 /// descend it and find again 402 self.analyze(pat.syntax()).type_of_pat(self.db, &pat)
212 pub fn find_node_at_offset_with_descend<N: AstNode>(
213 &self,
214 node: &SyntaxNode,
215 offset: TextSize,
216 ) -> Option<N> {
217 if let Some(it) = find_node_at_offset(&node, offset) {
218 return Some(it);
219 }
220 self.descend_node_at_offset(&node, offset)
221 } 403 }
222 404
223 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { 405 fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
224 self.analyze(expr.syntax()).type_of(self.db, &expr) 406 self.analyze(param.syntax()).type_of_self(self.db, &param)
225 } 407 }
226 408
227 pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { 409 fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> {
228 self.analyze(pat.syntax()).type_of_pat(self.db, &pat) 410 self.analyze(call.syntax()).resolve_method_call(self.db, call)
229 } 411 }
230 412
231 pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { 413 fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
232 self.analyze(call.syntax()).resolve_method_call(self.db, call) 414 // FIXME: this erases Substs
415 let func = self.resolve_method_call(call)?;
416 let ty = self.db.value_ty(func.into());
417 let resolver = self.analyze(call.syntax()).resolver;
418 let ty = Type::new_with_resolver(self.db, &resolver, ty.value)?;
419 let mut res = ty.as_callable(self.db)?;
420 res.is_bound_method = true;
421 Some(res)
233 } 422 }
234 423
235 pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> { 424 fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
236 self.analyze(field.syntax()).resolve_field(self.db, field) 425 self.analyze(field.syntax()).resolve_field(self.db, field)
237 } 426 }
238 427
239 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<(Field, Option<Local>)> { 428 fn resolve_record_field(&self, field: &ast::RecordExprField) -> Option<(Field, Option<Local>)> {
240 self.analyze(field.syntax()).resolve_record_field(self.db, field) 429 self.analyze(field.syntax()).resolve_record_field(self.db, field)
241 } 430 }
242 431
243 pub fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> { 432 fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> {
244 self.analyze(field.syntax()).resolve_record_field_pat(self.db, field) 433 self.analyze(field.syntax()).resolve_record_field_pat(self.db, field)
245 } 434 }
246 435
247 pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> { 436 fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> {
248 let sa = self.analyze(macro_call.syntax()); 437 let sa = self.analyze(macro_call.syntax());
249 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); 438 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call);
250 sa.resolve_macro_call(self.db, macro_call) 439 sa.resolve_macro_call(self.db, macro_call)
251 } 440 }
252 441
253 pub fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> { 442 fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
254 self.analyze(path.syntax()).resolve_path(self.db, path) 443 self.analyze(path.syntax()).resolve_path(self.db, path)
255 } 444 }
256 445
257 pub fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantId> { 446 fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> {
258 self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit) 447 self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit)
259 } 448 }
260 449
261 pub fn lower_path(&self, path: &ast::Path) -> Option<Path> { 450 fn lower_path(&self, path: &ast::Path) -> Option<Path> {
262 let src = self.find_file(path.syntax().clone()); 451 let src = self.find_file(path.syntax().clone());
263 Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into())) 452 Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into()))
264 } 453 }
265 454
266 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { 455 fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
267 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) 456 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat)
268 } 457 }
269 458
270 // FIXME: use this instead? 459 fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> {
271 // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
272
273 pub fn record_literal_missing_fields(&self, literal: &ast::RecordLit) -> Vec<(Field, Type)> {
274 self.analyze(literal.syntax()) 460 self.analyze(literal.syntax())
275 .record_literal_missing_fields(self.db, literal) 461 .record_literal_missing_fields(self.db, literal)
276 .unwrap_or_default() 462 .unwrap_or_default()
277 } 463 }
278 464
279 pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> { 465 fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> {
280 self.analyze(pattern.syntax()) 466 self.analyze(pattern.syntax())
281 .record_pattern_missing_fields(self.db, pattern) 467 .record_pattern_missing_fields(self.db, pattern)
282 .unwrap_or_default() 468 .unwrap_or_default()
283 } 469 }
284 470
285 pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
286 let src = self.find_file(src.syntax().clone()).with_value(src).cloned();
287 T::to_def(self, src)
288 }
289
290 fn with_ctx<F: FnOnce(&mut SourceToDefCtx) -> T, T>(&self, f: F) -> T { 471 fn with_ctx<F: FnOnce(&mut SourceToDefCtx) -> T, T>(&self, f: F) -> T {
291 let mut cache = self.s2d_cache.borrow_mut(); 472 let mut cache = self.s2d_cache.borrow_mut();
292 let mut ctx = SourceToDefCtx { db: self.db, cache: &mut *cache }; 473 let mut ctx = SourceToDefCtx { db: self.db, cache: &mut *cache };
293 f(&mut ctx) 474 f(&mut ctx)
294 } 475 }
295 476
296 pub fn to_module_def(&self, file: FileId) -> Option<Module> { 477 fn to_module_def(&self, file: FileId) -> Option<Module> {
297 self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) 478 self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from)
298 } 479 }
299 480
300 pub fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db, DB> { 481 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
301 let node = self.find_file(node.clone()); 482 let node = self.find_file(node.clone());
302 let resolver = self.analyze2(node.as_ref(), None).resolver; 483 let resolver = self.analyze2(node.as_ref(), None).resolver;
303 SemanticsScope { db: self.db, resolver } 484 SemanticsScope { db: self.db, resolver }
304 } 485 }
305 486
306 pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db, DB> { 487 fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> {
307 let node = self.find_file(node.clone()); 488 let node = self.find_file(node.clone());
308 let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver; 489 let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver;
309 SemanticsScope { db: self.db, resolver } 490 SemanticsScope { db: self.db, resolver }
310 } 491 }
311 492
312 pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db, DB> { 493 fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
313 let resolver = def.id.resolver(self.db); 494 let resolver = def.id.resolver(self.db.upcast());
314 SemanticsScope { db: self.db, resolver } 495 SemanticsScope { db: self.db, resolver }
315 } 496 }
316 497
@@ -331,12 +512,13 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
331 ChildContainer::DefWithBodyId(def) => { 512 ChildContainer::DefWithBodyId(def) => {
332 return SourceAnalyzer::new_for_body(self.db, def, src, offset) 513 return SourceAnalyzer::new_for_body(self.db, def, src, offset)
333 } 514 }
334 ChildContainer::TraitId(it) => it.resolver(self.db), 515 ChildContainer::TraitId(it) => it.resolver(self.db.upcast()),
335 ChildContainer::ImplId(it) => it.resolver(self.db), 516 ChildContainer::ImplId(it) => it.resolver(self.db.upcast()),
336 ChildContainer::ModuleId(it) => it.resolver(self.db), 517 ChildContainer::ModuleId(it) => it.resolver(self.db.upcast()),
337 ChildContainer::EnumId(it) => it.resolver(self.db), 518 ChildContainer::EnumId(it) => it.resolver(self.db.upcast()),
338 ChildContainer::VariantId(it) => it.resolver(self.db), 519 ChildContainer::VariantId(it) => it.resolver(self.db.upcast()),
339 ChildContainer::GenericDefId(it) => it.resolver(self.db), 520 ChildContainer::TypeAliasId(it) => it.resolver(self.db.upcast()),
521 ChildContainer::GenericDefId(it) => it.resolver(self.db.upcast()),
340 }; 522 };
341 SourceAnalyzer::new_for_resolver(resolver, src) 523 SourceAnalyzer::new_for_resolver(resolver, src)
342 } 524 }
@@ -348,7 +530,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
348 assert!(prev == None || prev == Some(file_id)) 530 assert!(prev == None || prev == Some(file_id))
349 } 531 }
350 532
351 pub fn assert_contains_node(&self, node: &SyntaxNode) { 533 fn assert_contains_node(&self, node: &SyntaxNode) {
352 self.find_file(node.clone()); 534 self.find_file(node.clone());
353 } 535 }
354 536
@@ -382,14 +564,14 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
382pub trait ToDef: AstNode + Clone { 564pub trait ToDef: AstNode + Clone {
383 type Def; 565 type Def;
384 566
385 fn to_def<DB: HirDatabase>(sema: &Semantics<DB>, src: InFile<Self>) -> Option<Self::Def>; 567 fn to_def(sema: &SemanticsImpl, src: InFile<Self>) -> Option<Self::Def>;
386} 568}
387 569
388macro_rules! to_def_impls { 570macro_rules! to_def_impls {
389 ($(($def:path, $ast:path, $meth:ident)),* ,) => {$( 571 ($(($def:path, $ast:path, $meth:ident)),* ,) => {$(
390 impl ToDef for $ast { 572 impl ToDef for $ast {
391 type Def = $def; 573 type Def = $def;
392 fn to_def<DB: HirDatabase>(sema: &Semantics<DB>, src: InFile<Self>) -> Option<Self::Def> { 574 fn to_def(sema: &SemanticsImpl, src: InFile<Self>) -> Option<Self::Def> {
393 sema.with_ctx(|ctx| ctx.$meth(src)).map(<$def>::from) 575 sema.with_ctx(|ctx| ctx.$meth(src)).map(<$def>::from)
394 } 576 }
395 } 577 }
@@ -398,18 +580,18 @@ macro_rules! to_def_impls {
398 580
399to_def_impls![ 581to_def_impls![
400 (crate::Module, ast::Module, module_to_def), 582 (crate::Module, ast::Module, module_to_def),
401 (crate::Struct, ast::StructDef, struct_to_def), 583 (crate::Struct, ast::Struct, struct_to_def),
402 (crate::Enum, ast::EnumDef, enum_to_def), 584 (crate::Enum, ast::Enum, enum_to_def),
403 (crate::Union, ast::UnionDef, union_to_def), 585 (crate::Union, ast::Union, union_to_def),
404 (crate::Trait, ast::TraitDef, trait_to_def), 586 (crate::Trait, ast::Trait, trait_to_def),
405 (crate::ImplDef, ast::ImplDef, impl_to_def), 587 (crate::ImplDef, ast::Impl, impl_to_def),
406 (crate::TypeAlias, ast::TypeAliasDef, type_alias_to_def), 588 (crate::TypeAlias, ast::TypeAlias, type_alias_to_def),
407 (crate::Const, ast::ConstDef, const_to_def), 589 (crate::Const, ast::Const, const_to_def),
408 (crate::Static, ast::StaticDef, static_to_def), 590 (crate::Static, ast::Static, static_to_def),
409 (crate::Function, ast::FnDef, fn_to_def), 591 (crate::Function, ast::Fn, fn_to_def),
410 (crate::Field, ast::RecordFieldDef, record_field_to_def), 592 (crate::Field, ast::RecordField, record_field_to_def),
411 (crate::Field, ast::TupleFieldDef, tuple_field_to_def), 593 (crate::Field, ast::TupleField, tuple_field_to_def),
412 (crate::EnumVariant, ast::EnumVariant, enum_variant_to_def), 594 (crate::EnumVariant, ast::Variant, enum_variant_to_def),
413 (crate::TypeParam, ast::TypeParam, type_param_to_def), 595 (crate::TypeParam, ast::TypeParam, type_param_to_def),
414 (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros 596 (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros
415 (crate::Local, ast::BindPat, bind_pat_to_def), 597 (crate::Local, ast::BindPat, bind_pat_to_def),
@@ -419,12 +601,13 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
419 node.ancestors().last().unwrap() 601 node.ancestors().last().unwrap()
420} 602}
421 603
422pub struct SemanticsScope<'a, DB> { 604#[derive(Debug)]
423 pub db: &'a DB, 605pub struct SemanticsScope<'a> {
606 pub db: &'a dyn HirDatabase,
424 resolver: Resolver, 607 resolver: Resolver,
425} 608}
426 609
427impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> { 610impl<'a> SemanticsScope<'a> {
428 pub fn module(&self) -> Option<Module> { 611 pub fn module(&self) -> Option<Module> {
429 Some(Module { id: self.resolver.module()? }) 612 Some(Module { id: self.resolver.module()? })
430 } 613 }
@@ -433,13 +616,13 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
433 // FIXME: rename to visible_traits to not repeat scope? 616 // FIXME: rename to visible_traits to not repeat scope?
434 pub fn traits_in_scope(&self) -> FxHashSet<TraitId> { 617 pub fn traits_in_scope(&self) -> FxHashSet<TraitId> {
435 let resolver = &self.resolver; 618 let resolver = &self.resolver;
436 resolver.traits_in_scope(self.db) 619 resolver.traits_in_scope(self.db.upcast())
437 } 620 }
438 621
439 pub fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) { 622 pub fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
440 let resolver = &self.resolver; 623 let resolver = &self.resolver;
441 624
442 resolver.process_all_names(self.db, &mut |name, def| { 625 resolver.process_all_names(self.db.upcast(), &mut |name, def| {
443 let def = match def { 626 let def = match def {
444 resolver::ScopeDef::PerNs(it) => { 627 resolver::ScopeDef::PerNs(it) => {
445 let items = ScopeDef::all_items(it); 628 let items = ScopeDef::all_items(it);
diff --git a/crates/ra_hir/src/semantics/source_to_def.rs b/crates/ra_hir/src/semantics/source_to_def.rs
index 8af64fdc1..d1994e2e7 100644
--- a/crates/ra_hir/src/semantics/source_to_def.rs
+++ b/crates/ra_hir/src/semantics/source_to_def.rs
@@ -16,6 +16,7 @@ use ra_syntax::{
16 match_ast, AstNode, SyntaxNode, 16 match_ast, AstNode, SyntaxNode,
17}; 17};
18use rustc_hash::FxHashMap; 18use rustc_hash::FxHashMap;
19use stdx::impl_from;
19 20
20use crate::{db::HirDatabase, InFile, MacroDefId}; 21use crate::{db::HirDatabase, InFile, MacroDefId};
21 22
@@ -64,53 +65,44 @@ impl SourceToDefCtx<'_, '_> {
64 Some(ModuleId { krate: parent_module.krate, local_id: child_id }) 65 Some(ModuleId { krate: parent_module.krate, local_id: child_id })
65 } 66 }
66 67
67 pub(super) fn trait_to_def(&mut self, src: InFile<ast::TraitDef>) -> Option<TraitId> { 68 pub(super) fn trait_to_def(&mut self, src: InFile<ast::Trait>) -> Option<TraitId> {
68 self.to_def(src, keys::TRAIT) 69 self.to_def(src, keys::TRAIT)
69 } 70 }
70 pub(super) fn impl_to_def(&mut self, src: InFile<ast::ImplDef>) -> Option<ImplId> { 71 pub(super) fn impl_to_def(&mut self, src: InFile<ast::Impl>) -> Option<ImplId> {
71 self.to_def(src, keys::IMPL) 72 self.to_def(src, keys::IMPL)
72 } 73 }
73 pub(super) fn fn_to_def(&mut self, src: InFile<ast::FnDef>) -> Option<FunctionId> { 74 pub(super) fn fn_to_def(&mut self, src: InFile<ast::Fn>) -> Option<FunctionId> {
74 self.to_def(src, keys::FUNCTION) 75 self.to_def(src, keys::FUNCTION)
75 } 76 }
76 pub(super) fn struct_to_def(&mut self, src: InFile<ast::StructDef>) -> Option<StructId> { 77 pub(super) fn struct_to_def(&mut self, src: InFile<ast::Struct>) -> Option<StructId> {
77 self.to_def(src, keys::STRUCT) 78 self.to_def(src, keys::STRUCT)
78 } 79 }
79 pub(super) fn enum_to_def(&mut self, src: InFile<ast::EnumDef>) -> Option<EnumId> { 80 pub(super) fn enum_to_def(&mut self, src: InFile<ast::Enum>) -> Option<EnumId> {
80 self.to_def(src, keys::ENUM) 81 self.to_def(src, keys::ENUM)
81 } 82 }
82 pub(super) fn union_to_def(&mut self, src: InFile<ast::UnionDef>) -> Option<UnionId> { 83 pub(super) fn union_to_def(&mut self, src: InFile<ast::Union>) -> Option<UnionId> {
83 self.to_def(src, keys::UNION) 84 self.to_def(src, keys::UNION)
84 } 85 }
85 pub(super) fn static_to_def(&mut self, src: InFile<ast::StaticDef>) -> Option<StaticId> { 86 pub(super) fn static_to_def(&mut self, src: InFile<ast::Static>) -> Option<StaticId> {
86 self.to_def(src, keys::STATIC) 87 self.to_def(src, keys::STATIC)
87 } 88 }
88 pub(super) fn const_to_def(&mut self, src: InFile<ast::ConstDef>) -> Option<ConstId> { 89 pub(super) fn const_to_def(&mut self, src: InFile<ast::Const>) -> Option<ConstId> {
89 self.to_def(src, keys::CONST) 90 self.to_def(src, keys::CONST)
90 } 91 }
91 pub(super) fn type_alias_to_def( 92 pub(super) fn type_alias_to_def(&mut self, src: InFile<ast::TypeAlias>) -> Option<TypeAliasId> {
92 &mut self,
93 src: InFile<ast::TypeAliasDef>,
94 ) -> Option<TypeAliasId> {
95 self.to_def(src, keys::TYPE_ALIAS) 93 self.to_def(src, keys::TYPE_ALIAS)
96 } 94 }
97 pub(super) fn record_field_to_def( 95 pub(super) fn record_field_to_def(&mut self, src: InFile<ast::RecordField>) -> Option<FieldId> {
98 &mut self,
99 src: InFile<ast::RecordFieldDef>,
100 ) -> Option<FieldId> {
101 self.to_def(src, keys::RECORD_FIELD) 96 self.to_def(src, keys::RECORD_FIELD)
102 } 97 }
103 pub(super) fn tuple_field_to_def( 98 pub(super) fn tuple_field_to_def(&mut self, src: InFile<ast::TupleField>) -> Option<FieldId> {
104 &mut self,
105 src: InFile<ast::TupleFieldDef>,
106 ) -> Option<FieldId> {
107 self.to_def(src, keys::TUPLE_FIELD) 99 self.to_def(src, keys::TUPLE_FIELD)
108 } 100 }
109 pub(super) fn enum_variant_to_def( 101 pub(super) fn enum_variant_to_def(
110 &mut self, 102 &mut self,
111 src: InFile<ast::EnumVariant>, 103 src: InFile<ast::Variant>,
112 ) -> Option<EnumVariantId> { 104 ) -> Option<EnumVariantId> {
113 self.to_def(src, keys::ENUM_VARIANT) 105 self.to_def(src, keys::VARIANT)
114 } 106 }
115 pub(super) fn bind_pat_to_def( 107 pub(super) fn bind_pat_to_def(
116 &mut self, 108 &mut self,
@@ -162,38 +154,42 @@ impl SourceToDefCtx<'_, '_> {
162 let def = self.module_to_def(container.with_value(it))?; 154 let def = self.module_to_def(container.with_value(it))?;
163 def.into() 155 def.into()
164 }, 156 },
165 ast::TraitDef(it) => { 157 ast::Trait(it) => {
166 let def = self.trait_to_def(container.with_value(it))?; 158 let def = self.trait_to_def(container.with_value(it))?;
167 def.into() 159 def.into()
168 }, 160 },
169 ast::ImplDef(it) => { 161 ast::Impl(it) => {
170 let def = self.impl_to_def(container.with_value(it))?; 162 let def = self.impl_to_def(container.with_value(it))?;
171 def.into() 163 def.into()
172 }, 164 },
173 ast::FnDef(it) => { 165 ast::Fn(it) => {
174 let def = self.fn_to_def(container.with_value(it))?; 166 let def = self.fn_to_def(container.with_value(it))?;
175 DefWithBodyId::from(def).into() 167 DefWithBodyId::from(def).into()
176 }, 168 },
177 ast::StructDef(it) => { 169 ast::Struct(it) => {
178 let def = self.struct_to_def(container.with_value(it))?; 170 let def = self.struct_to_def(container.with_value(it))?;
179 VariantId::from(def).into() 171 VariantId::from(def).into()
180 }, 172 },
181 ast::EnumDef(it) => { 173 ast::Enum(it) => {
182 let def = self.enum_to_def(container.with_value(it))?; 174 let def = self.enum_to_def(container.with_value(it))?;
183 def.into() 175 def.into()
184 }, 176 },
185 ast::UnionDef(it) => { 177 ast::Union(it) => {
186 let def = self.union_to_def(container.with_value(it))?; 178 let def = self.union_to_def(container.with_value(it))?;
187 VariantId::from(def).into() 179 VariantId::from(def).into()
188 }, 180 },
189 ast::StaticDef(it) => { 181 ast::Static(it) => {
190 let def = self.static_to_def(container.with_value(it))?; 182 let def = self.static_to_def(container.with_value(it))?;
191 DefWithBodyId::from(def).into() 183 DefWithBodyId::from(def).into()
192 }, 184 },
193 ast::ConstDef(it) => { 185 ast::Const(it) => {
194 let def = self.const_to_def(container.with_value(it))?; 186 let def = self.const_to_def(container.with_value(it))?;
195 DefWithBodyId::from(def).into() 187 DefWithBodyId::from(def).into()
196 }, 188 },
189 ast::TypeAlias(it) => {
190 let def = self.type_alias_to_def(container.with_value(it))?;
191 def.into()
192 },
197 _ => continue, 193 _ => continue,
198 } 194 }
199 }; 195 };
@@ -208,12 +204,12 @@ impl SourceToDefCtx<'_, '_> {
208 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { 204 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) {
209 let res: GenericDefId = match_ast! { 205 let res: GenericDefId = match_ast! {
210 match (container.value) { 206 match (container.value) {
211 ast::FnDef(it) => self.fn_to_def(container.with_value(it))?.into(), 207 ast::Fn(it) => self.fn_to_def(container.with_value(it))?.into(),
212 ast::StructDef(it) => self.struct_to_def(container.with_value(it))?.into(), 208 ast::Struct(it) => self.struct_to_def(container.with_value(it))?.into(),
213 ast::EnumDef(it) => self.enum_to_def(container.with_value(it))?.into(), 209 ast::Enum(it) => self.enum_to_def(container.with_value(it))?.into(),
214 ast::TraitDef(it) => self.trait_to_def(container.with_value(it))?.into(), 210 ast::Trait(it) => self.trait_to_def(container.with_value(it))?.into(),
215 ast::TypeAliasDef(it) => self.type_alias_to_def(container.with_value(it))?.into(), 211 ast::TypeAlias(it) => self.type_alias_to_def(container.with_value(it))?.into(),
216 ast::ImplDef(it) => self.impl_to_def(container.with_value(it))?.into(), 212 ast::Impl(it) => self.impl_to_def(container.with_value(it))?.into(),
217 _ => continue, 213 _ => continue,
218 } 214 }
219 }; 215 };
@@ -226,9 +222,9 @@ impl SourceToDefCtx<'_, '_> {
226 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { 222 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) {
227 let res: DefWithBodyId = match_ast! { 223 let res: DefWithBodyId = match_ast! {
228 match (container.value) { 224 match (container.value) {
229 ast::ConstDef(it) => self.const_to_def(container.with_value(it))?.into(), 225 ast::Const(it) => self.const_to_def(container.with_value(it))?.into(),
230 ast::StaticDef(it) => self.static_to_def(container.with_value(it))?.into(), 226 ast::Static(it) => self.static_to_def(container.with_value(it))?.into(),
231 ast::FnDef(it) => self.fn_to_def(container.with_value(it))?.into(), 227 ast::Fn(it) => self.fn_to_def(container.with_value(it))?.into(),
232 _ => continue, 228 _ => continue,
233 } 229 }
234 }; 230 };
@@ -246,19 +242,21 @@ pub(crate) enum ChildContainer {
246 ImplId(ImplId), 242 ImplId(ImplId),
247 EnumId(EnumId), 243 EnumId(EnumId),
248 VariantId(VariantId), 244 VariantId(VariantId),
245 TypeAliasId(TypeAliasId),
249 /// XXX: this might be the same def as, for example an `EnumId`. However, 246 /// XXX: this might be the same def as, for example an `EnumId`. However,
250 /// here the children generic parameters, and not, eg enum variants. 247 /// here the children generic parameters, and not, eg enum variants.
251 GenericDefId(GenericDefId), 248 GenericDefId(GenericDefId),
252} 249}
253impl_froms! { 250impl_from! {
254 ChildContainer:
255 DefWithBodyId, 251 DefWithBodyId,
256 ModuleId, 252 ModuleId,
257 TraitId, 253 TraitId,
258 ImplId, 254 ImplId,
259 EnumId, 255 EnumId,
260 VariantId, 256 VariantId,
257 TypeAliasId,
261 GenericDefId 258 GenericDefId
259 for ChildContainer
262} 260}
263 261
264impl ChildContainer { 262impl ChildContainer {
@@ -271,6 +269,7 @@ impl ChildContainer {
271 ChildContainer::ImplId(it) => it.child_by_source(db), 269 ChildContainer::ImplId(it) => it.child_by_source(db),
272 ChildContainer::EnumId(it) => it.child_by_source(db), 270 ChildContainer::EnumId(it) => it.child_by_source(db),
273 ChildContainer::VariantId(it) => it.child_by_source(db), 271 ChildContainer::VariantId(it) => it.child_by_source(db),
272 ChildContainer::TypeAliasId(_) => DynMap::default(),
274 ChildContainer::GenericDefId(it) => it.child_by_source(db), 273 ChildContainer::GenericDefId(it) => it.child_by_source(db),
275 } 274 }
276 } 275 }
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index 1d6c47103..f2e630ef1 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -14,11 +14,11 @@ use hir_def::{
14 }, 14 },
15 expr::{ExprId, Pat, PatId}, 15 expr::{ExprId, Pat, PatId},
16 resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, 16 resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
17 AsMacroCall, DefWithBodyId, FieldId, LocalFieldId, VariantId, 17 AsMacroCall, DefWithBodyId, FieldId, FunctionId, LocalFieldId, VariantId,
18}; 18};
19use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 19use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
20use hir_ty::{ 20use hir_ty::{
21 expr::{record_literal_missing_fields, record_pattern_missing_fields}, 21 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
22 InferenceResult, Substs, Ty, 22 InferenceResult, Substs, Ty,
23}; 23};
24use ra_syntax::{ 24use ra_syntax::{
@@ -115,7 +115,7 @@ impl SourceAnalyzer {
115 Some(res) 115 Some(res)
116 } 116 }
117 117
118 pub(crate) fn type_of(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<Type> { 118 pub(crate) fn type_of_expr(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<Type> {
119 let expr_id = self.expr_id(db, expr)?; 119 let expr_id = self.expr_id(db, expr)?;
120 let ty = self.infer.as_ref()?[expr_id].clone(); 120 let ty = self.infer.as_ref()?[expr_id].clone();
121 Type::new_with_resolver(db, &self.resolver, ty) 121 Type::new_with_resolver(db, &self.resolver, ty)
@@ -127,13 +127,24 @@ impl SourceAnalyzer {
127 Type::new_with_resolver(db, &self.resolver, ty) 127 Type::new_with_resolver(db, &self.resolver, ty)
128 } 128 }
129 129
130 pub(crate) fn type_of_self(
131 &self,
132 db: &dyn HirDatabase,
133 param: &ast::SelfParam,
134 ) -> Option<Type> {
135 let src = InFile { file_id: self.file_id, value: param };
136 let pat_id = self.body_source_map.as_ref()?.node_self_param(src)?;
137 let ty = self.infer.as_ref()?[pat_id].clone();
138 Type::new_with_resolver(db, &self.resolver, ty)
139 }
140
130 pub(crate) fn resolve_method_call( 141 pub(crate) fn resolve_method_call(
131 &self, 142 &self,
132 db: &dyn HirDatabase, 143 db: &dyn HirDatabase,
133 call: &ast::MethodCallExpr, 144 call: &ast::MethodCallExpr,
134 ) -> Option<Function> { 145 ) -> Option<FunctionId> {
135 let expr_id = self.expr_id(db, &call.clone().into())?; 146 let expr_id = self.expr_id(db, &call.clone().into())?;
136 self.infer.as_ref()?.method_resolution(expr_id).map(Function::from) 147 self.infer.as_ref()?.method_resolution(expr_id)
137 } 148 }
138 149
139 pub(crate) fn resolve_field( 150 pub(crate) fn resolve_field(
@@ -148,7 +159,7 @@ impl SourceAnalyzer {
148 pub(crate) fn resolve_record_field( 159 pub(crate) fn resolve_record_field(
149 &self, 160 &self,
150 db: &dyn HirDatabase, 161 db: &dyn HirDatabase,
151 field: &ast::RecordField, 162 field: &ast::RecordExprField,
152 ) -> Option<(Field, Option<Local>)> { 163 ) -> Option<(Field, Option<Local>)> {
153 let expr = field.expr()?; 164 let expr = field.expr()?;
154 let expr_id = self.expr_id(db, &expr)?; 165 let expr_id = self.expr_id(db, &expr)?;
@@ -235,7 +246,7 @@ impl SourceAnalyzer {
235 } 246 }
236 } 247 }
237 248
238 if let Some(rec_lit) = path.syntax().parent().and_then(ast::RecordLit::cast) { 249 if let Some(rec_lit) = path.syntax().parent().and_then(ast::RecordExpr::cast) {
239 let expr_id = self.expr_id(db, &rec_lit.into())?; 250 let expr_id = self.expr_id(db, &rec_lit.into())?;
240 if let Some(VariantId::EnumVariantId(variant)) = 251 if let Some(VariantId::EnumVariantId(variant)) =
241 self.infer.as_ref()?.variant_resolution_for_expr(expr_id) 252 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
@@ -273,7 +284,7 @@ impl SourceAnalyzer {
273 pub(crate) fn record_literal_missing_fields( 284 pub(crate) fn record_literal_missing_fields(
274 &self, 285 &self,
275 db: &dyn HirDatabase, 286 db: &dyn HirDatabase,
276 literal: &ast::RecordLit, 287 literal: &ast::RecordExpr,
277 ) -> Option<Vec<(Field, Type)>> { 288 ) -> Option<Vec<(Field, Type)>> {
278 let krate = self.resolver.krate()?; 289 let krate = self.resolver.krate()?;
279 let body = self.body.as_ref()?; 290 let body = self.body.as_ref()?;
@@ -341,13 +352,13 @@ impl SourceAnalyzer {
341 let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| { 352 let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
342 self.resolver.resolve_path_as_macro(db.upcast(), &path) 353 self.resolver.resolve_path_as_macro(db.upcast(), &path)
343 })?; 354 })?;
344 Some(macro_call_id.as_file()) 355 Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
345 } 356 }
346 357
347 pub(crate) fn resolve_variant( 358 pub(crate) fn resolve_variant(
348 &self, 359 &self,
349 db: &dyn HirDatabase, 360 db: &dyn HirDatabase,
350 record_lit: ast::RecordLit, 361 record_lit: ast::RecordExpr,
351 ) -> Option<VariantId> { 362 ) -> Option<VariantId> {
352 let infer = self.infer.as_ref()?; 363 let infer = self.infer.as_ref()?;
353 let expr_id = self.expr_id(db, &record_lit.into())?; 364 let expr_id = self.expr_id(db, &record_lit.into())?;
@@ -394,8 +405,7 @@ fn scope_for_offset(
394 ) 405 )
395 }) 406 })
396 .map(|(expr_range, scope)| { 407 .map(|(expr_range, scope)| {
397 adjust(db, scopes, source_map, expr_range, offset.file_id, offset.value) 408 adjust(db, scopes, source_map, expr_range, offset).unwrap_or(*scope)
398 .unwrap_or(*scope)
399 }) 409 })
400} 410}
401 411
@@ -406,8 +416,7 @@ fn adjust(
406 scopes: &ExprScopes, 416 scopes: &ExprScopes,
407 source_map: &BodySourceMap, 417 source_map: &BodySourceMap,
408 expr_range: TextRange, 418 expr_range: TextRange,
409 file_id: HirFileId, 419 offset: InFile<TextSize>,
410 offset: TextSize,
411) -> Option<ScopeId> { 420) -> Option<ScopeId> {
412 let child_scopes = scopes 421 let child_scopes = scopes
413 .scope_by_expr() 422 .scope_by_expr()
@@ -415,7 +424,7 @@ fn adjust(
415 .filter_map(|(id, scope)| { 424 .filter_map(|(id, scope)| {
416 let source = source_map.expr_syntax(*id).ok()?; 425 let source = source_map.expr_syntax(*id).ok()?;
417 // FIXME: correctly handle macro expansion 426 // FIXME: correctly handle macro expansion
418 if source.file_id != file_id { 427 if source.file_id != offset.file_id {
419 return None; 428 return None;
420 } 429 }
421 let root = source.file_syntax(db.upcast()); 430 let root = source.file_syntax(db.upcast());
@@ -423,7 +432,7 @@ fn adjust(
423 Some((node.syntax().text_range(), scope)) 432 Some((node.syntax().text_range(), scope))
424 }) 433 })
425 .filter(|&(range, _)| { 434 .filter(|&(range, _)| {
426 range.start() <= offset && expr_range.contains_range(range) && range != expr_range 435 range.start() <= offset.value && expr_range.contains_range(range) && range != expr_range
427 }); 436 });
428 437
429 child_scopes 438 child_scopes