diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 143 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/diagnostics.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 32 | ||||
-rw-r--r-- | crates/ra_hir/src/semantics.rs | 99 | ||||
-rw-r--r-- | crates/ra_hir/src/semantics/source_to_def.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/source_analyzer.rs | 23 |
8 files changed, 219 insertions, 102 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" | |||
3 | name = "ra_hir" | 3 | name = "ra_hir" |
4 | version = "0.1.0" | 4 | version = "0.1.0" |
5 | authors = ["rust-analyzer developers"] | 5 | authors = ["rust-analyzer developers"] |
6 | license = "MIT OR Apache-2.0" | ||
6 | 7 | ||
7 | [lib] | 8 | [lib] |
8 | doctest = false | 9 | doctest = false |
@@ -15,6 +16,7 @@ arrayvec = "0.5.1" | |||
15 | 16 | ||
16 | itertools = "0.9.0" | 17 | itertools = "0.9.0" |
17 | 18 | ||
19 | stdx = { path = "../stdx" } | ||
18 | ra_syntax = { path = "../ra_syntax" } | 20 | ra_syntax = { path = "../ra_syntax" } |
19 | ra_db = { path = "../ra_db" } | 21 | ra_db = { path = "../ra_db" } |
20 | ra_prof = { path = "../ra_prof" } | 22 | ra_prof = { path = "../ra_prof" } |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 1b3525011..859bdfb3b 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 |
2 | use std::sync::Arc; | 2 | use std::{iter, sync::Arc}; |
3 | 3 | ||
4 | use arrayvec::ArrayVec; | 4 | use arrayvec::ArrayVec; |
5 | use either::Either; | 5 | use 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::{ | |||
25 | use hir_ty::{ | 26 | use 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 | }; |
34 | use ra_db::{CrateId, Edition, FileId}; | 32 | use ra_db::{CrateId, Edition, FileId}; |
35 | use ra_prof::profile; | 33 | use ra_prof::profile; |
36 | use ra_syntax::ast::{self, AttrsOwner, NameOwner}; | 34 | use ra_syntax::{ |
35 | ast::{self, AttrsOwner, NameOwner}, | ||
36 | AstNode, | ||
37 | }; | ||
37 | use rustc_hash::FxHashSet; | 38 | use rustc_hash::FxHashSet; |
39 | use stdx::impl_from; | ||
38 | 40 | ||
39 | use crate::{ | 41 | use 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 |
@@ -139,8 +141,8 @@ pub enum ModuleDef { | |||
139 | TypeAlias(TypeAlias), | 141 | TypeAlias(TypeAlias), |
140 | BuiltinType(BuiltinType), | 142 | BuiltinType(BuiltinType), |
141 | } | 143 | } |
142 | impl_froms!( | 144 | impl_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 | ||
154 | impl ModuleDef { | 157 | impl ModuleDef { |
@@ -538,7 +541,7 @@ pub enum Adt { | |||
538 | Union(Union), | 541 | Union(Union), |
539 | Enum(Enum), | 542 | Enum(Enum), |
540 | } | 543 | } |
541 | impl_froms!(Adt: Struct, Union, Enum); | 544 | impl_from!(Struct, Union, Enum for Adt); |
542 | 545 | ||
543 | impl Adt { | 546 | impl Adt { |
544 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 547 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
@@ -581,7 +584,7 @@ pub enum VariantDef { | |||
581 | Union(Union), | 584 | Union(Union), |
582 | EnumVariant(EnumVariant), | 585 | EnumVariant(EnumVariant), |
583 | } | 586 | } |
584 | impl_froms!(VariantDef: Struct, Union, EnumVariant); | 587 | impl_from!(Struct, Union, EnumVariant for VariantDef); |
585 | 588 | ||
586 | impl VariantDef { | 589 | impl VariantDef { |
587 | pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { | 590 | pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { |
@@ -624,8 +627,7 @@ pub enum DefWithBody { | |||
624 | Static(Static), | 627 | Static(Static), |
625 | Const(Const), | 628 | Const(Const), |
626 | } | 629 | } |
627 | 630 | impl_from!(Function, Const, Static for DefWithBody); | |
628 | impl_froms!(DefWithBody: Function, Const, Static); | ||
629 | 631 | ||
630 | impl DefWithBody { | 632 | impl DefWithBody { |
631 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 633 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
@@ -676,13 +678,7 @@ impl Function { | |||
676 | } | 678 | } |
677 | 679 | ||
678 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 680 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
679 | let _p = profile("Function::diagnostics"); | 681 | hir_ty::diagnostics::validate_body(db, self.id.into(), sink) |
680 | let infer = db.infer(self.id.into()); | ||
681 | infer.add_diagnostics(db, self.id, sink); | ||
682 | let mut validator = ExprValidator::new(self.id, infer.clone(), sink); | ||
683 | validator.validate_body(db); | ||
684 | let mut validator = UnsafeValidator::new(self.id, infer, sink); | ||
685 | validator.validate_body(db); | ||
686 | } | 682 | } |
687 | } | 683 | } |
688 | 684 | ||
@@ -927,14 +923,15 @@ pub enum GenericDef { | |||
927 | // consts can have type parameters from their parents (i.e. associated consts of traits) | 923 | // consts can have type parameters from their parents (i.e. associated consts of traits) |
928 | Const(Const), | 924 | Const(Const), |
929 | } | 925 | } |
930 | impl_froms!( | 926 | impl_from!( |
931 | GenericDef: Function, | 927 | Function, |
932 | Adt(Struct, Enum, Union), | 928 | Adt(Struct, Enum, Union), |
933 | Trait, | 929 | Trait, |
934 | TypeAlias, | 930 | TypeAlias, |
935 | ImplDef, | 931 | ImplDef, |
936 | EnumVariant, | 932 | EnumVariant, |
937 | Const | 933 | Const |
934 | for GenericDef | ||
938 | ); | 935 | ); |
939 | 936 | ||
940 | impl GenericDef { | 937 | impl GenericDef { |
@@ -955,6 +952,16 @@ pub struct Local { | |||
955 | } | 952 | } |
956 | 953 | ||
957 | impl Local { | 954 | impl Local { |
955 | pub fn is_param(self, db: &dyn HirDatabase) -> bool { | ||
956 | let src = self.source(db); | ||
957 | match src.value { | ||
958 | Either::Left(bind_pat) => { | ||
959 | bind_pat.syntax().ancestors().any(|it| ast::Param::can_cast(it.kind())) | ||
960 | } | ||
961 | Either::Right(_self_param) => true, | ||
962 | } | ||
963 | } | ||
964 | |||
958 | // FIXME: why is this an option? It shouldn't be? | 965 | // FIXME: why is this an option? It shouldn't be? |
959 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 966 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
960 | let body = db.body(self.parent.into()); | 967 | let body = db.body(self.parent.into()); |
@@ -1162,6 +1169,12 @@ impl Type { | |||
1162 | Type::new(db, krate, def, ty) | 1169 | Type::new(db, krate, def, ty) |
1163 | } | 1170 | } |
1164 | 1171 | ||
1172 | pub fn is_unit(&self) -> bool { | ||
1173 | matches!( | ||
1174 | self.ty.value, | ||
1175 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. }) | ||
1176 | ) | ||
1177 | } | ||
1165 | pub fn is_bool(&self) -> bool { | 1178 | pub fn is_bool(&self) -> bool { |
1166 | matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) | 1179 | matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) |
1167 | } | 1180 | } |
@@ -1219,9 +1232,14 @@ impl Type { | |||
1219 | db.trait_solve(self.krate, goal).is_some() | 1232 | db.trait_solve(self.krate, goal).is_some() |
1220 | } | 1233 | } |
1221 | 1234 | ||
1222 | // FIXME: this method is broken, as it doesn't take closures into account. | 1235 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1223 | pub fn as_callable(&self) -> Option<CallableDef> { | 1236 | let def = match self.ty.value { |
1224 | Some(self.ty.value.as_callable()?.0) | 1237 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), |
1238 | _ => None, | ||
1239 | }; | ||
1240 | |||
1241 | let sig = self.ty.value.callable_sig(db)?; | ||
1242 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) | ||
1225 | } | 1243 | } |
1226 | 1244 | ||
1227 | pub fn is_closure(&self) -> bool { | 1245 | pub fn is_closure(&self) -> bool { |
@@ -1506,6 +1524,74 @@ impl HirDisplay for Type { | |||
1506 | } | 1524 | } |
1507 | } | 1525 | } |
1508 | 1526 | ||
1527 | // FIXME: closures | ||
1528 | #[derive(Debug)] | ||
1529 | pub struct Callable { | ||
1530 | ty: Type, | ||
1531 | sig: FnSig, | ||
1532 | def: Option<CallableDefId>, | ||
1533 | pub(crate) is_bound_method: bool, | ||
1534 | } | ||
1535 | |||
1536 | pub enum CallableKind { | ||
1537 | Function(Function), | ||
1538 | TupleStruct(Struct), | ||
1539 | TupleEnumVariant(EnumVariant), | ||
1540 | Closure, | ||
1541 | } | ||
1542 | |||
1543 | impl Callable { | ||
1544 | pub fn kind(&self) -> CallableKind { | ||
1545 | match self.def { | ||
1546 | Some(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), | ||
1547 | Some(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()), | ||
1548 | Some(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()), | ||
1549 | None => CallableKind::Closure, | ||
1550 | } | ||
1551 | } | ||
1552 | pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<ast::SelfParam> { | ||
1553 | let func = match self.def { | ||
1554 | Some(CallableDefId::FunctionId(it)) if self.is_bound_method => it, | ||
1555 | _ => return None, | ||
1556 | }; | ||
1557 | let src = func.lookup(db.upcast()).source(db.upcast()); | ||
1558 | let param_list = src.value.param_list()?; | ||
1559 | param_list.self_param() | ||
1560 | } | ||
1561 | pub fn n_params(&self) -> usize { | ||
1562 | self.sig.params().len() - if self.is_bound_method { 1 } else { 0 } | ||
1563 | } | ||
1564 | pub fn params( | ||
1565 | &self, | ||
1566 | db: &dyn HirDatabase, | ||
1567 | ) -> Vec<(Option<Either<ast::SelfParam, ast::Pat>>, Type)> { | ||
1568 | let types = self | ||
1569 | .sig | ||
1570 | .params() | ||
1571 | .iter() | ||
1572 | .skip(if self.is_bound_method { 1 } else { 0 }) | ||
1573 | .map(|ty| self.ty.derived(ty.clone())); | ||
1574 | let patterns = match self.def { | ||
1575 | Some(CallableDefId::FunctionId(func)) => { | ||
1576 | let src = func.lookup(db.upcast()).source(db.upcast()); | ||
1577 | src.value.param_list().map(|param_list| { | ||
1578 | param_list | ||
1579 | .self_param() | ||
1580 | .map(|it| Some(Either::Left(it))) | ||
1581 | .filter(|_| !self.is_bound_method) | ||
1582 | .into_iter() | ||
1583 | .chain(param_list.params().map(|it| it.pat().map(Either::Right))) | ||
1584 | }) | ||
1585 | } | ||
1586 | _ => None, | ||
1587 | }; | ||
1588 | patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect() | ||
1589 | } | ||
1590 | pub fn return_type(&self) -> Type { | ||
1591 | self.ty.derived(self.sig.ret().clone()) | ||
1592 | } | ||
1593 | } | ||
1594 | |||
1509 | /// For IDE only | 1595 | /// For IDE only |
1510 | #[derive(Debug)] | 1596 | #[derive(Debug)] |
1511 | pub enum ScopeDef { | 1597 | pub enum ScopeDef { |
@@ -1565,8 +1651,8 @@ pub enum AttrDef { | |||
1565 | MacroDef(MacroDef), | 1651 | MacroDef(MacroDef), |
1566 | } | 1652 | } |
1567 | 1653 | ||
1568 | impl_froms!( | 1654 | impl_from!( |
1569 | AttrDef: Module, | 1655 | Module, |
1570 | Field, | 1656 | Field, |
1571 | Adt(Struct, Enum, Union), | 1657 | Adt(Struct, Enum, Union), |
1572 | EnumVariant, | 1658 | EnumVariant, |
@@ -1576,6 +1662,7 @@ impl_froms!( | |||
1576 | Trait, | 1662 | Trait, |
1577 | TypeAlias, | 1663 | TypeAlias, |
1578 | MacroDef | 1664 | MacroDef |
1665 | for AttrDef | ||
1579 | ); | 1666 | ); |
1580 | 1667 | ||
1581 | pub trait HasAttrs { | 1668 | pub trait HasAttrs { |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index cb48ca065..1ad92a1f8 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -17,9 +17,9 @@ pub 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, InferQueryQuery, | 19 | HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, InferQueryQuery, |
20 | InherentImplsInCrateQuery, InternAssocTyValueQuery, InternChalkImplQuery, InternTypeCtorQuery, | 20 | InherentImplsInCrateQuery, InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery, |
21 | InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery, TraitDatumQuery, | 21 | TraitDatumQuery, TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery, |
22 | TraitImplsInCrateQuery, TraitImplsInDepsQuery, 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..11a0ecb8b 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs | |||
@@ -1,4 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | pub use hir_def::diagnostics::UnresolvedModule; | 2 | pub use hir_def::diagnostics::UnresolvedModule; |
3 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; | 3 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; |
4 | pub use hir_ty::diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField}; | 4 | pub use hir_ty::diagnostics::{ |
5 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField, | ||
6 | }; | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 3364a822f..31f3241c9 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 | ||
22 | macro_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 | |||
41 | mod semantics; | 22 | mod semantics; |
42 | pub mod db; | 23 | pub mod db; |
43 | mod source_analyzer; | 24 | mod source_analyzer; |
@@ -51,10 +32,10 @@ mod has_source; | |||
51 | 32 | ||
52 | pub use crate::{ | 33 | pub 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}, |
@@ -71,7 +52,8 @@ pub use hir_def::{ | |||
71 | type_ref::Mutability, | 52 | type_ref::Mutability, |
72 | }; | 53 | }; |
73 | pub use hir_expand::{ | 54 | pub use hir_expand::{ |
74 | hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, | 55 | hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, |
56 | MacroDefId, /* FIXME */ | ||
75 | MacroFile, Origin, | 57 | MacroFile, Origin, |
76 | }; | 58 | }; |
77 | pub use hir_ty::{display::HirDisplay, CallableDef}; | 59 | pub use hir_ty::display::HirDisplay; |
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 3d78f71c1..f5283ab22 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 | ||
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | resolver::{self, HasResolver, Resolver}, | 8 | resolver::{self, HasResolver, Resolver}, |
9 | AsMacroCall, TraitId, VariantId, | 9 | AsMacroCall, FunctionId, TraitId, VariantId, |
10 | }; | 10 | }; |
11 | use hir_expand::{diagnostics::AstDiagnostic, hygiene::Hygiene, ExpansionInfo}; | 11 | use hir_expand::{diagnostics::AstDiagnostic, hygiene::Hygiene, ExpansionInfo}; |
12 | use hir_ty::associated_type_shorthand_candidates; | 12 | use 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 | }; |
30 | use resolver::TypeNs; | 30 | use resolver::TypeNs; |
31 | 31 | ||
@@ -192,8 +192,16 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
192 | self.imp.type_of_pat(pat) | 192 | self.imp.type_of_pat(pat) |
193 | } | 193 | } |
194 | 194 | ||
195 | pub fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> { | ||
196 | self.imp.type_of_self(param) | ||
197 | } | ||
198 | |||
195 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | 199 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { |
196 | self.imp.resolve_method_call(call) | 200 | self.imp.resolve_method_call(call).map(Function::from) |
201 | } | ||
202 | |||
203 | pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> { | ||
204 | self.imp.resolve_method_call_as_callable(call) | ||
197 | } | 205 | } |
198 | 206 | ||
199 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> { | 207 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> { |
@@ -216,8 +224,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
216 | self.imp.resolve_path(path) | 224 | self.imp.resolve_path(path) |
217 | } | 225 | } |
218 | 226 | ||
219 | pub fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantId> { | 227 | pub fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantDef> { |
220 | self.imp.resolve_variant(record_lit) | 228 | self.imp.resolve_variant(record_lit).map(VariantDef::from) |
221 | } | 229 | } |
222 | 230 | ||
223 | pub fn lower_path(&self, path: &ast::Path) -> Option<Path> { | 231 | pub fn lower_path(&self, path: &ast::Path) -> Option<Path> { |
@@ -266,17 +274,17 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
266 | } | 274 | } |
267 | 275 | ||
268 | impl<'db> SemanticsImpl<'db> { | 276 | impl<'db> SemanticsImpl<'db> { |
269 | pub fn new(db: &'db dyn HirDatabase) -> Self { | 277 | fn new(db: &'db dyn HirDatabase) -> Self { |
270 | Self { db, s2d_cache: Default::default(), cache: Default::default() } | 278 | Self { db, s2d_cache: Default::default(), cache: Default::default() } |
271 | } | 279 | } |
272 | 280 | ||
273 | pub fn parse(&self, file_id: FileId) -> ast::SourceFile { | 281 | fn parse(&self, file_id: FileId) -> ast::SourceFile { |
274 | let tree = self.db.parse(file_id).tree(); | 282 | let tree = self.db.parse(file_id).tree(); |
275 | self.cache(tree.syntax().clone(), file_id.into()); | 283 | self.cache(tree.syntax().clone(), file_id.into()); |
276 | tree | 284 | tree |
277 | } | 285 | } |
278 | 286 | ||
279 | pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { | 287 | fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { |
280 | let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); | 288 | let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); |
281 | let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); | 289 | let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); |
282 | let file_id = sa.expand(self.db, macro_call)?; | 290 | let file_id = sa.expand(self.db, macro_call)?; |
@@ -285,7 +293,7 @@ impl<'db> SemanticsImpl<'db> { | |||
285 | Some(node) | 293 | Some(node) |
286 | } | 294 | } |
287 | 295 | ||
288 | pub fn expand_hypothetical( | 296 | fn expand_hypothetical( |
289 | &self, | 297 | &self, |
290 | actual_macro_call: &ast::MacroCall, | 298 | actual_macro_call: &ast::MacroCall, |
291 | hypothetical_args: &ast::TokenTree, | 299 | hypothetical_args: &ast::TokenTree, |
@@ -306,7 +314,7 @@ impl<'db> SemanticsImpl<'db> { | |||
306 | ) | 314 | ) |
307 | } | 315 | } |
308 | 316 | ||
309 | pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { | 317 | fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { |
310 | let parent = token.parent(); | 318 | let parent = token.parent(); |
311 | let parent = self.find_file(parent); | 319 | let parent = self.find_file(parent); |
312 | let sa = self.analyze2(parent.as_ref(), None); | 320 | let sa = self.analyze2(parent.as_ref(), None); |
@@ -330,7 +338,7 @@ impl<'db> SemanticsImpl<'db> { | |||
330 | token.value | 338 | token.value |
331 | } | 339 | } |
332 | 340 | ||
333 | pub fn descend_node_at_offset( | 341 | fn descend_node_at_offset( |
334 | &self, | 342 | &self, |
335 | node: &SyntaxNode, | 343 | node: &SyntaxNode, |
336 | offset: TextSize, | 344 | offset: TextSize, |
@@ -342,24 +350,24 @@ impl<'db> SemanticsImpl<'db> { | |||
342 | .flatten() | 350 | .flatten() |
343 | } | 351 | } |
344 | 352 | ||
345 | pub fn original_range(&self, node: &SyntaxNode) -> FileRange { | 353 | fn original_range(&self, node: &SyntaxNode) -> FileRange { |
346 | let node = self.find_file(node.clone()); | 354 | let node = self.find_file(node.clone()); |
347 | original_range(self.db, node.as_ref()) | 355 | original_range(self.db, node.as_ref()) |
348 | } | 356 | } |
349 | 357 | ||
350 | pub fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { | 358 | fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { |
351 | let src = diagnostics.source(); | 359 | let src = diagnostics.source(); |
352 | let root = self.db.parse_or_expand(src.file_id).unwrap(); | 360 | let root = self.db.parse_or_expand(src.file_id).unwrap(); |
353 | let node = src.value.to_node(&root); | 361 | let node = src.value.to_node(&root); |
354 | original_range(self.db, src.with_value(&node)) | 362 | original_range(self.db, src.with_value(&node)) |
355 | } | 363 | } |
356 | 364 | ||
357 | pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { | 365 | fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { |
358 | let node = self.find_file(node); | 366 | let node = self.find_file(node); |
359 | node.ancestors_with_macros(self.db.upcast()).map(|it| it.value) | 367 | node.ancestors_with_macros(self.db.upcast()).map(|it| it.value) |
360 | } | 368 | } |
361 | 369 | ||
362 | pub fn ancestors_at_offset_with_macros( | 370 | fn ancestors_at_offset_with_macros( |
363 | &self, | 371 | &self, |
364 | node: &SyntaxNode, | 372 | node: &SyntaxNode, |
365 | offset: TextSize, | 373 | offset: TextSize, |
@@ -369,60 +377,75 @@ impl<'db> SemanticsImpl<'db> { | |||
369 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) | 377 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) |
370 | } | 378 | } |
371 | 379 | ||
372 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 380 | fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
373 | self.analyze(expr.syntax()).type_of(self.db, &expr) | 381 | self.analyze(expr.syntax()).type_of_expr(self.db, &expr) |
374 | } | 382 | } |
375 | 383 | ||
376 | pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { | 384 | fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { |
377 | self.analyze(pat.syntax()).type_of_pat(self.db, &pat) | 385 | self.analyze(pat.syntax()).type_of_pat(self.db, &pat) |
378 | } | 386 | } |
379 | 387 | ||
380 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | 388 | fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> { |
389 | self.analyze(param.syntax()).type_of_self(self.db, ¶m) | ||
390 | } | ||
391 | |||
392 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { | ||
381 | self.analyze(call.syntax()).resolve_method_call(self.db, call) | 393 | self.analyze(call.syntax()).resolve_method_call(self.db, call) |
382 | } | 394 | } |
383 | 395 | ||
384 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> { | 396 | fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> { |
397 | // FIXME: this erases Substs | ||
398 | let func = self.resolve_method_call(call)?; | ||
399 | let ty = self.db.value_ty(func.into()); | ||
400 | let resolver = self.analyze(call.syntax()).resolver; | ||
401 | let ty = Type::new_with_resolver(self.db, &resolver, ty.value)?; | ||
402 | let mut res = ty.as_callable(self.db)?; | ||
403 | res.is_bound_method = true; | ||
404 | Some(res) | ||
405 | } | ||
406 | |||
407 | fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> { | ||
385 | self.analyze(field.syntax()).resolve_field(self.db, field) | 408 | self.analyze(field.syntax()).resolve_field(self.db, field) |
386 | } | 409 | } |
387 | 410 | ||
388 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<(Field, Option<Local>)> { | 411 | fn resolve_record_field(&self, field: &ast::RecordField) -> Option<(Field, Option<Local>)> { |
389 | self.analyze(field.syntax()).resolve_record_field(self.db, field) | 412 | self.analyze(field.syntax()).resolve_record_field(self.db, field) |
390 | } | 413 | } |
391 | 414 | ||
392 | pub fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> { | 415 | fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> { |
393 | self.analyze(field.syntax()).resolve_record_field_pat(self.db, field) | 416 | self.analyze(field.syntax()).resolve_record_field_pat(self.db, field) |
394 | } | 417 | } |
395 | 418 | ||
396 | pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> { | 419 | fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> { |
397 | let sa = self.analyze(macro_call.syntax()); | 420 | let sa = self.analyze(macro_call.syntax()); |
398 | let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); | 421 | let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); |
399 | sa.resolve_macro_call(self.db, macro_call) | 422 | sa.resolve_macro_call(self.db, macro_call) |
400 | } | 423 | } |
401 | 424 | ||
402 | pub fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> { | 425 | fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> { |
403 | self.analyze(path.syntax()).resolve_path(self.db, path) | 426 | self.analyze(path.syntax()).resolve_path(self.db, path) |
404 | } | 427 | } |
405 | 428 | ||
406 | pub fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantId> { | 429 | fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantId> { |
407 | self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit) | 430 | self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit) |
408 | } | 431 | } |
409 | 432 | ||
410 | pub fn lower_path(&self, path: &ast::Path) -> Option<Path> { | 433 | fn lower_path(&self, path: &ast::Path) -> Option<Path> { |
411 | let src = self.find_file(path.syntax().clone()); | 434 | let src = self.find_file(path.syntax().clone()); |
412 | Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into())) | 435 | Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into())) |
413 | } | 436 | } |
414 | 437 | ||
415 | pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { | 438 | fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { |
416 | self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) | 439 | self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) |
417 | } | 440 | } |
418 | 441 | ||
419 | pub fn record_literal_missing_fields(&self, literal: &ast::RecordLit) -> Vec<(Field, Type)> { | 442 | fn record_literal_missing_fields(&self, literal: &ast::RecordLit) -> Vec<(Field, Type)> { |
420 | self.analyze(literal.syntax()) | 443 | self.analyze(literal.syntax()) |
421 | .record_literal_missing_fields(self.db, literal) | 444 | .record_literal_missing_fields(self.db, literal) |
422 | .unwrap_or_default() | 445 | .unwrap_or_default() |
423 | } | 446 | } |
424 | 447 | ||
425 | pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> { | 448 | fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> { |
426 | self.analyze(pattern.syntax()) | 449 | self.analyze(pattern.syntax()) |
427 | .record_pattern_missing_fields(self.db, pattern) | 450 | .record_pattern_missing_fields(self.db, pattern) |
428 | .unwrap_or_default() | 451 | .unwrap_or_default() |
@@ -434,23 +457,23 @@ impl<'db> SemanticsImpl<'db> { | |||
434 | f(&mut ctx) | 457 | f(&mut ctx) |
435 | } | 458 | } |
436 | 459 | ||
437 | pub fn to_module_def(&self, file: FileId) -> Option<Module> { | 460 | fn to_module_def(&self, file: FileId) -> Option<Module> { |
438 | self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) | 461 | self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) |
439 | } | 462 | } |
440 | 463 | ||
441 | pub fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { | 464 | fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { |
442 | let node = self.find_file(node.clone()); | 465 | let node = self.find_file(node.clone()); |
443 | let resolver = self.analyze2(node.as_ref(), None).resolver; | 466 | let resolver = self.analyze2(node.as_ref(), None).resolver; |
444 | SemanticsScope { db: self.db, resolver } | 467 | SemanticsScope { db: self.db, resolver } |
445 | } | 468 | } |
446 | 469 | ||
447 | pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> { | 470 | fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> { |
448 | let node = self.find_file(node.clone()); | 471 | let node = self.find_file(node.clone()); |
449 | let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver; | 472 | let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver; |
450 | SemanticsScope { db: self.db, resolver } | 473 | SemanticsScope { db: self.db, resolver } |
451 | } | 474 | } |
452 | 475 | ||
453 | pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> { | 476 | fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> { |
454 | let resolver = def.id.resolver(self.db.upcast()); | 477 | let resolver = def.id.resolver(self.db.upcast()); |
455 | SemanticsScope { db: self.db, resolver } | 478 | SemanticsScope { db: self.db, resolver } |
456 | } | 479 | } |
@@ -477,19 +500,20 @@ impl<'db> SemanticsImpl<'db> { | |||
477 | ChildContainer::ModuleId(it) => it.resolver(self.db.upcast()), | 500 | ChildContainer::ModuleId(it) => it.resolver(self.db.upcast()), |
478 | ChildContainer::EnumId(it) => it.resolver(self.db.upcast()), | 501 | ChildContainer::EnumId(it) => it.resolver(self.db.upcast()), |
479 | ChildContainer::VariantId(it) => it.resolver(self.db.upcast()), | 502 | ChildContainer::VariantId(it) => it.resolver(self.db.upcast()), |
503 | ChildContainer::TypeAliasId(it) => it.resolver(self.db.upcast()), | ||
480 | ChildContainer::GenericDefId(it) => it.resolver(self.db.upcast()), | 504 | ChildContainer::GenericDefId(it) => it.resolver(self.db.upcast()), |
481 | }; | 505 | }; |
482 | SourceAnalyzer::new_for_resolver(resolver, src) | 506 | SourceAnalyzer::new_for_resolver(resolver, src) |
483 | } | 507 | } |
484 | 508 | ||
485 | pub fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) { | 509 | fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) { |
486 | assert!(root_node.parent().is_none()); | 510 | assert!(root_node.parent().is_none()); |
487 | let mut cache = self.cache.borrow_mut(); | 511 | let mut cache = self.cache.borrow_mut(); |
488 | let prev = cache.insert(root_node, file_id); | 512 | let prev = cache.insert(root_node, file_id); |
489 | assert!(prev == None || prev == Some(file_id)) | 513 | assert!(prev == None || prev == Some(file_id)) |
490 | } | 514 | } |
491 | 515 | ||
492 | pub fn assert_contains_node(&self, node: &SyntaxNode) { | 516 | fn assert_contains_node(&self, node: &SyntaxNode) { |
493 | self.find_file(node.clone()); | 517 | self.find_file(node.clone()); |
494 | } | 518 | } |
495 | 519 | ||
@@ -498,7 +522,7 @@ impl<'db> SemanticsImpl<'db> { | |||
498 | cache.get(root_node).copied() | 522 | cache.get(root_node).copied() |
499 | } | 523 | } |
500 | 524 | ||
501 | pub fn find_file(&self, node: SyntaxNode) -> InFile<SyntaxNode> { | 525 | fn find_file(&self, node: SyntaxNode) -> InFile<SyntaxNode> { |
502 | let root_node = find_root(&node); | 526 | let root_node = find_root(&node); |
503 | let file_id = self.lookup(&root_node).unwrap_or_else(|| { | 527 | let file_id = self.lookup(&root_node).unwrap_or_else(|| { |
504 | panic!( | 528 | panic!( |
@@ -560,6 +584,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode { | |||
560 | node.ancestors().last().unwrap() | 584 | node.ancestors().last().unwrap() |
561 | } | 585 | } |
562 | 586 | ||
587 | #[derive(Debug)] | ||
563 | pub struct SemanticsScope<'a> { | 588 | pub struct SemanticsScope<'a> { |
564 | pub db: &'a dyn HirDatabase, | 589 | pub db: &'a dyn HirDatabase, |
565 | resolver: Resolver, | 590 | resolver: Resolver, |
diff --git a/crates/ra_hir/src/semantics/source_to_def.rs b/crates/ra_hir/src/semantics/source_to_def.rs index 8af64fdc1..42e5a1bdb 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 | }; |
18 | use rustc_hash::FxHashMap; | 18 | use rustc_hash::FxHashMap; |
19 | use stdx::impl_from; | ||
19 | 20 | ||
20 | use crate::{db::HirDatabase, InFile, MacroDefId}; | 21 | use crate::{db::HirDatabase, InFile, MacroDefId}; |
21 | 22 | ||
@@ -194,6 +195,10 @@ impl SourceToDefCtx<'_, '_> { | |||
194 | let def = self.const_to_def(container.with_value(it))?; | 195 | let def = self.const_to_def(container.with_value(it))?; |
195 | DefWithBodyId::from(def).into() | 196 | DefWithBodyId::from(def).into() |
196 | }, | 197 | }, |
198 | ast::TypeAliasDef(it) => { | ||
199 | let def = self.type_alias_to_def(container.with_value(it))?; | ||
200 | def.into() | ||
201 | }, | ||
197 | _ => continue, | 202 | _ => continue, |
198 | } | 203 | } |
199 | }; | 204 | }; |
@@ -246,19 +251,21 @@ pub(crate) enum ChildContainer { | |||
246 | ImplId(ImplId), | 251 | ImplId(ImplId), |
247 | EnumId(EnumId), | 252 | EnumId(EnumId), |
248 | VariantId(VariantId), | 253 | VariantId(VariantId), |
254 | TypeAliasId(TypeAliasId), | ||
249 | /// XXX: this might be the same def as, for example an `EnumId`. However, | 255 | /// XXX: this might be the same def as, for example an `EnumId`. However, |
250 | /// here the children generic parameters, and not, eg enum variants. | 256 | /// here the children generic parameters, and not, eg enum variants. |
251 | GenericDefId(GenericDefId), | 257 | GenericDefId(GenericDefId), |
252 | } | 258 | } |
253 | impl_froms! { | 259 | impl_from! { |
254 | ChildContainer: | ||
255 | DefWithBodyId, | 260 | DefWithBodyId, |
256 | ModuleId, | 261 | ModuleId, |
257 | TraitId, | 262 | TraitId, |
258 | ImplId, | 263 | ImplId, |
259 | EnumId, | 264 | EnumId, |
260 | VariantId, | 265 | VariantId, |
266 | TypeAliasId, | ||
261 | GenericDefId | 267 | GenericDefId |
268 | for ChildContainer | ||
262 | } | 269 | } |
263 | 270 | ||
264 | impl ChildContainer { | 271 | impl ChildContainer { |
@@ -271,6 +278,7 @@ impl ChildContainer { | |||
271 | ChildContainer::ImplId(it) => it.child_by_source(db), | 278 | ChildContainer::ImplId(it) => it.child_by_source(db), |
272 | ChildContainer::EnumId(it) => it.child_by_source(db), | 279 | ChildContainer::EnumId(it) => it.child_by_source(db), |
273 | ChildContainer::VariantId(it) => it.child_by_source(db), | 280 | ChildContainer::VariantId(it) => it.child_by_source(db), |
281 | ChildContainer::TypeAliasId(_) => DynMap::default(), | ||
274 | ChildContainer::GenericDefId(it) => it.child_by_source(db), | 282 | ChildContainer::GenericDefId(it) => it.child_by_source(db), |
275 | } | 283 | } |
276 | } | 284 | } |
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 1d6c47103..86a47a9e5 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 | }; |
19 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; | 19 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; |
20 | use hir_ty::{ | 20 | use 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 | }; |
24 | use ra_syntax::{ | 24 | use 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( |
@@ -341,7 +352,7 @@ 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( |