diff options
28 files changed, 763 insertions, 510 deletions
diff --git a/Cargo.lock b/Cargo.lock index ef3735197..8f7783deb 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -10,7 +10,7 @@ dependencies = [ | |||
10 | 10 | ||
11 | [[package]] | 11 | [[package]] |
12 | name = "anyhow" | 12 | name = "anyhow" |
13 | version = "1.0.19" | 13 | version = "1.0.22" |
14 | source = "registry+https://github.com/rust-lang/crates.io-index" | 14 | source = "registry+https://github.com/rust-lang/crates.io-index" |
15 | 15 | ||
16 | [[package]] | 16 | [[package]] |
@@ -276,14 +276,6 @@ dependencies = [ | |||
276 | 276 | ||
277 | [[package]] | 277 | [[package]] |
278 | name = "crossbeam-queue" | 278 | name = "crossbeam-queue" |
279 | version = "0.1.2" | ||
280 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
281 | dependencies = [ | ||
282 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
283 | ] | ||
284 | |||
285 | [[package]] | ||
286 | name = "crossbeam-queue" | ||
287 | version = "0.2.0" | 279 | version = "0.2.0" |
288 | source = "registry+https://github.com/rust-lang/crates.io-index" | 280 | source = "registry+https://github.com/rust-lang/crates.io-index" |
289 | dependencies = [ | 281 | dependencies = [ |
@@ -292,15 +284,6 @@ dependencies = [ | |||
292 | 284 | ||
293 | [[package]] | 285 | [[package]] |
294 | name = "crossbeam-utils" | 286 | name = "crossbeam-utils" |
295 | version = "0.6.6" | ||
296 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
297 | dependencies = [ | ||
298 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", | ||
299 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
300 | ] | ||
301 | |||
302 | [[package]] | ||
303 | name = "crossbeam-utils" | ||
304 | version = "0.7.0" | 287 | version = "0.7.0" |
305 | source = "registry+https://github.com/rust-lang/crates.io-index" | 288 | source = "registry+https://github.com/rust-lang/crates.io-index" |
306 | dependencies = [ | 289 | dependencies = [ |
@@ -1092,7 +1075,7 @@ dependencies = [ | |||
1092 | "ra_syntax 0.1.0", | 1075 | "ra_syntax 0.1.0", |
1093 | "ra_text_edit 0.1.0", | 1076 | "ra_text_edit 0.1.0", |
1094 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1077 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1095 | "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1078 | "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1096 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1079 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1097 | "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1080 | "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1098 | "test_utils 0.1.0", | 1081 | "test_utils 0.1.0", |
@@ -1371,22 +1354,22 @@ dependencies = [ | |||
1371 | 1354 | ||
1372 | [[package]] | 1355 | [[package]] |
1373 | name = "rayon" | 1356 | name = "rayon" |
1374 | version = "1.2.0" | 1357 | version = "1.2.1" |
1375 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1376 | dependencies = [ | 1359 | dependencies = [ |
1377 | "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1360 | "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1378 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1361 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1379 | "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1362 | "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1380 | ] | 1363 | ] |
1381 | 1364 | ||
1382 | [[package]] | 1365 | [[package]] |
1383 | name = "rayon-core" | 1366 | name = "rayon-core" |
1384 | version = "1.6.0" | 1367 | version = "1.6.1" |
1385 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1368 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1386 | dependencies = [ | 1369 | dependencies = [ |
1387 | "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1370 | "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1388 | "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1371 | "crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1389 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1372 | "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1390 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1373 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1391 | "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1374 | "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1392 | ] | 1375 | ] |
@@ -1833,7 +1816,7 @@ dependencies = [ | |||
1833 | name = "xtask" | 1816 | name = "xtask" |
1834 | version = "0.1.0" | 1817 | version = "0.1.0" |
1835 | dependencies = [ | 1818 | dependencies = [ |
1836 | "anyhow 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", | 1819 | "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", |
1837 | "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1820 | "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1838 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1821 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1839 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1822 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1857,7 +1840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1857 | 1840 | ||
1858 | [metadata] | 1841 | [metadata] |
1859 | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" | 1842 | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" |
1860 | "checksum anyhow 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "57114fc2a6cc374bce195d3482057c846e706d252ff3604363449695684d7a0d" | 1843 | "checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968" |
1861 | "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" | 1844 | "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" |
1862 | "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" | 1845 | "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" |
1863 | "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" | 1846 | "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" |
@@ -1887,9 +1870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1887 | "checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" | 1870 | "checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" |
1888 | "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" | 1871 | "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" |
1889 | "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" | 1872 | "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" |
1890 | "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" | ||
1891 | "checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" | 1873 | "checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" |
1892 | "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" | ||
1893 | "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" | 1874 | "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" |
1894 | "checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" | 1875 | "checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" |
1895 | "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" | 1876 | "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" |
@@ -1984,8 +1965,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1984 | "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" | 1965 | "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" |
1985 | "checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" | 1966 | "checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" |
1986 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" | 1967 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" |
1987 | "checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" | 1968 | "checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd" |
1988 | "checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" | 1969 | "checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791" |
1989 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" | 1970 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" |
1990 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" | 1971 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" |
1991 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" | 1972 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a132d128b..5690040a7 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -10,10 +10,12 @@ use hir_def::{ | |||
10 | adt::VariantData, | 10 | adt::VariantData, |
11 | body::scope::ExprScopes, | 11 | body::scope::ExprScopes, |
12 | builtin_type::BuiltinType, | 12 | builtin_type::BuiltinType, |
13 | nameres::per_ns::PerNs, | ||
14 | resolver::{HasResolver, TypeNs}, | ||
13 | traits::TraitData, | 15 | traits::TraitData, |
14 | type_ref::{Mutability, TypeRef}, | 16 | type_ref::{Mutability, TypeRef}, |
15 | AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, | 17 | ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, |
16 | LocalStructFieldId, Lookup, ModuleId, UnionId, | 18 | ModuleId, UnionId, |
17 | }; | 19 | }; |
18 | use hir_expand::{ | 20 | use hir_expand::{ |
19 | diagnostics::DiagnosticSink, | 21 | diagnostics::DiagnosticSink, |
@@ -25,14 +27,12 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | |||
25 | use crate::{ | 27 | use crate::{ |
26 | db::{AstDatabase, DefDatabase, HirDatabase}, | 28 | db::{AstDatabase, DefDatabase, HirDatabase}, |
27 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 29 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, |
28 | generics::{GenericDef, HasGenericParams}, | ||
29 | ids::{ | 30 | ids::{ |
30 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, | 31 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, |
31 | TypeAliasId, | 32 | TypeAliasId, |
32 | }, | 33 | }, |
33 | resolve::{HasResolver, TypeNs}, | ||
34 | ty::{InferenceResult, Namespace, TraitRef}, | 34 | ty::{InferenceResult, Namespace, TraitRef}, |
35 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, | 35 | Either, HasSource, ImportId, Name, Source, Ty, |
36 | }; | 36 | }; |
37 | 37 | ||
38 | /// hir::Crate describes a single crate. It's the main interface with which | 38 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -829,12 +829,12 @@ impl Trait { | |||
829 | } | 829 | } |
830 | 830 | ||
831 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | 831 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { |
832 | let resolver = self.resolver(db); | 832 | let resolver = self.id.resolver(db); |
833 | // returning the iterator directly doesn't easily work because of | 833 | // returning the iterator directly doesn't easily work because of |
834 | // lifetime problems, but since there usually shouldn't be more than a | 834 | // lifetime problems, but since there usually shouldn't be more than a |
835 | // few direct traits this should be fine (we could even use some kind of | 835 | // few direct traits this should be fine (we could even use some kind of |
836 | // SmallVec if performance is a concern) | 836 | // SmallVec if performance is a concern) |
837 | self.generic_params(db) | 837 | db.generic_params(self.id.into()) |
838 | .where_predicates | 838 | .where_predicates |
839 | .iter() | 839 | .iter() |
840 | .filter_map(|pred| match &pred.type_ref { | 840 | .filter_map(|pred| match &pred.type_ref { |
@@ -842,9 +842,10 @@ impl Trait { | |||
842 | _ => None, | 842 | _ => None, |
843 | }) | 843 | }) |
844 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { | 844 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { |
845 | Some(TypeNs::Trait(t)) => Some(t), | 845 | Some(TypeNs::TraitId(t)) => Some(t), |
846 | _ => None, | 846 | _ => None, |
847 | }) | 847 | }) |
848 | .map(Trait::from) | ||
848 | .collect() | 849 | .collect() |
849 | } | 850 | } |
850 | 851 | ||
@@ -871,14 +872,9 @@ impl Trait { | |||
871 | 872 | ||
872 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | 873 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { |
873 | let trait_data = self.trait_data(db); | 874 | let trait_data = self.trait_data(db); |
874 | trait_data | 875 | let res = |
875 | .items | 876 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; |
876 | .iter() | 877 | Some(res) |
877 | .filter_map(|item| match item { | ||
878 | AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)), | ||
879 | _ => None, | ||
880 | }) | ||
881 | .find(|t| &t.name(db) == name) | ||
882 | } | 878 | } |
883 | 879 | ||
884 | pub fn associated_type_by_name_including_super_traits( | 880 | pub fn associated_type_by_name_including_super_traits( |
@@ -978,16 +974,6 @@ pub enum AssocItem { | |||
978 | // casting them, and somehow making the constructors private, which would be annoying. | 974 | // casting them, and somehow making the constructors private, which would be annoying. |
979 | impl_froms!(AssocItem: Function, Const, TypeAlias); | 975 | impl_froms!(AssocItem: Function, Const, TypeAlias); |
980 | 976 | ||
981 | impl From<AssocItem> for crate::generics::GenericDef { | ||
982 | fn from(item: AssocItem) -> Self { | ||
983 | match item { | ||
984 | AssocItem::Function(f) => f.into(), | ||
985 | AssocItem::Const(c) => c.into(), | ||
986 | AssocItem::TypeAlias(t) => t.into(), | ||
987 | } | ||
988 | } | ||
989 | } | ||
990 | |||
991 | impl AssocItem { | 977 | impl AssocItem { |
992 | pub fn module(self, db: &impl DefDatabase) -> Module { | 978 | pub fn module(self, db: &impl DefDatabase) -> Module { |
993 | match self { | 979 | match self { |
@@ -1007,6 +993,39 @@ impl AssocItem { | |||
1007 | } | 993 | } |
1008 | } | 994 | } |
1009 | 995 | ||
996 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
997 | pub enum GenericDef { | ||
998 | Function(Function), | ||
999 | Adt(Adt), | ||
1000 | Trait(Trait), | ||
1001 | TypeAlias(TypeAlias), | ||
1002 | ImplBlock(ImplBlock), | ||
1003 | // enum variants cannot have generics themselves, but their parent enums | ||
1004 | // can, and this makes some code easier to write | ||
1005 | EnumVariant(EnumVariant), | ||
1006 | // consts can have type parameters from their parents (i.e. associated consts of traits) | ||
1007 | Const(Const), | ||
1008 | } | ||
1009 | impl_froms!( | ||
1010 | GenericDef: Function, | ||
1011 | Adt(Struct, Enum, Union), | ||
1012 | Trait, | ||
1013 | TypeAlias, | ||
1014 | ImplBlock, | ||
1015 | EnumVariant, | ||
1016 | Const | ||
1017 | ); | ||
1018 | |||
1019 | impl From<AssocItem> for GenericDef { | ||
1020 | fn from(item: AssocItem) -> Self { | ||
1021 | match item { | ||
1022 | AssocItem::Function(f) => f.into(), | ||
1023 | AssocItem::Const(c) => c.into(), | ||
1024 | AssocItem::TypeAlias(t) => t.into(), | ||
1025 | } | ||
1026 | } | ||
1027 | } | ||
1028 | |||
1010 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1029 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1011 | pub struct Local { | 1030 | pub struct Local { |
1012 | pub(crate) parent: DefWithBody, | 1031 | pub(crate) parent: DefWithBody, |
@@ -1068,3 +1087,26 @@ pub struct GenericParam { | |||
1068 | pub struct ImplBlock { | 1087 | pub struct ImplBlock { |
1069 | pub(crate) id: ImplId, | 1088 | pub(crate) id: ImplId, |
1070 | } | 1089 | } |
1090 | |||
1091 | /// For IDE only | ||
1092 | pub enum ScopeDef { | ||
1093 | ModuleDef(ModuleDef), | ||
1094 | MacroDef(MacroDef), | ||
1095 | GenericParam(GenericParam), | ||
1096 | ImplSelfType(ImplBlock), | ||
1097 | AdtSelfType(Adt), | ||
1098 | Local(Local), | ||
1099 | Unknown, | ||
1100 | } | ||
1101 | |||
1102 | impl From<PerNs> for ScopeDef { | ||
1103 | fn from(def: PerNs) -> Self { | ||
1104 | def.take_types() | ||
1105 | .or_else(|| def.take_values()) | ||
1106 | .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) | ||
1107 | .or_else(|| { | ||
1108 | def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) | ||
1109 | }) | ||
1110 | .unwrap_or(ScopeDef::Unknown) | ||
1111 | } | ||
1112 | } | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a9982a70f..ed0d68001 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -8,7 +8,6 @@ use ra_syntax::SmolStr; | |||
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | debug::HirDebugDatabase, | 10 | debug::HirDebugDatabase, |
11 | generics::GenericDef, | ||
12 | ids, | 11 | ids, |
13 | lang_item::{LangItemTarget, LangItems}, | 12 | lang_item::{LangItemTarget, LangItems}, |
14 | ty::{ | 13 | ty::{ |
@@ -18,8 +17,8 @@ use crate::{ | |||
18 | TypeCtor, | 17 | TypeCtor, |
19 | }, | 18 | }, |
20 | type_alias::TypeAliasData, | 19 | type_alias::TypeAliasData, |
21 | Const, ConstData, Crate, DefWithBody, FnData, Function, ImplBlock, Module, Static, StructField, | 20 | Const, ConstData, Crate, DefWithBody, FnData, Function, GenericDef, ImplBlock, Module, Static, |
22 | Trait, TypeAlias, | 21 | StructField, Trait, TypeAlias, |
23 | }; | 22 | }; |
24 | 23 | ||
25 | pub use hir_def::db::{ | 24 | pub use hir_def::db::{ |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 869879bdf..6b703d8b4 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::path::known; | 5 | use hir_def::{path::known, resolver::HasResolver}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use ra_syntax::ast; | 7 | use ra_syntax::ast; |
8 | use ra_syntax::AstPtr; | 8 | use ra_syntax::AstPtr; |
@@ -11,9 +11,8 @@ use rustc_hash::FxHashSet; | |||
11 | use crate::{ | 11 | use crate::{ |
12 | db::HirDatabase, | 12 | db::HirDatabase, |
13 | diagnostics::{MissingFields, MissingOkInTailExpr}, | 13 | diagnostics::{MissingFields, MissingOkInTailExpr}, |
14 | resolve::HasResolver, | ||
15 | ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, | 14 | ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, |
16 | Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, | 15 | Adt, Function, Name, Path, |
17 | }; | 16 | }; |
18 | 17 | ||
19 | pub use hir_def::{ | 18 | pub use hir_def::{ |
@@ -27,30 +26,6 @@ pub use hir_def::{ | |||
27 | }, | 26 | }, |
28 | }; | 27 | }; |
29 | 28 | ||
30 | // needs arbitrary_self_types to be a method... or maybe move to the def? | ||
31 | pub(crate) fn resolver_for_expr( | ||
32 | db: &impl HirDatabase, | ||
33 | owner: DefWithBody, | ||
34 | expr_id: ExprId, | ||
35 | ) -> Resolver { | ||
36 | let scopes = owner.expr_scopes(db); | ||
37 | resolver_for_scope(db, owner, scopes.scope_for(expr_id)) | ||
38 | } | ||
39 | |||
40 | pub(crate) fn resolver_for_scope( | ||
41 | db: &impl HirDatabase, | ||
42 | owner: DefWithBody, | ||
43 | scope_id: Option<ScopeId>, | ||
44 | ) -> Resolver { | ||
45 | let mut r = owner.resolver(db); | ||
46 | let scopes = owner.expr_scopes(db); | ||
47 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); | ||
48 | for scope in scope_chain.into_iter().rev() { | ||
49 | r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); | ||
50 | } | ||
51 | r | ||
52 | } | ||
53 | |||
54 | pub(crate) struct ExprValidator<'a, 'b: 'a> { | 29 | pub(crate) struct ExprValidator<'a, 'b: 'a> { |
55 | func: Function, | 30 | func: Function, |
56 | infer: Arc<InferenceResult>, | 31 | infer: Arc<InferenceResult>, |
@@ -146,13 +121,13 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
146 | 121 | ||
147 | let std_result_path = known::std_result_result(); | 122 | let std_result_path = known::std_result_result(); |
148 | 123 | ||
149 | let resolver = self.func.resolver(db); | 124 | let resolver = self.func.id.resolver(db); |
150 | let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) { | 125 | let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) { |
151 | Some(it) => it, | 126 | Some(it) => it, |
152 | _ => return, | 127 | _ => return, |
153 | }; | 128 | }; |
154 | 129 | ||
155 | let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum)); | 130 | let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into())); |
156 | let params = match &mismatch.expected { | 131 | let params = match &mismatch.expected { |
157 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, | 132 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, |
158 | _ => return, | 133 | _ => return, |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index b7692d407..e8ed04056 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -3,9 +3,22 @@ | |||
3 | //! It's unclear if we need this long-term, but it's definitelly useful while we | 3 | //! It's unclear if we need this long-term, but it's definitelly useful while we |
4 | //! are splitting the hir. | 4 | //! are splitting the hir. |
5 | 5 | ||
6 | use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId}; | 6 | use hir_def::{ |
7 | AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, | ||
8 | ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, | ||
9 | }; | ||
7 | 10 | ||
8 | use crate::{Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef}; | 11 | use crate::{ |
12 | ty::{CallableDef, TypableDef}, | ||
13 | Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef, | ||
14 | Static, TypeAlias, | ||
15 | }; | ||
16 | |||
17 | impl From<ra_db::CrateId> for Crate { | ||
18 | fn from(crate_id: ra_db::CrateId) -> Self { | ||
19 | Crate { crate_id } | ||
20 | } | ||
21 | } | ||
9 | 22 | ||
10 | macro_rules! from_id { | 23 | macro_rules! from_id { |
11 | ($(($id:path, $ty:path)),*) => {$( | 24 | ($(($id:path, $ty:path)),*) => {$( |
@@ -83,6 +96,16 @@ impl From<DefWithBody> for DefWithBodyId { | |||
83 | } | 96 | } |
84 | } | 97 | } |
85 | 98 | ||
99 | impl From<DefWithBodyId> for DefWithBody { | ||
100 | fn from(def: DefWithBodyId) -> Self { | ||
101 | match def { | ||
102 | DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()), | ||
103 | DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()), | ||
104 | DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()), | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
86 | impl From<AssocItemId> for AssocItem { | 109 | impl From<AssocItemId> for AssocItem { |
87 | fn from(def: AssocItemId) -> Self { | 110 | fn from(def: AssocItemId) -> Self { |
88 | match def { | 111 | match def { |
@@ -122,3 +145,77 @@ impl From<GenericDefId> for GenericDef { | |||
122 | } | 145 | } |
123 | } | 146 | } |
124 | } | 147 | } |
148 | |||
149 | impl From<AdtId> for TypableDef { | ||
150 | fn from(id: AdtId) -> Self { | ||
151 | Adt::from(id).into() | ||
152 | } | ||
153 | } | ||
154 | |||
155 | impl From<StructId> for TypableDef { | ||
156 | fn from(id: StructId) -> Self { | ||
157 | AdtId::StructId(id).into() | ||
158 | } | ||
159 | } | ||
160 | |||
161 | impl From<UnionId> for TypableDef { | ||
162 | fn from(id: UnionId) -> Self { | ||
163 | AdtId::UnionId(id).into() | ||
164 | } | ||
165 | } | ||
166 | |||
167 | impl From<EnumId> for TypableDef { | ||
168 | fn from(id: EnumId) -> Self { | ||
169 | AdtId::EnumId(id).into() | ||
170 | } | ||
171 | } | ||
172 | |||
173 | impl From<EnumVariantId> for TypableDef { | ||
174 | fn from(id: EnumVariantId) -> Self { | ||
175 | EnumVariant::from(id).into() | ||
176 | } | ||
177 | } | ||
178 | |||
179 | impl From<TypeAliasId> for TypableDef { | ||
180 | fn from(id: TypeAliasId) -> Self { | ||
181 | TypeAlias::from(id).into() | ||
182 | } | ||
183 | } | ||
184 | |||
185 | impl From<FunctionId> for TypableDef { | ||
186 | fn from(id: FunctionId) -> Self { | ||
187 | Function::from(id).into() | ||
188 | } | ||
189 | } | ||
190 | impl From<ConstId> for TypableDef { | ||
191 | fn from(id: ConstId) -> Self { | ||
192 | Const::from(id).into() | ||
193 | } | ||
194 | } | ||
195 | impl From<StaticId> for TypableDef { | ||
196 | fn from(id: StaticId) -> Self { | ||
197 | Static::from(id).into() | ||
198 | } | ||
199 | } | ||
200 | |||
201 | impl From<Adt> for GenericDefId { | ||
202 | fn from(id: Adt) -> Self { | ||
203 | match id { | ||
204 | Adt::Struct(it) => it.id.into(), | ||
205 | Adt::Union(it) => it.id.into(), | ||
206 | Adt::Enum(it) => it.id.into(), | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | impl From<CallableDef> for GenericDefId { | ||
212 | fn from(def: CallableDef) -> Self { | ||
213 | match def { | ||
214 | CallableDef::Function(it) => it.id.into(), | ||
215 | CallableDef::Struct(it) => it.id.into(), | ||
216 | CallableDef::EnumVariant(it) => { | ||
217 | EnumVariantId { parent: it.parent.id, local_id: it.id }.into() | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | } | ||
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs deleted file mode 100644 index f1bf2ee9d..000000000 --- a/crates/ra_hir/src/generics.rs +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | //! Temp module to wrap hir_def::generics | ||
2 | use std::sync::Arc; | ||
3 | |||
4 | use crate::{ | ||
5 | db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, | ||
6 | TypeAlias, Union, | ||
7 | }; | ||
8 | |||
9 | pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate}; | ||
10 | |||
11 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
12 | pub enum GenericDef { | ||
13 | Function(Function), | ||
14 | Adt(Adt), | ||
15 | Trait(Trait), | ||
16 | TypeAlias(TypeAlias), | ||
17 | ImplBlock(ImplBlock), | ||
18 | // enum variants cannot have generics themselves, but their parent enums | ||
19 | // can, and this makes some code easier to write | ||
20 | EnumVariant(EnumVariant), | ||
21 | // consts can have type parameters from their parents (i.e. associated consts of traits) | ||
22 | Const(Const), | ||
23 | } | ||
24 | impl_froms!( | ||
25 | GenericDef: Function, | ||
26 | Adt(Struct, Enum, Union), | ||
27 | Trait, | ||
28 | TypeAlias, | ||
29 | ImplBlock, | ||
30 | EnumVariant, | ||
31 | Const | ||
32 | ); | ||
33 | |||
34 | impl From<Container> for GenericDef { | ||
35 | fn from(c: Container) -> Self { | ||
36 | match c { | ||
37 | Container::Trait(trait_) => trait_.into(), | ||
38 | Container::ImplBlock(impl_block) => impl_block.into(), | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | |||
43 | pub trait HasGenericParams: Copy { | ||
44 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>; | ||
45 | } | ||
46 | |||
47 | impl<T> HasGenericParams for T | ||
48 | where | ||
49 | T: Into<GenericDef> + Copy, | ||
50 | { | ||
51 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
52 | db.generic_params(self.into().into()) | ||
53 | } | ||
54 | } | ||
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 964a3da8c..774fa1d96 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -1,11 +1,10 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{type_ref::TypeRef, AstItemDef}; | 3 | use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef}; |
4 | use ra_syntax::ast::{self}; | 4 | use ra_syntax::ast; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | 7 | db::{AstDatabase, DefDatabase, HirDatabase}, |
8 | resolve::HasResolver, | ||
9 | ty::Ty, | 8 | ty::Ty, |
10 | AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, | 9 | AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, |
11 | }; | 10 | }; |
@@ -27,12 +26,12 @@ impl ImplBlock { | |||
27 | } | 26 | } |
28 | 27 | ||
29 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | 28 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { |
30 | Ty::from_hir(db, &self.resolver(db), &self.target_type(db)) | 29 | Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) |
31 | } | 30 | } |
32 | 31 | ||
33 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | 32 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { |
34 | let target_ty = self.target_ty(db); | 33 | let target_ty = self.target_ty(db); |
35 | TraitRef::from_hir(db, &self.resolver(db), &self.target_trait(db)?, Some(target_ty)) | 34 | TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) |
36 | } | 35 | } |
37 | 36 | ||
38 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | 37 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 31da74d2f..8c6834392 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -37,8 +37,6 @@ mod ty; | |||
37 | mod impl_block; | 37 | mod impl_block; |
38 | mod expr; | 38 | mod expr; |
39 | mod lang_item; | 39 | mod lang_item; |
40 | pub mod generics; | ||
41 | mod resolve; | ||
42 | pub mod diagnostics; | 40 | pub mod diagnostics; |
43 | mod util; | 41 | mod util; |
44 | 42 | ||
@@ -52,23 +50,19 @@ mod test_db; | |||
52 | #[cfg(test)] | 50 | #[cfg(test)] |
53 | mod marks; | 51 | mod marks; |
54 | 52 | ||
55 | use crate::resolve::Resolver; | ||
56 | |||
57 | pub use crate::{ | 53 | pub use crate::{ |
58 | code_model::{ | 54 | code_model::{ |
59 | attrs::{AttrDef, Attrs}, | 55 | attrs::{AttrDef, Attrs}, |
60 | docs::{DocDef, Docs, Documentation}, | 56 | docs::{DocDef, Docs, Documentation}, |
61 | src::{HasBodySource, HasSource}, | 57 | src::{HasBodySource, HasSource}, |
62 | Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, | 58 | Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, |
63 | EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, | 59 | EnumVariant, FieldSource, FnData, Function, GenericDef, GenericParam, HasBody, ImplBlock, |
64 | MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, | 60 | Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, |
65 | Union, VariantDef, | 61 | Trait, TypeAlias, Union, VariantDef, |
66 | }, | 62 | }, |
67 | expr::ExprScopes, | 63 | expr::ExprScopes, |
68 | from_source::FromSource, | 64 | from_source::FromSource, |
69 | generics::GenericDef, | ||
70 | ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, | 65 | ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, |
71 | resolve::ScopeDef, | ||
72 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 66 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
73 | ty::{ | 67 | ty::{ |
74 | display::HirDisplay, | 68 | display::HirDisplay, |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 727310f06..797f90d50 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -10,6 +10,8 @@ use std::sync::Arc; | |||
10 | use hir_def::{ | 10 | use hir_def::{ |
11 | expr::{ExprId, PatId}, | 11 | expr::{ExprId, PatId}, |
12 | path::known, | 12 | path::known, |
13 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | ||
14 | DefWithBodyId, | ||
13 | }; | 15 | }; |
14 | use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; | 16 | use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; |
15 | use ra_syntax::{ | 17 | use ra_syntax::{ |
@@ -21,12 +23,12 @@ use ra_syntax::{ | |||
21 | 23 | ||
22 | use crate::{ | 24 | use crate::{ |
23 | db::HirDatabase, | 25 | db::HirDatabase, |
24 | expr::{self, BodySourceMap, ExprScopes, ScopeId}, | 26 | expr::{BodySourceMap, ExprScopes, ScopeId}, |
25 | ids::LocationCtx, | 27 | ids::LocationCtx, |
26 | resolve::{HasResolver, ScopeDef, TypeNs, ValueNs}, | ||
27 | ty::method_resolution::{self, implements_trait}, | 28 | ty::method_resolution::{self, implements_trait}, |
28 | AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, | 29 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, |
29 | HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, | 30 | GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static, |
31 | Struct, Trait, Ty, TypeAlias, | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 34 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { |
@@ -34,23 +36,25 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - | |||
34 | match (node.value) { | 36 | match (node.value) { |
35 | ast::Module(it) => { | 37 | ast::Module(it) => { |
36 | let src = node.with_value(it); | 38 | let src = node.with_value(it); |
37 | Some(crate::Module::from_declaration(db, src)?.resolver(db)) | 39 | Some(crate::Module::from_declaration(db, src)?.id.resolver(db)) |
38 | }, | 40 | }, |
39 | ast::SourceFile(it) => { | 41 | ast::SourceFile(it) => { |
40 | let src = node.with_value(crate::ModuleSource::SourceFile(it)); | 42 | let src = node.with_value(crate::ModuleSource::SourceFile(it)); |
41 | Some(crate::Module::from_definition(db, src)?.resolver(db)) | 43 | Some(crate::Module::from_definition(db, src)?.id.resolver(db)) |
42 | }, | 44 | }, |
43 | ast::StructDef(it) => { | 45 | ast::StructDef(it) => { |
44 | let src = node.with_value(it); | 46 | let src = node.with_value(it); |
45 | Some(Struct::from_source(db, src)?.resolver(db)) | 47 | Some(Struct::from_source(db, src)?.id.resolver(db)) |
46 | }, | 48 | }, |
47 | ast::EnumDef(it) => { | 49 | ast::EnumDef(it) => { |
48 | let src = node.with_value(it); | 50 | let src = node.with_value(it); |
49 | Some(Enum::from_source(db, src)?.resolver(db)) | 51 | Some(Enum::from_source(db, src)?.id.resolver(db)) |
50 | }, | 52 | }, |
51 | _ => match node.value.kind() { | 53 | _ => match node.value.kind() { |
52 | FN_DEF | CONST_DEF | STATIC_DEF => { | 54 | FN_DEF | CONST_DEF | STATIC_DEF => { |
53 | Some(def_with_body_from_child_node(db, node)?.resolver(db)) | 55 | let def = def_with_body_from_child_node(db, node)?; |
56 | let def = DefWithBodyId::from(def); | ||
57 | Some(def.resolver(db)) | ||
54 | } | 58 | } |
55 | // FIXME add missing cases | 59 | // FIXME add missing cases |
56 | _ => None | 60 | _ => None |
@@ -127,6 +131,7 @@ pub struct ReferenceDescriptor { | |||
127 | } | 131 | } |
128 | 132 | ||
129 | pub struct Expansion { | 133 | pub struct Expansion { |
134 | macro_file_kind: MacroFileKind, | ||
130 | macro_call_id: MacroCallId, | 135 | macro_call_id: MacroCallId, |
131 | } | 136 | } |
132 | 137 | ||
@@ -141,7 +146,7 @@ impl Expansion { | |||
141 | } | 146 | } |
142 | 147 | ||
143 | pub fn file_id(&self) -> HirFileId { | 148 | pub fn file_id(&self) -> HirFileId { |
144 | self.macro_call_id.as_file(MacroFileKind::Items) | 149 | self.macro_call_id.as_file(self.macro_file_kind) |
145 | } | 150 | } |
146 | } | 151 | } |
147 | 152 | ||
@@ -159,7 +164,7 @@ impl SourceAnalyzer { | |||
159 | None => scope_for(&scopes, &source_map, node), | 164 | None => scope_for(&scopes, &source_map, node), |
160 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), | 165 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), |
161 | }; | 166 | }; |
162 | let resolver = expr::resolver_for_scope(db, def, scope); | 167 | let resolver = resolver_for_scope(db, def.into(), scope); |
163 | SourceAnalyzer { | 168 | SourceAnalyzer { |
164 | resolver, | 169 | resolver, |
165 | body_owner: Some(def), | 170 | body_owner: Some(def), |
@@ -231,7 +236,7 @@ impl SourceAnalyzer { | |||
231 | ) -> Option<MacroDef> { | 236 | ) -> Option<MacroDef> { |
232 | // This must be a normal source file rather than macro file. | 237 | // This must be a normal source file rather than macro file. |
233 | let path = macro_call.path().and_then(Path::from_ast)?; | 238 | let path = macro_call.path().and_then(Path::from_ast)?; |
234 | self.resolver.resolve_path_as_macro(db, &path) | 239 | self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) |
235 | } | 240 | } |
236 | 241 | ||
237 | pub fn resolve_hir_path( | 242 | pub fn resolve_hir_path( |
@@ -240,16 +245,18 @@ impl SourceAnalyzer { | |||
240 | path: &crate::Path, | 245 | path: &crate::Path, |
241 | ) -> Option<PathResolution> { | 246 | ) -> Option<PathResolution> { |
242 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { | 247 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { |
243 | TypeNs::SelfType(it) => PathResolution::SelfType(it), | 248 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
244 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { | 249 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { |
245 | parent: self.resolver.generic_def().unwrap(), | 250 | parent: self.resolver.generic_def().unwrap().into(), |
246 | idx, | 251 | idx, |
247 | }), | 252 | }), |
248 | TypeNs::AdtSelfType(it) | TypeNs::Adt(it) => PathResolution::Def(it.into()), | 253 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
249 | TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), | 254 | PathResolution::Def(Adt::from(it).into()) |
250 | TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), | 255 | } |
256 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
257 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | ||
251 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | 258 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), |
252 | TypeNs::Trait(it) => PathResolution::Def(it.into()), | 259 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
253 | }); | 260 | }); |
254 | let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { | 261 | let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { |
255 | let res = match val { | 262 | let res = match val { |
@@ -257,11 +264,11 @@ impl SourceAnalyzer { | |||
257 | let var = Local { parent: self.body_owner?, pat_id }; | 264 | let var = Local { parent: self.body_owner?, pat_id }; |
258 | PathResolution::Local(var) | 265 | PathResolution::Local(var) |
259 | } | 266 | } |
260 | ValueNs::Function(it) => PathResolution::Def(it.into()), | 267 | ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), |
261 | ValueNs::Const(it) => PathResolution::Def(it.into()), | 268 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), |
262 | ValueNs::Static(it) => PathResolution::Def(it.into()), | 269 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), |
263 | ValueNs::Struct(it) => PathResolution::Def(it.into()), | 270 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), |
264 | ValueNs::EnumVariant(it) => PathResolution::Def(it.into()), | 271 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), |
265 | }; | 272 | }; |
266 | Some(res) | 273 | Some(res) |
267 | }); | 274 | }); |
@@ -272,7 +279,9 @@ impl SourceAnalyzer { | |||
272 | .take_types() | 279 | .take_types() |
273 | .map(|it| PathResolution::Def(it.into())); | 280 | .map(|it| PathResolution::Def(it.into())); |
274 | types.or(values).or(items).or_else(|| { | 281 | types.or(values).or(items).or_else(|| { |
275 | self.resolver.resolve_path_as_macro(db, &path).map(|def| PathResolution::Macro(def)) | 282 | self.resolver |
283 | .resolve_path_as_macro(db, &path) | ||
284 | .map(|def| PathResolution::Macro(def.into())) | ||
276 | }) | 285 | }) |
277 | } | 286 | } |
278 | 287 | ||
@@ -307,7 +316,22 @@ impl SourceAnalyzer { | |||
307 | } | 316 | } |
308 | 317 | ||
309 | pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { | 318 | pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { |
310 | self.resolver.process_all_names(db, f) | 319 | self.resolver.process_all_names(db, &mut |name, def| { |
320 | let def = match def { | ||
321 | resolver::ScopeDef::PerNs(it) => it.into(), | ||
322 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), | ||
323 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), | ||
324 | resolver::ScopeDef::GenericParam(idx) => { | ||
325 | let parent = self.resolver.generic_def().unwrap().into(); | ||
326 | ScopeDef::GenericParam(GenericParam { parent, idx }) | ||
327 | } | ||
328 | resolver::ScopeDef::Local(pat_id) => { | ||
329 | let parent = self.resolver.body_owner().unwrap().into(); | ||
330 | ScopeDef::Local(Local { parent, pat_id }) | ||
331 | } | ||
332 | }; | ||
333 | f(name, def) | ||
334 | }) | ||
311 | } | 335 | } |
312 | 336 | ||
313 | // FIXME: we only use this in `inline_local_variable` assist, ideally, we | 337 | // FIXME: we only use this in `inline_local_variable` assist, ideally, we |
@@ -392,7 +416,7 @@ impl SourceAnalyzer { | |||
392 | let std_future_path = known::std_future_future(); | 416 | let std_future_path = known::std_future_future(); |
393 | 417 | ||
394 | let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { | 418 | let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { |
395 | Some(it) => it, | 419 | Some(it) => it.into(), |
396 | _ => return false, | 420 | _ => return false, |
397 | }; | 421 | }; |
398 | 422 | ||
@@ -402,7 +426,7 @@ impl SourceAnalyzer { | |||
402 | }; | 426 | }; |
403 | 427 | ||
404 | let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; | 428 | let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; |
405 | implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) | 429 | implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) |
406 | } | 430 | } |
407 | 431 | ||
408 | pub fn expand( | 432 | pub fn expand( |
@@ -416,7 +440,10 @@ impl SourceAnalyzer { | |||
416 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | 440 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), |
417 | ); | 441 | ); |
418 | let macro_call_loc = MacroCallLoc { def, ast_id }; | 442 | let macro_call_loc = MacroCallLoc { def, ast_id }; |
419 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) | 443 | Some(Expansion { |
444 | macro_call_id: db.intern_macro(macro_call_loc), | ||
445 | macro_file_kind: to_macro_file_kind(macro_call.value), | ||
446 | }) | ||
420 | } | 447 | } |
421 | 448 | ||
422 | #[cfg(test)] | 449 | #[cfg(test)] |
@@ -515,3 +542,35 @@ fn adjust( | |||
515 | }) | 542 | }) |
516 | .map(|(_ptr, scope)| *scope) | 543 | .map(|(_ptr, scope)| *scope) |
517 | } | 544 | } |
545 | |||
546 | /// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to. | ||
547 | /// FIXME: Not completed | ||
548 | fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind { | ||
549 | let syn = macro_call.syntax(); | ||
550 | let parent = match syn.parent() { | ||
551 | Some(it) => it, | ||
552 | None => { | ||
553 | // FIXME: | ||
554 | // If it is root, which means the parent HirFile | ||
555 | // MacroKindFile must be non-items | ||
556 | // return expr now. | ||
557 | return MacroFileKind::Expr; | ||
558 | } | ||
559 | }; | ||
560 | |||
561 | match parent.kind() { | ||
562 | MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items, | ||
563 | LET_STMT => { | ||
564 | // FIXME: Handle Pattern | ||
565 | MacroFileKind::Expr | ||
566 | } | ||
567 | EXPR_STMT => MacroFileKind::Statements, | ||
568 | BLOCK => MacroFileKind::Statements, | ||
569 | ARG_LIST => MacroFileKind::Expr, | ||
570 | TRY_EXPR => MacroFileKind::Expr, | ||
571 | _ => { | ||
572 | // Unknown , Just guess it is `Items` | ||
573 | MacroFileKind::Items | ||
574 | } | ||
575 | } | ||
576 | } | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 36ece723f..95b8df181 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -17,12 +17,11 @@ use std::ops::Deref; | |||
17 | use std::sync::Arc; | 17 | use std::sync::Arc; |
18 | use std::{fmt, iter, mem}; | 18 | use std::{fmt, iter, mem}; |
19 | 19 | ||
20 | use hir_def::{generics::GenericParams, AdtId}; | ||
21 | |||
20 | use crate::{ | 22 | use crate::{ |
21 | db::HirDatabase, | 23 | db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, |
22 | expr::ExprId, | 24 | GenericDef, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, |
23 | generics::{GenericParams, HasGenericParams}, | ||
24 | util::make_mut_slice, | ||
25 | Adt, Crate, DefWithBody, FloatTy, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, | ||
26 | }; | 25 | }; |
27 | use display::{HirDisplay, HirFormatter}; | 26 | use display::{HirDisplay, HirFormatter}; |
28 | 27 | ||
@@ -131,15 +130,15 @@ impl TypeCtor { | |||
131 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | 130 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure |
132 | => 1, | 131 | => 1, |
133 | TypeCtor::Adt(adt) => { | 132 | TypeCtor::Adt(adt) => { |
134 | let generic_params = adt.generic_params(db); | 133 | let generic_params = db.generic_params(AdtId::from(adt).into()); |
135 | generic_params.count_params_including_parent() | 134 | generic_params.count_params_including_parent() |
136 | } | 135 | } |
137 | TypeCtor::FnDef(callable) => { | 136 | TypeCtor::FnDef(callable) => { |
138 | let generic_params = callable.generic_params(db); | 137 | let generic_params = db.generic_params(callable.into()); |
139 | generic_params.count_params_including_parent() | 138 | generic_params.count_params_including_parent() |
140 | } | 139 | } |
141 | TypeCtor::AssociatedType(type_alias) => { | 140 | TypeCtor::AssociatedType(type_alias) => { |
142 | let generic_params = type_alias.generic_params(db); | 141 | let generic_params = db.generic_params(type_alias.id.into()); |
143 | generic_params.count_params_including_parent() | 142 | generic_params.count_params_including_parent() |
144 | } | 143 | } |
145 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, | 144 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, |
@@ -168,7 +167,7 @@ impl TypeCtor { | |||
168 | } | 167 | } |
169 | } | 168 | } |
170 | 169 | ||
171 | pub fn as_generic_def(self) -> Option<crate::generics::GenericDef> { | 170 | pub fn as_generic_def(self) -> Option<crate::GenericDef> { |
172 | match self { | 171 | match self { |
173 | TypeCtor::Bool | 172 | TypeCtor::Bool |
174 | | TypeCtor::Char | 173 | | TypeCtor::Char |
@@ -348,8 +347,9 @@ impl Substs { | |||
348 | ) | 347 | ) |
349 | } | 348 | } |
350 | 349 | ||
351 | pub fn build_for_def(db: &impl HirDatabase, def: impl HasGenericParams) -> SubstsBuilder { | 350 | pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDef>) -> SubstsBuilder { |
352 | let params = def.generic_params(db); | 351 | let def = def.into(); |
352 | let params = db.generic_params(def.into()); | ||
353 | let param_count = params.count_params_including_parent(); | 353 | let param_count = params.count_params_including_parent(); |
354 | Substs::builder(param_count) | 354 | Substs::builder(param_count) |
355 | } | 355 | } |
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 872a4517d..b60e4bb31 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs | |||
@@ -5,11 +5,12 @@ | |||
5 | 5 | ||
6 | use std::iter::successors; | 6 | use std::iter::successors; |
7 | 7 | ||
8 | use hir_def::resolver::Resolver; | ||
8 | use hir_expand::name; | 9 | use hir_expand::name; |
9 | use log::{info, warn}; | 10 | use log::{info, warn}; |
10 | 11 | ||
11 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; | 12 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; |
12 | use crate::{db::HirDatabase, generics::HasGenericParams, Resolver}; | 13 | use crate::db::HirDatabase; |
13 | 14 | ||
14 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 15 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
15 | 16 | ||
@@ -39,13 +40,13 @@ fn deref_by_trait( | |||
39 | ty: &Canonical<Ty>, | 40 | ty: &Canonical<Ty>, |
40 | ) -> Option<Canonical<Ty>> { | 41 | ) -> Option<Canonical<Ty>> { |
41 | let krate = resolver.krate()?; | 42 | let krate = resolver.krate()?; |
42 | let deref_trait = match db.lang_item(krate, "deref".into())? { | 43 | let deref_trait = match db.lang_item(krate.into(), "deref".into())? { |
43 | crate::lang_item::LangItemTarget::Trait(t) => t, | 44 | crate::lang_item::LangItemTarget::Trait(t) => t, |
44 | _ => return None, | 45 | _ => return None, |
45 | }; | 46 | }; |
46 | let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; | 47 | let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; |
47 | 48 | ||
48 | let generic_params = target.generic_params(db); | 49 | let generic_params = db.generic_params(target.id.into()); |
49 | if generic_params.count_params_including_parent() != 1 { | 50 | if generic_params.count_params_including_parent() != 1 { |
50 | // the Target type + Deref trait should only have one generic parameter, | 51 | // the Target type + Deref trait should only have one generic parameter, |
51 | // namely Deref's Self type | 52 | // namely Deref's Self type |
@@ -71,7 +72,7 @@ fn deref_by_trait( | |||
71 | 72 | ||
72 | let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; | 73 | let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; |
73 | 74 | ||
74 | let solution = db.trait_solve(krate, canonical)?; | 75 | let solution = db.trait_solve(krate.into(), canonical)?; |
75 | 76 | ||
76 | match &solution { | 77 | match &solution { |
77 | Solution::Unique(vars) => { | 78 | Solution::Unique(vars) => { |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 7f9e81d64..69b13baef 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -23,7 +23,9 @@ use rustc_hash::FxHashMap; | |||
23 | 23 | ||
24 | use hir_def::{ | 24 | use hir_def::{ |
25 | path::known, | 25 | path::known, |
26 | resolver::{HasResolver, Resolver, TypeNs}, | ||
26 | type_ref::{Mutability, TypeRef}, | 27 | type_ref::{Mutability, TypeRef}, |
28 | AdtId, DefWithBodyId, | ||
27 | }; | 29 | }; |
28 | use hir_expand::{diagnostics::DiagnosticSink, name}; | 30 | use hir_expand::{diagnostics::DiagnosticSink, name}; |
29 | use ra_arena::map::ArenaMap; | 31 | use ra_arena::map::ArenaMap; |
@@ -40,10 +42,9 @@ use crate::{ | |||
40 | code_model::TypeAlias, | 42 | code_model::TypeAlias, |
41 | db::HirDatabase, | 43 | db::HirDatabase, |
42 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 44 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
43 | resolve::{HasResolver, Resolver, TypeNs}, | ||
44 | ty::infer::diagnostics::InferenceDiagnostic, | 45 | ty::infer::diagnostics::InferenceDiagnostic, |
45 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, | 46 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, |
46 | StructField, VariantDef, | 47 | StructField, Trait, VariantDef, |
47 | }; | 48 | }; |
48 | 49 | ||
49 | macro_rules! ty_app { | 50 | macro_rules! ty_app { |
@@ -64,7 +65,7 @@ mod coerce; | |||
64 | /// The entry point of type inference. | 65 | /// The entry point of type inference. |
65 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 66 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { |
66 | let _p = profile("infer_query"); | 67 | let _p = profile("infer_query"); |
67 | let resolver = def.resolver(db); | 68 | let resolver = DefWithBodyId::from(def).resolver(db); |
68 | let mut ctx = InferenceContext::new(db, def, resolver); | 69 | let mut ctx = InferenceContext::new(db, def, resolver); |
69 | 70 | ||
70 | match def { | 71 | match def { |
@@ -377,8 +378,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
377 | for obligation in obligations { | 378 | for obligation in obligations { |
378 | let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); | 379 | let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); |
379 | let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); | 380 | let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); |
380 | let solution = | 381 | let solution = self |
381 | self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); | 382 | .db |
383 | .trait_solve(self.resolver.krate().unwrap().into(), canonicalized.value.clone()); | ||
382 | 384 | ||
383 | match solution { | 385 | match solution { |
384 | Some(Solution::Unique(substs)) => { | 386 | Some(Solution::Unique(substs)) => { |
@@ -518,17 +520,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
518 | // FIXME: this should resolve assoc items as well, see this example: | 520 | // FIXME: this should resolve assoc items as well, see this example: |
519 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 | 521 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 |
520 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { | 522 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { |
521 | Some(TypeNs::Adt(Adt::Struct(it))) => it.into(), | 523 | Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), |
522 | Some(TypeNs::Adt(Adt::Union(it))) => it.into(), | 524 | Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), |
523 | Some(TypeNs::AdtSelfType(adt)) => adt.into(), | 525 | Some(TypeNs::AdtSelfType(adt)) => adt.into(), |
524 | Some(TypeNs::EnumVariant(it)) => it.into(), | 526 | Some(TypeNs::EnumVariantId(it)) => it.into(), |
525 | Some(TypeNs::TypeAlias(it)) => it.into(), | 527 | Some(TypeNs::TypeAliasId(it)) => it.into(), |
526 | 528 | ||
527 | Some(TypeNs::SelfType(_)) | | 529 | Some(TypeNs::SelfType(_)) | |
528 | Some(TypeNs::GenericParam(_)) | | 530 | Some(TypeNs::GenericParam(_)) | |
529 | Some(TypeNs::BuiltinType(_)) | | 531 | Some(TypeNs::BuiltinType(_)) | |
530 | Some(TypeNs::Trait(_)) | | 532 | Some(TypeNs::TraitId(_)) | |
531 | Some(TypeNs::Adt(Adt::Enum(_))) | | 533 | Some(TypeNs::AdtId(AdtId::EnumId(_))) | |
532 | None => { | 534 | None => { |
533 | return (Ty::Unknown, None) | 535 | return (Ty::Unknown, None) |
534 | } | 536 | } |
@@ -576,26 +578,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
576 | 578 | ||
577 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { | 579 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { |
578 | let path = known::std_iter_into_iterator(); | 580 | let path = known::std_iter_into_iterator(); |
579 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 581 | let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); |
580 | trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) | 582 | trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) |
581 | } | 583 | } |
582 | 584 | ||
583 | fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { | 585 | fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { |
584 | let path = known::std_ops_try(); | 586 | let path = known::std_ops_try(); |
585 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 587 | let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); |
586 | trait_.associated_type_by_name(self.db, &name::OK_TYPE) | 588 | trait_.associated_type_by_name(self.db, &name::OK_TYPE) |
587 | } | 589 | } |
588 | 590 | ||
589 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { | 591 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { |
590 | let path = known::std_future_future(); | 592 | let path = known::std_future_future(); |
591 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 593 | let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); |
592 | trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) | 594 | trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) |
593 | } | 595 | } |
594 | 596 | ||
595 | fn resolve_boxed_box(&self) -> Option<Adt> { | 597 | fn resolve_boxed_box(&self) -> Option<Adt> { |
596 | let path = known::std_boxed_box(); | 598 | let path = known::std_boxed_box(); |
597 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | 599 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; |
598 | Some(Adt::Struct(struct_)) | 600 | Some(Adt::Struct(struct_.into())) |
599 | } | 601 | } |
600 | } | 602 | } |
601 | 603 | ||
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 6ea135126..0772b9df5 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs | |||
@@ -4,19 +4,19 @@ | |||
4 | //! | 4 | //! |
5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
6 | 6 | ||
7 | use hir_def::resolver::Resolver; | ||
7 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
8 | |||
9 | use test_utils::tested_by; | 9 | use test_utils::tested_by; |
10 | 10 | ||
11 | use super::{InferTy, InferenceContext, TypeVarValue}; | ||
12 | use crate::{ | 11 | use crate::{ |
13 | db::HirDatabase, | 12 | db::HirDatabase, |
14 | lang_item::LangItemTarget, | 13 | lang_item::LangItemTarget, |
15 | resolve::Resolver, | ||
16 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, | 14 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, |
17 | Adt, Mutability, | 15 | Adt, Mutability, |
18 | }; | 16 | }; |
19 | 17 | ||
18 | use super::{InferTy, InferenceContext, TypeVarValue}; | ||
19 | |||
20 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 20 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
21 | /// Unify two types, but may coerce the first one to the second one | 21 | /// Unify two types, but may coerce the first one to the second one |
22 | /// using "implicit coercion rules" if needed. | 22 | /// using "implicit coercion rules" if needed. |
@@ -49,8 +49,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
49 | resolver: &Resolver, | 49 | resolver: &Resolver, |
50 | ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { | 50 | ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { |
51 | let krate = resolver.krate().unwrap(); | 51 | let krate = resolver.krate().unwrap(); |
52 | let impls = match db.lang_item(krate, "coerce_unsized".into()) { | 52 | let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) { |
53 | Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate, trait_), | 53 | Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate.into(), trait_), |
54 | _ => return FxHashMap::default(), | 54 | _ => return FxHashMap::default(), |
55 | }; | 55 | }; |
56 | 56 | ||
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 5e68a1678..20a7e9352 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -5,15 +5,15 @@ use std::sync::Arc; | |||
5 | 5 | ||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | builtin_type::Signedness, | 7 | builtin_type::Signedness, |
8 | generics::GenericParams, | ||
8 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
10 | resolver::resolver_for_expr, | ||
9 | }; | 11 | }; |
10 | use hir_expand::name; | 12 | use hir_expand::name; |
11 | 13 | ||
12 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | ||
13 | use crate::{ | 14 | use crate::{ |
14 | db::HirDatabase, | 15 | db::HirDatabase, |
15 | expr::{self, Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 16 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
16 | generics::{GenericParams, HasGenericParams}, | ||
17 | ty::{ | 17 | ty::{ |
18 | autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, | 18 | autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, |
19 | Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | 19 | Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, |
@@ -22,6 +22,8 @@ use crate::{ | |||
22 | Adt, Name, | 22 | Adt, Name, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | ||
26 | |||
25 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 27 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
26 | pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 28 | pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
27 | let ty = self.infer_expr_inner(tgt_expr, expected); | 29 | let ty = self.infer_expr_inner(tgt_expr, expected); |
@@ -186,7 +188,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
186 | } | 188 | } |
187 | Expr::Path(p) => { | 189 | Expr::Path(p) => { |
188 | // FIXME this could be more efficient... | 190 | // FIXME this could be more efficient... |
189 | let resolver = expr::resolver_for_expr(self.db, self.owner, tgt_expr); | 191 | let resolver = resolver_for_expr(self.db, self.owner.into(), tgt_expr); |
190 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 192 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
191 | } | 193 | } |
192 | Expr::Continue => Ty::simple(TypeCtor::Never), | 194 | Expr::Continue => Ty::simple(TypeCtor::Never), |
@@ -532,7 +534,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
532 | ( | 534 | ( |
533 | ty, | 535 | ty, |
534 | self.db.type_for_def(func.into(), Namespace::Values), | 536 | self.db.type_for_def(func.into(), Namespace::Values), |
535 | Some(func.generic_params(self.db)), | 537 | Some(self.db.generic_params(func.id.into())), |
536 | ) | 538 | ) |
537 | } | 539 | } |
538 | None => (receiver_ty, Ty::Unknown, None), | 540 | None => (receiver_ty, Ty::Unknown, None), |
@@ -643,7 +645,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
643 | if let Some(trait_) = f.parent_trait(self.db) { | 645 | if let Some(trait_) = f.parent_trait(self.db) { |
644 | // construct a TraitDef | 646 | // construct a TraitDef |
645 | let substs = a_ty.parameters.prefix( | 647 | let substs = a_ty.parameters.prefix( |
646 | trait_.generic_params(self.db).count_params_including_parent(), | 648 | self.db |
649 | .generic_params(trait_.id.into()) | ||
650 | .count_params_including_parent(), | ||
647 | ); | 651 | ); |
648 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | 652 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
649 | } | 653 | } |
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 31ca675aa..ee54d8217 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs | |||
@@ -1,16 +1,18 @@ | |||
1 | //! Path expression resolution. | 1 | //! Path expression resolution. |
2 | 2 | ||
3 | use hir_def::path::PathSegment; | 3 | use hir_def::{ |
4 | path::PathSegment, | ||
5 | resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, | ||
6 | }; | ||
4 | 7 | ||
5 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | ||
6 | use crate::{ | 8 | use crate::{ |
7 | db::HirDatabase, | 9 | db::HirDatabase, |
8 | generics::HasGenericParams, | ||
9 | resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, | ||
10 | ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, | 10 | ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, |
11 | AssocItem, Container, Name, Path, | 11 | AssocItem, Container, Function, Name, Path, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | ||
15 | |||
14 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 16 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
15 | pub(super) fn infer_path( | 17 | pub(super) fn infer_path( |
16 | &mut self, | 18 | &mut self, |
@@ -60,11 +62,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
60 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | 62 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); |
61 | return Some(ty); | 63 | return Some(ty); |
62 | } | 64 | } |
63 | ValueNs::Function(it) => it.into(), | 65 | ValueNs::FunctionId(it) => it.into(), |
64 | ValueNs::Const(it) => it.into(), | 66 | ValueNs::ConstId(it) => it.into(), |
65 | ValueNs::Static(it) => it.into(), | 67 | ValueNs::StaticId(it) => it.into(), |
66 | ValueNs::Struct(it) => it.into(), | 68 | ValueNs::StructId(it) => it.into(), |
67 | ValueNs::EnumVariant(it) => it.into(), | 69 | ValueNs::EnumVariantId(it) => it.into(), |
68 | }; | 70 | }; |
69 | 71 | ||
70 | let mut ty = self.db.type_for_def(typable, Namespace::Values); | 72 | let mut ty = self.db.type_for_def(typable, Namespace::Values); |
@@ -94,13 +96,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
94 | let is_before_last = remaining_segments.len() == 1; | 96 | let is_before_last = remaining_segments.len() == 1; |
95 | 97 | ||
96 | match (def, is_before_last) { | 98 | match (def, is_before_last) { |
97 | (TypeNs::Trait(trait_), true) => { | 99 | (TypeNs::TraitId(trait_), true) => { |
98 | let segment = | 100 | let segment = |
99 | remaining_segments.last().expect("there should be at least one segment here"); | 101 | remaining_segments.last().expect("there should be at least one segment here"); |
100 | let trait_ref = TraitRef::from_resolved_path( | 102 | let trait_ref = TraitRef::from_resolved_path( |
101 | self.db, | 103 | self.db, |
102 | &self.resolver, | 104 | &self.resolver, |
103 | trait_, | 105 | trait_.into(), |
104 | resolved_segment, | 106 | resolved_segment, |
105 | None, | 107 | None, |
106 | ); | 108 | ); |
@@ -160,8 +162,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
160 | AssocItem::TypeAlias(_) => None, | 162 | AssocItem::TypeAlias(_) => None, |
161 | })?; | 163 | })?; |
162 | let def = match item { | 164 | let def = match item { |
163 | AssocItem::Function(f) => ValueNs::Function(f), | 165 | AssocItem::Function(f) => ValueNs::FunctionId(f.id), |
164 | AssocItem::Const(c) => ValueNs::Const(c), | 166 | AssocItem::Const(c) => ValueNs::ConstId(c.id), |
165 | AssocItem::TypeAlias(_) => unreachable!(), | 167 | AssocItem::TypeAlias(_) => unreachable!(), |
166 | }; | 168 | }; |
167 | let substs = Substs::build_for_def(self.db, item) | 169 | let substs = Substs::build_for_def(self.db, item) |
@@ -193,8 +195,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
193 | method_resolution::LookupMode::Path, | 195 | method_resolution::LookupMode::Path, |
194 | move |_ty, item| { | 196 | move |_ty, item| { |
195 | let def = match item { | 197 | let def = match item { |
196 | AssocItem::Function(f) => ValueNs::Function(f), | 198 | AssocItem::Function(f) => ValueNs::FunctionId(f.id), |
197 | AssocItem::Const(c) => ValueNs::Const(c), | 199 | AssocItem::Const(c) => ValueNs::ConstId(c.id), |
198 | AssocItem::TypeAlias(_) => unreachable!(), | 200 | AssocItem::TypeAlias(_) => unreachable!(), |
199 | }; | 201 | }; |
200 | let substs = match item.container(self.db) { | 202 | let substs = match item.container(self.db) { |
@@ -224,9 +226,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
224 | } | 226 | } |
225 | 227 | ||
226 | fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> { | 228 | fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> { |
227 | if let ValueNs::Function(func) = def { | 229 | if let ValueNs::FunctionId(func) = def { |
230 | let func = Function::from(*func); | ||
228 | // We only do the infer if parent has generic params | 231 | // We only do the infer if parent has generic params |
229 | let gen = func.generic_params(self.db); | 232 | let gen = self.db.generic_params(func.id.into()); |
230 | if gen.count_parent_params() == 0 { | 233 | if gen.count_parent_params() == 0 { |
231 | return None; | 234 | return None; |
232 | } | 235 | } |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 397ee7d5f..75c552569 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -10,8 +10,11 @@ use std::sync::Arc; | |||
10 | 10 | ||
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, | 12 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, |
13 | generics::WherePredicate, | ||
13 | path::{GenericArg, PathSegment}, | 14 | path::{GenericArg, PathSegment}, |
15 | resolver::{HasResolver, Resolver, TypeNs}, | ||
14 | type_ref::{TypeBound, TypeRef}, | 16 | type_ref::{TypeBound, TypeRef}, |
17 | AdtId, GenericDefId, | ||
15 | }; | 18 | }; |
16 | 19 | ||
17 | use super::{ | 20 | use super::{ |
@@ -20,16 +23,13 @@ use super::{ | |||
20 | }; | 23 | }; |
21 | use crate::{ | 24 | use crate::{ |
22 | db::HirDatabase, | 25 | db::HirDatabase, |
23 | generics::HasGenericParams, | ||
24 | generics::{GenericDef, WherePredicate}, | ||
25 | resolve::{HasResolver, Resolver, TypeNs}, | ||
26 | ty::{ | 26 | ty::{ |
27 | primitive::{FloatTy, IntTy, Uncertain}, | 27 | primitive::{FloatTy, IntTy, Uncertain}, |
28 | Adt, | 28 | Adt, |
29 | }, | 29 | }, |
30 | util::make_mut_slice, | 30 | util::make_mut_slice, |
31 | Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, | 31 | Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, |
32 | TypeAlias, Union, VariantDef, | 32 | StructField, Trait, TypeAlias, Union, VariantDef, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | 35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of |
@@ -156,9 +156,14 @@ impl Ty { | |||
156 | remaining_segments: &[PathSegment], | 156 | remaining_segments: &[PathSegment], |
157 | ) -> Ty { | 157 | ) -> Ty { |
158 | let ty = match resolution { | 158 | let ty = match resolution { |
159 | TypeNs::Trait(trait_) => { | 159 | TypeNs::TraitId(trait_) => { |
160 | let trait_ref = | 160 | let trait_ref = TraitRef::from_resolved_path( |
161 | TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); | 161 | db, |
162 | resolver, | ||
163 | trait_.into(), | ||
164 | resolved_segment, | ||
165 | None, | ||
166 | ); | ||
162 | return if remaining_segments.len() == 1 { | 167 | return if remaining_segments.len() == 1 { |
163 | let segment = &remaining_segments[0]; | 168 | let segment = &remaining_segments[0]; |
164 | match trait_ref | 169 | match trait_ref |
@@ -189,18 +194,18 @@ impl Ty { | |||
189 | let name = resolved_segment.name.clone(); | 194 | let name = resolved_segment.name.clone(); |
190 | Ty::Param { idx, name } | 195 | Ty::Param { idx, name } |
191 | } | 196 | } |
192 | TypeNs::SelfType(impl_block) => impl_block.target_ty(db), | 197 | TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db), |
193 | TypeNs::AdtSelfType(adt) => adt.ty(db), | 198 | TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db), |
194 | 199 | ||
195 | TypeNs::Adt(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), | 200 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), |
196 | TypeNs::BuiltinType(it) => { | 201 | TypeNs::BuiltinType(it) => { |
197 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) | 202 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) |
198 | } | 203 | } |
199 | TypeNs::TypeAlias(it) => { | 204 | TypeNs::TypeAliasId(it) => { |
200 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) | 205 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) |
201 | } | 206 | } |
202 | // FIXME: report error | 207 | // FIXME: report error |
203 | TypeNs::EnumVariant(_) => return Ty::Unknown, | 208 | TypeNs::EnumVariantId(_) => return Ty::Unknown, |
204 | }; | 209 | }; |
205 | 210 | ||
206 | Ty::from_type_relative_path(db, resolver, ty, remaining_segments) | 211 | Ty::from_type_relative_path(db, resolver, ty, remaining_segments) |
@@ -247,7 +252,7 @@ impl Ty { | |||
247 | Some(def) => def, | 252 | Some(def) => def, |
248 | None => return Ty::Unknown, // this can't actually happen | 253 | None => return Ty::Unknown, // this can't actually happen |
249 | }; | 254 | }; |
250 | let predicates = db.generic_predicates_for_param(def, param_idx); | 255 | let predicates = db.generic_predicates_for_param(def.into(), param_idx); |
251 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { | 256 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { |
252 | GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), | 257 | GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), |
253 | _ => None, | 258 | _ => None, |
@@ -336,7 +341,7 @@ pub(super) fn substs_from_path_segment( | |||
336 | add_self_param: bool, | 341 | add_self_param: bool, |
337 | ) -> Substs { | 342 | ) -> Substs { |
338 | let mut substs = Vec::new(); | 343 | let mut substs = Vec::new(); |
339 | let def_generics = def_generic.map(|def| def.generic_params(db)); | 344 | let def_generics = def_generic.map(|def| db.generic_params(def.into())); |
340 | 345 | ||
341 | let (parent_param_count, param_count) = | 346 | let (parent_param_count, param_count) = |
342 | def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); | 347 | def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); |
@@ -391,11 +396,11 @@ impl TraitRef { | |||
391 | explicit_self_ty: Option<Ty>, | 396 | explicit_self_ty: Option<Ty>, |
392 | ) -> Option<Self> { | 397 | ) -> Option<Self> { |
393 | let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { | 398 | let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { |
394 | TypeNs::Trait(tr) => tr, | 399 | TypeNs::TraitId(tr) => tr, |
395 | _ => return None, | 400 | _ => return None, |
396 | }; | 401 | }; |
397 | let segment = path.segments.last().expect("path should have at least one segment"); | 402 | let segment = path.segments.last().expect("path should have at least one segment"); |
398 | Some(TraitRef::from_resolved_path(db, resolver, resolved, segment, explicit_self_ty)) | 403 | Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) |
399 | } | 404 | } |
400 | 405 | ||
401 | pub(super) fn from_resolved_path( | 406 | pub(super) fn from_resolved_path( |
@@ -437,7 +442,7 @@ impl TraitRef { | |||
437 | } | 442 | } |
438 | 443 | ||
439 | pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { | 444 | pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { |
440 | let substs = Substs::identity(&trait_.generic_params(db)); | 445 | let substs = Substs::identity(&db.generic_params(trait_.id.into())); |
441 | TraitRef { trait_, substs } | 446 | TraitRef { trait_, substs } |
442 | } | 447 | } |
443 | 448 | ||
@@ -548,8 +553,8 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi | |||
548 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | 553 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { |
549 | let parent_def = field.parent_def(db); | 554 | let parent_def = field.parent_def(db); |
550 | let resolver = match parent_def { | 555 | let resolver = match parent_def { |
551 | VariantDef::Struct(it) => it.resolver(db), | 556 | VariantDef::Struct(it) => it.id.resolver(db), |
552 | VariantDef::EnumVariant(it) => it.parent_enum(db).resolver(db), | 557 | VariantDef::EnumVariant(it) => it.parent.id.resolver(db), |
553 | }; | 558 | }; |
554 | let var_data = parent_def.variant_data(db); | 559 | let var_data = parent_def.variant_data(db); |
555 | let type_ref = &var_data.fields().unwrap()[field.id].type_ref; | 560 | let type_ref = &var_data.fields().unwrap()[field.id].type_ref; |
@@ -569,7 +574,7 @@ pub(crate) fn generic_predicates_for_param_query( | |||
569 | def: GenericDef, | 574 | def: GenericDef, |
570 | param_idx: u32, | 575 | param_idx: u32, |
571 | ) -> Arc<[GenericPredicate]> { | 576 | ) -> Arc<[GenericPredicate]> { |
572 | let resolver = def.resolver(db); | 577 | let resolver = GenericDefId::from(def).resolver(db); |
573 | resolver | 578 | resolver |
574 | .where_predicates_in_scope() | 579 | .where_predicates_in_scope() |
575 | // we have to filter out all other predicates *first*, before attempting to lower them | 580 | // we have to filter out all other predicates *first*, before attempting to lower them |
@@ -595,7 +600,7 @@ pub(crate) fn generic_predicates_query( | |||
595 | db: &impl HirDatabase, | 600 | db: &impl HirDatabase, |
596 | def: GenericDef, | 601 | def: GenericDef, |
597 | ) -> Arc<[GenericPredicate]> { | 602 | ) -> Arc<[GenericPredicate]> { |
598 | let resolver = def.resolver(db); | 603 | let resolver = GenericDefId::from(def).resolver(db); |
599 | resolver | 604 | resolver |
600 | .where_predicates_in_scope() | 605 | .where_predicates_in_scope() |
601 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | 606 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) |
@@ -604,8 +609,8 @@ pub(crate) fn generic_predicates_query( | |||
604 | 609 | ||
605 | /// Resolve the default type params from generics | 610 | /// Resolve the default type params from generics |
606 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { | 611 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { |
607 | let resolver = def.resolver(db); | 612 | let resolver = GenericDefId::from(def).resolver(db); |
608 | let generic_params = def.generic_params(db); | 613 | let generic_params = db.generic_params(def.into()); |
609 | 614 | ||
610 | let defaults = generic_params | 615 | let defaults = generic_params |
611 | .params_including_parent() | 616 | .params_including_parent() |
@@ -618,7 +623,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> | |||
618 | 623 | ||
619 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 624 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { |
620 | let data = def.data(db); | 625 | let data = def.data(db); |
621 | let resolver = def.resolver(db); | 626 | let resolver = def.id.resolver(db); |
622 | let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); | 627 | let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); |
623 | let ret = Ty::from_hir(db, &resolver, data.ret_type()); | 628 | let ret = Ty::from_hir(db, &resolver, data.ret_type()); |
624 | FnSig::from_params_and_return(params, ret) | 629 | FnSig::from_params_and_return(params, ret) |
@@ -627,7 +632,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | |||
627 | /// Build the declared type of a function. This should not need to look at the | 632 | /// Build the declared type of a function. This should not need to look at the |
628 | /// function body. | 633 | /// function body. |
629 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | 634 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { |
630 | let generics = def.generic_params(db); | 635 | let generics = db.generic_params(def.id.into()); |
631 | let substs = Substs::identity(&generics); | 636 | let substs = Substs::identity(&generics); |
632 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 637 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
633 | } | 638 | } |
@@ -635,7 +640,7 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | |||
635 | /// Build the declared type of a const. | 640 | /// Build the declared type of a const. |
636 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { | 641 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { |
637 | let data = def.data(db); | 642 | let data = def.data(db); |
638 | let resolver = def.resolver(db); | 643 | let resolver = def.id.resolver(db); |
639 | 644 | ||
640 | Ty::from_hir(db, &resolver, data.type_ref()) | 645 | Ty::from_hir(db, &resolver, data.type_ref()) |
641 | } | 646 | } |
@@ -643,7 +648,7 @@ fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { | |||
643 | /// Build the declared type of a static. | 648 | /// Build the declared type of a static. |
644 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { | 649 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { |
645 | let data = def.data(db); | 650 | let data = def.data(db); |
646 | let resolver = def.resolver(db); | 651 | let resolver = def.id.resolver(db); |
647 | 652 | ||
648 | Ty::from_hir(db, &resolver, data.type_ref()) | 653 | Ty::from_hir(db, &resolver, data.type_ref()) |
649 | } | 654 | } |
@@ -695,7 +700,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | |||
695 | Some(fields) => fields, | 700 | Some(fields) => fields, |
696 | None => panic!("fn_sig_for_struct_constructor called on unit struct"), | 701 | None => panic!("fn_sig_for_struct_constructor called on unit struct"), |
697 | }; | 702 | }; |
698 | let resolver = def.resolver(db); | 703 | let resolver = def.id.resolver(db); |
699 | let params = fields | 704 | let params = fields |
700 | .iter() | 705 | .iter() |
701 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 706 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
@@ -710,7 +715,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | |||
710 | if struct_data.variant_data.fields().is_none() { | 715 | if struct_data.variant_data.fields().is_none() { |
711 | return type_for_adt(db, def); // Unit struct | 716 | return type_for_adt(db, def); // Unit struct |
712 | } | 717 | } |
713 | let generics = def.generic_params(db); | 718 | let generics = db.generic_params(def.id.into()); |
714 | let substs = Substs::identity(&generics); | 719 | let substs = Substs::identity(&generics); |
715 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 720 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
716 | } | 721 | } |
@@ -721,12 +726,12 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) | |||
721 | Some(fields) => fields, | 726 | Some(fields) => fields, |
722 | None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), | 727 | None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), |
723 | }; | 728 | }; |
724 | let resolver = def.parent_enum(db).resolver(db); | 729 | let resolver = def.parent.id.resolver(db); |
725 | let params = fields | 730 | let params = fields |
726 | .iter() | 731 | .iter() |
727 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 732 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
728 | .collect::<Vec<_>>(); | 733 | .collect::<Vec<_>>(); |
729 | let generics = def.parent_enum(db).generic_params(db); | 734 | let generics = db.generic_params(def.parent_enum(db).id.into()); |
730 | let substs = Substs::identity(&generics); | 735 | let substs = Substs::identity(&generics); |
731 | let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); | 736 | let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); |
732 | FnSig::from_params_and_return(params, ret) | 737 | FnSig::from_params_and_return(params, ret) |
@@ -738,19 +743,21 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> | |||
738 | if var_data.fields().is_none() { | 743 | if var_data.fields().is_none() { |
739 | return type_for_adt(db, def.parent_enum(db)); // Unit variant | 744 | return type_for_adt(db, def.parent_enum(db)); // Unit variant |
740 | } | 745 | } |
741 | let generics = def.parent_enum(db).generic_params(db); | 746 | let generics = db.generic_params(def.parent_enum(db).id.into()); |
742 | let substs = Substs::identity(&generics); | 747 | let substs = Substs::identity(&generics); |
743 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 748 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
744 | } | 749 | } |
745 | 750 | ||
746 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt> + HasGenericParams) -> Ty { | 751 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { |
747 | let generics = adt.generic_params(db); | 752 | let adt = adt.into(); |
748 | Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics)) | 753 | let adt_id: AdtId = adt.into(); |
754 | let generics = db.generic_params(adt_id.into()); | ||
755 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) | ||
749 | } | 756 | } |
750 | 757 | ||
751 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { | 758 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { |
752 | let generics = t.generic_params(db); | 759 | let generics = db.generic_params(t.id.into()); |
753 | let resolver = t.resolver(db); | 760 | let resolver = t.id.resolver(db); |
754 | let type_ref = t.type_ref(db); | 761 | let type_ref = t.type_ref(db); |
755 | let substs = Substs::identity(&generics); | 762 | let substs = Substs::identity(&generics); |
756 | let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); | 763 | let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index f377fca48..64adb814d 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -5,11 +5,11 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::resolver::Resolver; | ||
8 | use rustc_hash::FxHashMap; | 9 | use rustc_hash::FxHashMap; |
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
11 | db::HirDatabase, | 12 | db::HirDatabase, |
12 | resolve::Resolver, | ||
13 | ty::primitive::{FloatBitness, Uncertain}, | 13 | ty::primitive::{FloatBitness, Uncertain}, |
14 | ty::{Ty, TypeCtor}, | 14 | ty::{Ty, TypeCtor}, |
15 | AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, | 15 | AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, |
@@ -172,9 +172,14 @@ pub(crate) fn iterate_method_candidates<T>( | |||
172 | // rustc does an autoderef and then autoref again). | 172 | // rustc does an autoderef and then autoref again). |
173 | 173 | ||
174 | for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { | 174 | for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { |
175 | if let Some(result) = | 175 | if let Some(result) = iterate_inherent_methods( |
176 | iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback) | 176 | &derefed_ty, |
177 | { | 177 | db, |
178 | name, | ||
179 | mode, | ||
180 | krate.into(), | ||
181 | &mut callback, | ||
182 | ) { | ||
178 | return Some(result); | 183 | return Some(result); |
179 | } | 184 | } |
180 | if let Some(result) = iterate_trait_method_candidates( | 185 | if let Some(result) = iterate_trait_method_candidates( |
@@ -192,7 +197,7 @@ pub(crate) fn iterate_method_candidates<T>( | |||
192 | LookupMode::Path => { | 197 | LookupMode::Path => { |
193 | // No autoderef for path lookups | 198 | // No autoderef for path lookups |
194 | if let Some(result) = | 199 | if let Some(result) = |
195 | iterate_inherent_methods(&ty, db, name, mode, krate, &mut callback) | 200 | iterate_inherent_methods(&ty, db, name, mode, krate.into(), &mut callback) |
196 | { | 201 | { |
197 | return Some(result); | 202 | return Some(result); |
198 | } | 203 | } |
@@ -224,7 +229,9 @@ fn iterate_trait_method_candidates<T>( | |||
224 | .trait_predicates_for_self_ty(&ty.value) | 229 | .trait_predicates_for_self_ty(&ty.value) |
225 | .map(|tr| tr.trait_) | 230 | .map(|tr| tr.trait_) |
226 | .flat_map(|t| t.all_super_traits(db)); | 231 | .flat_map(|t| t.all_super_traits(db)); |
227 | let traits = inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db)); | 232 | let traits = inherent_trait |
233 | .chain(traits_from_env) | ||
234 | .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); | ||
228 | 'traits: for t in traits { | 235 | 'traits: for t in traits { |
229 | let data = t.trait_data(db); | 236 | let data = t.trait_data(db); |
230 | 237 | ||
@@ -238,7 +245,7 @@ fn iterate_trait_method_candidates<T>( | |||
238 | } | 245 | } |
239 | if !known_implemented { | 246 | if !known_implemented { |
240 | let goal = generic_implements_goal(db, env.clone(), t, ty.clone()); | 247 | let goal = generic_implements_goal(db, env.clone(), t, ty.clone()); |
241 | if db.trait_solve(krate, goal).is_none() { | 248 | if db.trait_solve(krate.into(), goal).is_none() { |
242 | continue 'traits; | 249 | continue 'traits; |
243 | } | 250 | } |
244 | } | 251 | } |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 9bf93981a..88785f305 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -16,10 +16,9 @@ use ra_db::salsa::{InternId, InternKey}; | |||
16 | use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; | 16 | use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; |
17 | use crate::{ | 17 | use crate::{ |
18 | db::HirDatabase, | 18 | db::HirDatabase, |
19 | generics::{GenericDef, HasGenericParams}, | ||
20 | ty::display::HirDisplay, | 19 | ty::display::HirDisplay, |
21 | ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, | 20 | ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, |
22 | Crate, HasBody, ImplBlock, Trait, TypeAlias, | 21 | Crate, GenericDef, HasBody, ImplBlock, Trait, TypeAlias, |
23 | }; | 22 | }; |
24 | 23 | ||
25 | /// This represents a trait whose name we could not resolve. | 24 | /// This represents a trait whose name we could not resolve. |
@@ -509,7 +508,7 @@ pub(crate) fn associated_ty_data_query( | |||
509 | Some(crate::Container::Trait(t)) => t, | 508 | Some(crate::Container::Trait(t)) => t, |
510 | _ => panic!("associated type not in trait"), | 509 | _ => panic!("associated type not in trait"), |
511 | }; | 510 | }; |
512 | let generic_params = type_alias.generic_params(db); | 511 | let generic_params = db.generic_params(type_alias.id.into()); |
513 | let bound_data = chalk_rust_ir::AssociatedTyDatumBound { | 512 | let bound_data = chalk_rust_ir::AssociatedTyDatumBound { |
514 | // FIXME add bounds and where clauses | 513 | // FIXME add bounds and where clauses |
515 | bounds: vec![], | 514 | bounds: vec![], |
@@ -550,7 +549,7 @@ pub(crate) fn trait_datum_query( | |||
550 | } | 549 | } |
551 | let trait_: Trait = from_chalk(db, trait_id); | 550 | let trait_: Trait = from_chalk(db, trait_id); |
552 | debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); | 551 | debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); |
553 | let generic_params = trait_.generic_params(db); | 552 | let generic_params = db.generic_params(trait_.id.into()); |
554 | let bound_vars = Substs::bound_vars(&generic_params); | 553 | let bound_vars = Substs::bound_vars(&generic_params); |
555 | let flags = chalk_rust_ir::TraitFlags { | 554 | let flags = chalk_rust_ir::TraitFlags { |
556 | auto: trait_.is_auto(db), | 555 | auto: trait_.is_auto(db), |
@@ -594,7 +593,7 @@ pub(crate) fn struct_datum_query( | |||
594 | let where_clauses = type_ctor | 593 | let where_clauses = type_ctor |
595 | .as_generic_def() | 594 | .as_generic_def() |
596 | .map(|generic_def| { | 595 | .map(|generic_def| { |
597 | let generic_params = generic_def.generic_params(db); | 596 | let generic_params = db.generic_params(generic_def.into()); |
598 | let bound_vars = Substs::bound_vars(&generic_params); | 597 | let bound_vars = Substs::bound_vars(&generic_params); |
599 | convert_where_clauses(db, generic_def, &bound_vars) | 598 | convert_where_clauses(db, generic_def, &bound_vars) |
600 | }) | 599 | }) |
@@ -634,7 +633,7 @@ fn impl_block_datum( | |||
634 | impl_id: ImplId, | 633 | impl_id: ImplId, |
635 | impl_block: ImplBlock, | 634 | impl_block: ImplBlock, |
636 | ) -> Option<Arc<ImplDatum<ChalkIr>>> { | 635 | ) -> Option<Arc<ImplDatum<ChalkIr>>> { |
637 | let generic_params = impl_block.generic_params(db); | 636 | let generic_params = db.generic_params(impl_block.id.into()); |
638 | let bound_vars = Substs::bound_vars(&generic_params); | 637 | let bound_vars = Substs::bound_vars(&generic_params); |
639 | let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); | 638 | let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); |
640 | let trait_ = trait_ref.trait_; | 639 | let trait_ = trait_ref.trait_; |
@@ -786,7 +785,7 @@ fn type_alias_associated_ty_value( | |||
786 | let assoc_ty = trait_ | 785 | let assoc_ty = trait_ |
787 | .associated_type_by_name(db, &type_alias.name(db)) | 786 | .associated_type_by_name(db, &type_alias.name(db)) |
788 | .expect("assoc ty value should not exist"); // validated when building the impl data as well | 787 | .expect("assoc ty value should not exist"); // validated when building the impl data as well |
789 | let generic_params = impl_block.generic_params(db); | 788 | let generic_params = db.generic_params(impl_block.id.into()); |
790 | let bound_vars = Substs::bound_vars(&generic_params); | 789 | let bound_vars = Substs::bound_vars(&generic_params); |
791 | let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); | 790 | let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); |
792 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; | 791 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index a5bb60e85..d8e911aa5 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -12,6 +12,7 @@ use ra_syntax::{ | |||
12 | }, | 12 | }, |
13 | AstNode, AstPtr, | 13 | AstNode, AstPtr, |
14 | }; | 14 | }; |
15 | use test_utils::tested_by; | ||
15 | 16 | ||
16 | use crate::{ | 17 | use crate::{ |
17 | body::{Body, BodySourceMap, Expander, PatPtr}, | 18 | body::{Body, BodySourceMap, Expander, PatPtr}, |
@@ -190,6 +191,7 @@ where | |||
190 | None => self.collect_expr_opt(condition.expr()), | 191 | None => self.collect_expr_opt(condition.expr()), |
191 | // if let -- desugar to match | 192 | // if let -- desugar to match |
192 | Some(pat) => { | 193 | Some(pat) => { |
194 | tested_by!(infer_resolve_while_let); | ||
193 | let pat = self.collect_pat(pat); | 195 | let pat = self.collect_pat(pat); |
194 | let match_expr = self.collect_expr_opt(condition.expr()); | 196 | let match_expr = self.collect_expr_opt(condition.expr()); |
195 | let placeholder_pat = self.missing_pat(); | 197 | let placeholder_pat = self.missing_pat(); |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index aeb71ff22..58740b679 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -174,7 +174,7 @@ mod tests { | |||
174 | use hir_expand::{name::AsName, Source}; | 174 | use hir_expand::{name::AsName, Source}; |
175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; | 175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; |
176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
177 | use test_utils::{assert_eq_text, extract_offset}; | 177 | use test_utils::{assert_eq_text, covers, extract_offset}; |
178 | 178 | ||
179 | use crate::{db::DefDatabase2, test_db::TestDB, FunctionId, ModuleDefId}; | 179 | use crate::{db::DefDatabase2, test_db::TestDB, FunctionId, ModuleDefId}; |
180 | 180 | ||
@@ -382,4 +382,20 @@ mod tests { | |||
382 | 53, | 382 | 53, |
383 | ); | 383 | ); |
384 | } | 384 | } |
385 | |||
386 | #[test] | ||
387 | fn while_let_desugaring() { | ||
388 | covers!(infer_resolve_while_let); | ||
389 | do_check_local_name( | ||
390 | r#" | ||
391 | fn test() { | ||
392 | let foo: Option<f32> = None; | ||
393 | while let Option::Some(spam) = foo { | ||
394 | spam<|> | ||
395 | } | ||
396 | } | ||
397 | "#, | ||
398 | 75, | ||
399 | ); | ||
400 | } | ||
385 | } | 401 | } |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 0af41de87..d579f5c7e 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -19,6 +19,7 @@ pub mod expr; | |||
19 | pub mod body; | 19 | pub mod body; |
20 | pub mod generics; | 20 | pub mod generics; |
21 | pub mod traits; | 21 | pub mod traits; |
22 | pub mod resolver; | ||
22 | 23 | ||
23 | #[cfg(test)] | 24 | #[cfg(test)] |
24 | mod test_db; | 25 | mod test_db; |
diff --git a/crates/ra_hir_def/src/marks.rs b/crates/ra_hir_def/src/marks.rs index 0b99eac71..65239ca0a 100644 --- a/crates/ra_hir_def/src/marks.rs +++ b/crates/ra_hir_def/src/marks.rs | |||
@@ -11,4 +11,5 @@ test_utils::marks!( | |||
11 | prelude_is_macro_use | 11 | prelude_is_macro_use |
12 | macro_dollar_crate_self | 12 | macro_dollar_crate_self |
13 | macro_dollar_crate_other | 13 | macro_dollar_crate_other |
14 | infer_resolve_while_let | ||
14 | ); | 15 | ); |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir_def/src/resolver.rs index eca8e0596..7b5c3ec06 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir_def/src/resolver.rs | |||
@@ -1,26 +1,28 @@ | |||
1 | //! Name resolution. | 1 | //! Name resolution façade. |
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use hir_def::{ | 4 | use hir_expand::{ |
5 | builtin_type::BuiltinType, | 5 | name::{self, Name}, |
6 | nameres::CrateDefMap, | 6 | MacroDefId, |
7 | path::{Path, PathKind}, | ||
8 | AdtId, CrateModuleId, ModuleDefId, | ||
9 | }; | 7 | }; |
10 | use hir_expand::name::{self, Name}; | 8 | use ra_db::CrateId; |
11 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
12 | 10 | ||
13 | use crate::{ | 11 | use crate::{ |
14 | code_model::Crate, | 12 | body::scope::{ExprScopes, ScopeId}, |
15 | db::{DefDatabase, HirDatabase}, | 13 | builtin_type::BuiltinType, |
16 | expr::{ExprScopes, PatId, ScopeId}, | 14 | db::DefDatabase2, |
17 | generics::{GenericParams, HasGenericParams}, | 15 | expr::{ExprId, PatId}, |
18 | Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, | 16 | generics::GenericParams, |
19 | MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, | 17 | nameres::{per_ns::PerNs, CrateDefMap}, |
18 | path::{Path, PathKind}, | ||
19 | AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, | ||
20 | FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, | ||
21 | TypeAliasId, | ||
20 | }; | 22 | }; |
21 | 23 | ||
22 | #[derive(Debug, Clone, Default)] | 24 | #[derive(Debug, Clone, Default)] |
23 | pub(crate) struct Resolver { | 25 | pub struct Resolver { |
24 | scopes: Vec<Scope>, | 26 | scopes: Vec<Scope>, |
25 | } | 27 | } |
26 | 28 | ||
@@ -33,7 +35,7 @@ pub(crate) struct ModuleItemMap { | |||
33 | 35 | ||
34 | #[derive(Debug, Clone)] | 36 | #[derive(Debug, Clone)] |
35 | pub(crate) struct ExprScope { | 37 | pub(crate) struct ExprScope { |
36 | owner: DefWithBody, | 38 | owner: DefWithBodyId, |
37 | expr_scopes: Arc<ExprScopes>, | 39 | expr_scopes: Arc<ExprScopes>, |
38 | scope_id: ScopeId, | 40 | scope_id: ScopeId, |
39 | } | 41 | } |
@@ -43,80 +45,76 @@ pub(crate) enum Scope { | |||
43 | /// All the items and imported names of a module | 45 | /// All the items and imported names of a module |
44 | ModuleScope(ModuleItemMap), | 46 | ModuleScope(ModuleItemMap), |
45 | /// Brings the generic parameters of an item into scope | 47 | /// Brings the generic parameters of an item into scope |
46 | GenericParams { def: GenericDef, params: Arc<GenericParams> }, | 48 | GenericParams { def: GenericDefId, params: Arc<GenericParams> }, |
47 | /// Brings `Self` in `impl` block into scope | 49 | /// Brings `Self` in `impl` block into scope |
48 | ImplBlockScope(ImplBlock), | 50 | ImplBlockScope(ImplId), |
49 | /// Brings `Self` in enum, struct and union definitions into scope | 51 | /// Brings `Self` in enum, struct and union definitions into scope |
50 | AdtScope(Adt), | 52 | AdtScope(AdtId), |
51 | /// Local bindings | 53 | /// Local bindings |
52 | ExprScope(ExprScope), | 54 | ExprScope(ExprScope), |
53 | } | 55 | } |
54 | 56 | ||
55 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 57 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
56 | pub(crate) enum TypeNs { | 58 | pub enum TypeNs { |
57 | SelfType(ImplBlock), | 59 | SelfType(ImplId), |
58 | GenericParam(u32), | 60 | GenericParam(u32), |
59 | Adt(Adt), | 61 | AdtId(AdtId), |
60 | AdtSelfType(Adt), | 62 | AdtSelfType(AdtId), |
61 | EnumVariant(EnumVariant), | 63 | EnumVariantId(EnumVariantId), |
62 | TypeAlias(TypeAlias), | 64 | TypeAliasId(TypeAliasId), |
63 | BuiltinType(BuiltinType), | 65 | BuiltinType(BuiltinType), |
64 | Trait(Trait), | 66 | TraitId(TraitId), |
65 | // Module belong to type ns, but the resolver is used when all module paths | 67 | // Module belong to type ns, but the resolver is used when all module paths |
66 | // are fully resolved. | 68 | // are fully resolved. |
67 | // Module(Module) | 69 | // ModuleId(ModuleId) |
68 | } | 70 | } |
69 | 71 | ||
70 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 72 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
71 | pub(crate) enum ResolveValueResult { | 73 | pub enum ResolveValueResult { |
72 | ValueNs(ValueNs), | 74 | ValueNs(ValueNs), |
73 | Partial(TypeNs, usize), | 75 | Partial(TypeNs, usize), |
74 | } | 76 | } |
75 | 77 | ||
76 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 78 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
77 | pub(crate) enum ValueNs { | 79 | pub enum ValueNs { |
78 | LocalBinding(PatId), | 80 | LocalBinding(PatId), |
79 | Function(Function), | 81 | FunctionId(FunctionId), |
80 | Const(Const), | 82 | ConstId(ConstId), |
81 | Static(Static), | 83 | StaticId(StaticId), |
82 | Struct(Struct), | 84 | StructId(StructId), |
83 | EnumVariant(EnumVariant), | 85 | EnumVariantId(EnumVariantId), |
84 | } | 86 | } |
85 | 87 | ||
86 | impl Resolver { | 88 | impl Resolver { |
87 | /// Resolve known trait from std, like `std::futures::Future` | 89 | /// Resolve known trait from std, like `std::futures::Future` |
88 | pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> { | 90 | pub fn resolve_known_trait(&self, db: &impl DefDatabase2, path: &Path) -> Option<TraitId> { |
89 | let res = self.resolve_module_path(db, path).take_types()?; | 91 | let res = self.resolve_module_path(db, path).take_types()?; |
90 | match res { | 92 | match res { |
91 | ModuleDefId::TraitId(it) => Some(it.into()), | 93 | ModuleDefId::TraitId(it) => Some(it), |
92 | _ => None, | 94 | _ => None, |
93 | } | 95 | } |
94 | } | 96 | } |
95 | 97 | ||
96 | /// Resolve known struct from std, like `std::boxed::Box` | 98 | /// Resolve known struct from std, like `std::boxed::Box` |
97 | pub(crate) fn resolve_known_struct( | 99 | pub fn resolve_known_struct(&self, db: &impl DefDatabase2, path: &Path) -> Option<StructId> { |
98 | &self, | ||
99 | db: &impl HirDatabase, | ||
100 | path: &Path, | ||
101 | ) -> Option<Struct> { | ||
102 | let res = self.resolve_module_path(db, path).take_types()?; | 100 | let res = self.resolve_module_path(db, path).take_types()?; |
103 | match res { | 101 | match res { |
104 | ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it.into()), | 102 | ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), |
105 | _ => None, | 103 | _ => None, |
106 | } | 104 | } |
107 | } | 105 | } |
108 | 106 | ||
109 | /// Resolve known enum from std, like `std::result::Result` | 107 | /// Resolve known enum from std, like `std::result::Result` |
110 | pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> { | 108 | pub fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option<EnumId> { |
111 | let res = self.resolve_module_path(db, path).take_types()?; | 109 | let res = self.resolve_module_path(db, path).take_types()?; |
112 | match res { | 110 | match res { |
113 | ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it.into()), | 111 | ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), |
114 | _ => None, | 112 | _ => None, |
115 | } | 113 | } |
116 | } | 114 | } |
117 | 115 | ||
118 | /// pub only for source-binder | 116 | /// pub only for source-binder |
119 | pub(crate) fn resolve_module_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs { | 117 | pub fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs { |
120 | let (item_map, module) = match self.module() { | 118 | let (item_map, module) = match self.module() { |
121 | Some(it) => it, | 119 | Some(it) => it, |
122 | None => return PerNs::none(), | 120 | None => return PerNs::none(), |
@@ -128,9 +126,9 @@ impl Resolver { | |||
128 | module_res | 126 | module_res |
129 | } | 127 | } |
130 | 128 | ||
131 | pub(crate) fn resolve_path_in_type_ns( | 129 | pub fn resolve_path_in_type_ns( |
132 | &self, | 130 | &self, |
133 | db: &impl HirDatabase, | 131 | db: &impl DefDatabase2, |
134 | path: &Path, | 132 | path: &Path, |
135 | ) -> Option<(TypeNs, Option<usize>)> { | 133 | ) -> Option<(TypeNs, Option<usize>)> { |
136 | if path.is_type_relative() { | 134 | if path.is_type_relative() { |
@@ -164,13 +162,13 @@ impl Resolver { | |||
164 | Scope::ModuleScope(m) => { | 162 | Scope::ModuleScope(m) => { |
165 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | 163 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); |
166 | let res = match module_def.take_types()? { | 164 | let res = match module_def.take_types()? { |
167 | ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), | 165 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), |
168 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariant(it.into()), | 166 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), |
169 | 167 | ||
170 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), | 168 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), |
171 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | 169 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), |
172 | 170 | ||
173 | ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), | 171 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), |
174 | 172 | ||
175 | ModuleDefId::FunctionId(_) | 173 | ModuleDefId::FunctionId(_) |
176 | | ModuleDefId::ConstId(_) | 174 | | ModuleDefId::ConstId(_) |
@@ -184,9 +182,9 @@ impl Resolver { | |||
184 | None | 182 | None |
185 | } | 183 | } |
186 | 184 | ||
187 | pub(crate) fn resolve_path_in_type_ns_fully( | 185 | pub fn resolve_path_in_type_ns_fully( |
188 | &self, | 186 | &self, |
189 | db: &impl HirDatabase, | 187 | db: &impl DefDatabase2, |
190 | path: &Path, | 188 | path: &Path, |
191 | ) -> Option<TypeNs> { | 189 | ) -> Option<TypeNs> { |
192 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; | 190 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; |
@@ -196,9 +194,9 @@ impl Resolver { | |||
196 | Some(res) | 194 | Some(res) |
197 | } | 195 | } |
198 | 196 | ||
199 | pub(crate) fn resolve_path_in_value_ns<'p>( | 197 | pub fn resolve_path_in_value_ns<'p>( |
200 | &self, | 198 | &self, |
201 | db: &impl HirDatabase, | 199 | db: &impl DefDatabase2, |
202 | path: &'p Path, | 200 | path: &'p Path, |
203 | ) -> Option<ResolveValueResult> { | 201 | ) -> Option<ResolveValueResult> { |
204 | if path.is_type_relative() { | 202 | if path.is_type_relative() { |
@@ -259,13 +257,11 @@ impl Resolver { | |||
259 | return match idx { | 257 | return match idx { |
260 | None => { | 258 | None => { |
261 | let value = match module_def.take_values()? { | 259 | let value = match module_def.take_values()? { |
262 | ModuleDefId::FunctionId(it) => ValueNs::Function(it.into()), | 260 | ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), |
263 | ModuleDefId::AdtId(AdtId::StructId(it)) => { | 261 | ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), |
264 | ValueNs::Struct(it.into()) | 262 | ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it), |
265 | } | 263 | ModuleDefId::ConstId(it) => ValueNs::ConstId(it), |
266 | ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariant(it.into()), | 264 | ModuleDefId::StaticId(it) => ValueNs::StaticId(it), |
267 | ModuleDefId::ConstId(it) => ValueNs::Const(it.into()), | ||
268 | ModuleDefId::StaticId(it) => ValueNs::Static(it.into()), | ||
269 | 265 | ||
270 | ModuleDefId::AdtId(AdtId::EnumId(_)) | 266 | ModuleDefId::AdtId(AdtId::EnumId(_)) |
271 | | ModuleDefId::AdtId(AdtId::UnionId(_)) | 267 | | ModuleDefId::AdtId(AdtId::UnionId(_)) |
@@ -278,9 +274,9 @@ impl Resolver { | |||
278 | } | 274 | } |
279 | Some(idx) => { | 275 | Some(idx) => { |
280 | let ty = match module_def.take_types()? { | 276 | let ty = match module_def.take_types()? { |
281 | ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), | 277 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), |
282 | ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), | 278 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), |
283 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), | 279 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), |
284 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | 280 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), |
285 | 281 | ||
286 | ModuleDefId::ModuleId(_) | 282 | ModuleDefId::ModuleId(_) |
@@ -298,9 +294,9 @@ impl Resolver { | |||
298 | None | 294 | None |
299 | } | 295 | } |
300 | 296 | ||
301 | pub(crate) fn resolve_path_in_value_ns_fully( | 297 | pub fn resolve_path_in_value_ns_fully( |
302 | &self, | 298 | &self, |
303 | db: &impl HirDatabase, | 299 | db: &impl DefDatabase2, |
304 | path: &Path, | 300 | path: &Path, |
305 | ) -> Option<ValueNs> { | 301 | ) -> Option<ValueNs> { |
306 | match self.resolve_path_in_value_ns(db, path)? { | 302 | match self.resolve_path_in_value_ns(db, path)? { |
@@ -309,35 +305,26 @@ impl Resolver { | |||
309 | } | 305 | } |
310 | } | 306 | } |
311 | 307 | ||
312 | pub(crate) fn resolve_path_as_macro( | 308 | pub fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option<MacroDefId> { |
313 | &self, | ||
314 | db: &impl DefDatabase, | ||
315 | path: &Path, | ||
316 | ) -> Option<MacroDef> { | ||
317 | let (item_map, module) = self.module()?; | 309 | let (item_map, module) = self.module()?; |
318 | item_map.resolve_path(db, module, path).0.get_macros().map(MacroDef::from) | 310 | item_map.resolve_path(db, module, path).0.get_macros() |
319 | } | 311 | } |
320 | 312 | ||
321 | pub(crate) fn process_all_names( | 313 | pub fn process_all_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { |
322 | &self, | ||
323 | db: &impl HirDatabase, | ||
324 | f: &mut dyn FnMut(Name, ScopeDef), | ||
325 | ) { | ||
326 | for scope in self.scopes.iter().rev() { | 314 | for scope in self.scopes.iter().rev() { |
327 | scope.process_names(db, f); | 315 | scope.process_names(db, f); |
328 | } | 316 | } |
329 | } | 317 | } |
330 | 318 | ||
331 | pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> { | 319 | pub fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet<TraitId> { |
332 | let mut traits = FxHashSet::default(); | 320 | let mut traits = FxHashSet::default(); |
333 | for scope in &self.scopes { | 321 | for scope in &self.scopes { |
334 | if let Scope::ModuleScope(m) = scope { | 322 | if let Scope::ModuleScope(m) = scope { |
335 | if let Some(prelude) = m.crate_def_map.prelude() { | 323 | if let Some(prelude) = m.crate_def_map.prelude() { |
336 | let prelude_def_map = db.crate_def_map(prelude.krate); | 324 | let prelude_def_map = db.crate_def_map(prelude.krate); |
337 | traits | 325 | traits.extend(prelude_def_map[prelude.module_id].scope.traits()); |
338 | .extend(prelude_def_map[prelude.module_id].scope.traits().map(Trait::from)); | ||
339 | } | 326 | } |
340 | traits.extend(m.crate_def_map[m.module_id].scope.traits().map(Trait::from)); | 327 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); |
341 | } | 328 | } |
342 | } | 329 | } |
343 | traits | 330 | traits |
@@ -351,11 +338,11 @@ impl Resolver { | |||
351 | }) | 338 | }) |
352 | } | 339 | } |
353 | 340 | ||
354 | pub(crate) fn krate(&self) -> Option<Crate> { | 341 | pub fn krate(&self) -> Option<CrateId> { |
355 | self.module().map(|t| Crate { crate_id: t.0.krate() }) | 342 | self.module().map(|t| t.0.krate()) |
356 | } | 343 | } |
357 | 344 | ||
358 | pub(crate) fn where_predicates_in_scope<'a>( | 345 | pub fn where_predicates_in_scope<'a>( |
359 | &'a self, | 346 | &'a self, |
360 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { | 347 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { |
361 | self.scopes | 348 | self.scopes |
@@ -367,80 +354,31 @@ impl Resolver { | |||
367 | .flat_map(|params| params.where_predicates.iter()) | 354 | .flat_map(|params| params.where_predicates.iter()) |
368 | } | 355 | } |
369 | 356 | ||
370 | pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { | 357 | pub fn generic_def(&self) -> Option<GenericDefId> { |
371 | self.scopes.iter().find_map(|scope| match scope { | 358 | self.scopes.iter().find_map(|scope| match scope { |
372 | Scope::GenericParams { def, .. } => Some(*def), | 359 | Scope::GenericParams { def, .. } => Some(*def), |
373 | _ => None, | 360 | _ => None, |
374 | }) | 361 | }) |
375 | } | 362 | } |
376 | } | ||
377 | |||
378 | impl Resolver { | ||
379 | pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver { | ||
380 | self.scopes.push(scope); | ||
381 | self | ||
382 | } | ||
383 | |||
384 | pub(crate) fn push_generic_params_scope( | ||
385 | self, | ||
386 | db: &impl DefDatabase, | ||
387 | def: GenericDef, | ||
388 | ) -> Resolver { | ||
389 | let params = def.generic_params(db); | ||
390 | if params.params.is_empty() { | ||
391 | self | ||
392 | } else { | ||
393 | self.push_scope(Scope::GenericParams { def, params }) | ||
394 | } | ||
395 | } | ||
396 | |||
397 | pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { | ||
398 | self.push_scope(Scope::ImplBlockScope(impl_block)) | ||
399 | } | ||
400 | 363 | ||
401 | pub(crate) fn push_module_scope( | 364 | pub fn body_owner(&self) -> Option<DefWithBodyId> { |
402 | self, | 365 | self.scopes.iter().find_map(|scope| match scope { |
403 | crate_def_map: Arc<CrateDefMap>, | 366 | Scope::ExprScope(it) => Some(it.owner), |
404 | module_id: CrateModuleId, | 367 | _ => None, |
405 | ) -> Resolver { | 368 | }) |
406 | self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) | ||
407 | } | ||
408 | |||
409 | pub(crate) fn push_expr_scope( | ||
410 | self, | ||
411 | owner: DefWithBody, | ||
412 | expr_scopes: Arc<ExprScopes>, | ||
413 | scope_id: ScopeId, | ||
414 | ) -> Resolver { | ||
415 | self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) | ||
416 | } | 369 | } |
417 | } | 370 | } |
418 | 371 | ||
419 | /// For IDE only | ||
420 | pub enum ScopeDef { | 372 | pub enum ScopeDef { |
421 | ModuleDef(ModuleDef), | 373 | PerNs(PerNs), |
422 | MacroDef(MacroDef), | 374 | ImplSelfType(ImplId), |
375 | AdtSelfType(AdtId), | ||
423 | GenericParam(u32), | 376 | GenericParam(u32), |
424 | ImplSelfType(ImplBlock), | 377 | Local(PatId), |
425 | AdtSelfType(Adt), | ||
426 | Local(Local), | ||
427 | Unknown, | ||
428 | } | ||
429 | |||
430 | impl From<PerNs> for ScopeDef { | ||
431 | fn from(def: PerNs) -> Self { | ||
432 | def.take_types() | ||
433 | .or_else(|| def.take_values()) | ||
434 | .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) | ||
435 | .or_else(|| { | ||
436 | def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) | ||
437 | }) | ||
438 | .unwrap_or(ScopeDef::Unknown) | ||
439 | } | ||
440 | } | 378 | } |
441 | 379 | ||
442 | impl Scope { | 380 | impl Scope { |
443 | fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { | 381 | fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { |
444 | match self { | 382 | match self { |
445 | Scope::ModuleScope(m) => { | 383 | Scope::ModuleScope(m) => { |
446 | // FIXME: should we provide `self` here? | 384 | // FIXME: should we provide `self` here? |
@@ -451,18 +389,18 @@ impl Scope { | |||
451 | // }), | 389 | // }), |
452 | // ); | 390 | // ); |
453 | m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { | 391 | m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { |
454 | f(name.clone(), res.def.into()); | 392 | f(name.clone(), ScopeDef::PerNs(res.def)); |
455 | }); | 393 | }); |
456 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { | 394 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { |
457 | f(name.clone(), ScopeDef::MacroDef(macro_.into())); | 395 | f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); |
458 | }); | 396 | }); |
459 | m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { | 397 | m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { |
460 | f(name.clone(), ScopeDef::ModuleDef(def.into())); | 398 | f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into()))); |
461 | }); | 399 | }); |
462 | if let Some(prelude) = m.crate_def_map.prelude() { | 400 | if let Some(prelude) = m.crate_def_map.prelude() { |
463 | let prelude_def_map = db.crate_def_map(prelude.krate); | 401 | let prelude_def_map = db.crate_def_map(prelude.krate); |
464 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { | 402 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { |
465 | f(name.clone(), res.def.into()); | 403 | f(name.clone(), ScopeDef::PerNs(res.def)); |
466 | }); | 404 | }); |
467 | } | 405 | } |
468 | } | 406 | } |
@@ -472,114 +410,175 @@ impl Scope { | |||
472 | } | 410 | } |
473 | } | 411 | } |
474 | Scope::ImplBlockScope(i) => { | 412 | Scope::ImplBlockScope(i) => { |
475 | f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i)); | 413 | f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into())); |
476 | } | 414 | } |
477 | Scope::AdtScope(i) => { | 415 | Scope::AdtScope(i) => { |
478 | f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); | 416 | f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into())); |
479 | } | 417 | } |
480 | Scope::ExprScope(scope) => { | 418 | Scope::ExprScope(scope) => { |
481 | scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { | 419 | scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { |
482 | let local = Local { parent: scope.owner, pat_id: e.pat() }; | 420 | f(e.name().clone(), ScopeDef::Local(e.pat())); |
483 | f(e.name().clone(), ScopeDef::Local(local)); | ||
484 | }); | 421 | }); |
485 | } | 422 | } |
486 | } | 423 | } |
487 | } | 424 | } |
488 | } | 425 | } |
489 | 426 | ||
490 | pub(crate) trait HasResolver { | 427 | // needs arbitrary_self_types to be a method... or maybe move to the def? |
428 | pub fn resolver_for_expr( | ||
429 | db: &impl DefDatabase2, | ||
430 | owner: DefWithBodyId, | ||
431 | expr_id: ExprId, | ||
432 | ) -> Resolver { | ||
433 | let scopes = db.expr_scopes(owner); | ||
434 | resolver_for_scope(db, owner, scopes.scope_for(expr_id)) | ||
435 | } | ||
436 | |||
437 | pub fn resolver_for_scope( | ||
438 | db: &impl DefDatabase2, | ||
439 | owner: DefWithBodyId, | ||
440 | scope_id: Option<ScopeId>, | ||
441 | ) -> Resolver { | ||
442 | let mut r = owner.resolver(db); | ||
443 | let scopes = db.expr_scopes(owner); | ||
444 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); | ||
445 | for scope in scope_chain.into_iter().rev() { | ||
446 | r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); | ||
447 | } | ||
448 | r | ||
449 | } | ||
450 | |||
451 | impl Resolver { | ||
452 | fn push_scope(mut self, scope: Scope) -> Resolver { | ||
453 | self.scopes.push(scope); | ||
454 | self | ||
455 | } | ||
456 | |||
457 | fn push_generic_params_scope(self, db: &impl DefDatabase2, def: GenericDefId) -> Resolver { | ||
458 | let params = db.generic_params(def); | ||
459 | if params.params.is_empty() { | ||
460 | self | ||
461 | } else { | ||
462 | self.push_scope(Scope::GenericParams { def, params }) | ||
463 | } | ||
464 | } | ||
465 | |||
466 | fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver { | ||
467 | self.push_scope(Scope::ImplBlockScope(impl_block)) | ||
468 | } | ||
469 | |||
470 | fn push_module_scope( | ||
471 | self, | ||
472 | crate_def_map: Arc<CrateDefMap>, | ||
473 | module_id: CrateModuleId, | ||
474 | ) -> Resolver { | ||
475 | self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) | ||
476 | } | ||
477 | |||
478 | fn push_expr_scope( | ||
479 | self, | ||
480 | owner: DefWithBodyId, | ||
481 | expr_scopes: Arc<ExprScopes>, | ||
482 | scope_id: ScopeId, | ||
483 | ) -> Resolver { | ||
484 | self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) | ||
485 | } | ||
486 | } | ||
487 | |||
488 | pub trait HasResolver { | ||
491 | /// Builds a resolver for type references inside this def. | 489 | /// Builds a resolver for type references inside this def. |
492 | fn resolver(self, db: &impl DefDatabase) -> Resolver; | 490 | fn resolver(self, db: &impl DefDatabase2) -> Resolver; |
493 | } | 491 | } |
494 | 492 | ||
495 | impl HasResolver for Module { | 493 | impl HasResolver for ModuleId { |
496 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 494 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
497 | let def_map = db.crate_def_map(self.id.krate); | 495 | let def_map = db.crate_def_map(self.krate); |
498 | Resolver::default().push_module_scope(def_map, self.id.module_id) | 496 | Resolver::default().push_module_scope(def_map, self.module_id) |
499 | } | 497 | } |
500 | } | 498 | } |
501 | 499 | ||
502 | impl HasResolver for Trait { | 500 | impl HasResolver for TraitId { |
503 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 501 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
504 | self.module(db).resolver(db).push_generic_params_scope(db, self.into()) | 502 | self.module(db).resolver(db).push_generic_params_scope(db, self.into()) |
505 | } | 503 | } |
506 | } | 504 | } |
507 | 505 | ||
508 | impl<T: Into<Adt>> HasResolver for T { | 506 | impl<T: Into<AdtId>> HasResolver for T { |
509 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 507 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
510 | let def = self.into(); | 508 | let def = self.into(); |
511 | def.module(db) | 509 | let module = match def { |
510 | AdtId::StructId(it) => it.0.module(db), | ||
511 | AdtId::UnionId(it) => it.0.module(db), | ||
512 | AdtId::EnumId(it) => it.module(db), | ||
513 | }; | ||
514 | |||
515 | module | ||
512 | .resolver(db) | 516 | .resolver(db) |
513 | .push_generic_params_scope(db, def.into()) | 517 | .push_generic_params_scope(db, def.into()) |
514 | .push_scope(Scope::AdtScope(def)) | 518 | .push_scope(Scope::AdtScope(def)) |
515 | } | 519 | } |
516 | } | 520 | } |
517 | 521 | ||
518 | impl HasResolver for Function { | 522 | impl HasResolver for FunctionId { |
519 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 523 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
520 | self.container(db) | 524 | self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) |
521 | .map(|c| c.resolver(db)) | ||
522 | .unwrap_or_else(|| self.module(db).resolver(db)) | ||
523 | .push_generic_params_scope(db, self.into()) | ||
524 | } | 525 | } |
525 | } | 526 | } |
526 | 527 | ||
527 | impl HasResolver for DefWithBody { | 528 | impl HasResolver for DefWithBodyId { |
528 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 529 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
529 | match self { | 530 | match self { |
530 | DefWithBody::Const(c) => c.resolver(db), | 531 | DefWithBodyId::ConstId(c) => c.resolver(db), |
531 | DefWithBody::Function(f) => f.resolver(db), | 532 | DefWithBodyId::FunctionId(f) => f.resolver(db), |
532 | DefWithBody::Static(s) => s.resolver(db), | 533 | DefWithBodyId::StaticId(s) => s.resolver(db), |
533 | } | 534 | } |
534 | } | 535 | } |
535 | } | 536 | } |
536 | 537 | ||
537 | impl HasResolver for Const { | 538 | impl HasResolver for ConstId { |
538 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 539 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
539 | self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db)) | 540 | self.lookup(db).container.resolver(db) |
540 | } | 541 | } |
541 | } | 542 | } |
542 | 543 | ||
543 | impl HasResolver for Static { | 544 | impl HasResolver for StaticId { |
544 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 545 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
545 | self.module(db).resolver(db) | 546 | self.module(db).resolver(db) |
546 | } | 547 | } |
547 | } | 548 | } |
548 | 549 | ||
549 | impl HasResolver for TypeAlias { | 550 | impl HasResolver for TypeAliasId { |
550 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 551 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
551 | self.container(db) | 552 | self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) |
552 | .map(|ib| ib.resolver(db)) | ||
553 | .unwrap_or_else(|| self.module(db).resolver(db)) | ||
554 | .push_generic_params_scope(db, self.into()) | ||
555 | } | 553 | } |
556 | } | 554 | } |
557 | 555 | ||
558 | impl HasResolver for Container { | 556 | impl HasResolver for ContainerId { |
559 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 557 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
560 | match self { | 558 | match self { |
561 | Container::Trait(trait_) => trait_.resolver(db), | 559 | ContainerId::TraitId(it) => it.resolver(db), |
562 | Container::ImplBlock(impl_block) => impl_block.resolver(db), | 560 | ContainerId::ImplId(it) => it.resolver(db), |
561 | ContainerId::ModuleId(it) => it.resolver(db), | ||
563 | } | 562 | } |
564 | } | 563 | } |
565 | } | 564 | } |
566 | 565 | ||
567 | impl HasResolver for GenericDef { | 566 | impl HasResolver for GenericDefId { |
568 | fn resolver(self, db: &impl DefDatabase) -> crate::Resolver { | 567 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
569 | match self { | 568 | match self { |
570 | GenericDef::Function(inner) => inner.resolver(db), | 569 | GenericDefId::FunctionId(inner) => inner.resolver(db), |
571 | GenericDef::Adt(adt) => adt.resolver(db), | 570 | GenericDefId::AdtId(adt) => adt.resolver(db), |
572 | GenericDef::Trait(inner) => inner.resolver(db), | 571 | GenericDefId::TraitId(inner) => inner.resolver(db), |
573 | GenericDef::TypeAlias(inner) => inner.resolver(db), | 572 | GenericDefId::TypeAliasId(inner) => inner.resolver(db), |
574 | GenericDef::ImplBlock(inner) => inner.resolver(db), | 573 | GenericDefId::ImplId(inner) => inner.resolver(db), |
575 | GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), | 574 | GenericDefId::EnumVariantId(inner) => inner.parent.resolver(db), |
576 | GenericDef::Const(inner) => inner.resolver(db), | 575 | GenericDefId::ConstId(inner) => inner.resolver(db), |
577 | } | 576 | } |
578 | } | 577 | } |
579 | } | 578 | } |
580 | 579 | ||
581 | impl HasResolver for ImplBlock { | 580 | impl HasResolver for ImplId { |
582 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 581 | fn resolver(self, db: &impl DefDatabase2) -> Resolver { |
583 | self.module(db) | 582 | self.module(db) |
584 | .resolver(db) | 583 | .resolver(db) |
585 | .push_generic_params_scope(db, self.into()) | 584 | .push_generic_params_scope(db, self.into()) |
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs index 877d73d66..6c2d5b2a9 100644 --- a/crates/ra_hir_def/src/traits.rs +++ b/crates/ra_hir_def/src/traits.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::ast::{self, NameOwner}; | |||
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, | 13 | db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, |
14 | TypeAliasLoc, | 14 | TypeAliasId, TypeAliasLoc, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | #[derive(Debug, Clone, PartialEq, Eq)] | 17 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -56,4 +56,11 @@ impl TraitData { | |||
56 | }; | 56 | }; |
57 | Arc::new(TraitData { name, items, auto }) | 57 | Arc::new(TraitData { name, items, auto }) |
58 | } | 58 | } |
59 | |||
60 | pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ { | ||
61 | self.items.iter().filter_map(|item| match item { | ||
62 | AssocItemId::TypeAliasId(t) => Some(*t), | ||
63 | _ => None, | ||
64 | }) | ||
65 | } | ||
59 | } | 66 | } |
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 3c11c8a22..e1d93a8ef 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs | |||
@@ -151,6 +151,7 @@ pub(crate) fn parse_macro( | |||
151 | let fragment_kind = match macro_file.macro_file_kind { | 151 | let fragment_kind = match macro_file.macro_file_kind { |
152 | MacroFileKind::Items => FragmentKind::Items, | 152 | MacroFileKind::Items => FragmentKind::Items, |
153 | MacroFileKind::Expr => FragmentKind::Expr, | 153 | MacroFileKind::Expr => FragmentKind::Expr, |
154 | MacroFileKind::Statements => FragmentKind::Statements, | ||
154 | }; | 155 | }; |
155 | let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; | 156 | let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; |
156 | Some((parse, Arc::new(rev_token_map))) | 157 | Some((parse, Arc::new(rev_token_map))) |
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 1389f64ce..126d12fbb 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -109,6 +109,7 @@ pub struct MacroFile { | |||
109 | pub enum MacroFileKind { | 109 | pub enum MacroFileKind { |
110 | Items, | 110 | Items, |
111 | Expr, | 111 | Expr, |
112 | Statements, | ||
112 | } | 113 | } |
113 | 114 | ||
114 | /// `MacroCallId` identifies a particular macro invocation, like | 115 | /// `MacroCallId` identifies a particular macro invocation, like |
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 7f39262dc..7dbf33a16 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs | |||
@@ -84,24 +84,19 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { | |||
84 | }; | 84 | }; |
85 | 85 | ||
86 | res += &match token.kind() { | 86 | res += &match token.kind() { |
87 | k @ _ | 87 | k @ _ if is_text(k) && is_next(|it| !it.is_punct(), true) => { |
88 | if (k.is_keyword() || k.is_literal() || k == IDENT) | ||
89 | && is_next(|it| !it.is_punct(), true) => | ||
90 | { | ||
91 | token.text().to_string() + " " | 88 | token.text().to_string() + " " |
92 | } | 89 | } |
93 | L_CURLY if is_next(|it| it != R_CURLY, true) => { | 90 | L_CURLY if is_next(|it| it != R_CURLY, true) => { |
94 | indent += 1; | 91 | indent += 1; |
95 | format!(" {{\n{}", " ".repeat(indent)) | 92 | let leading_space = if is_last(|it| is_text(it), false) { " " } else { "" }; |
93 | format!("{}{{\n{}", leading_space, " ".repeat(indent)) | ||
96 | } | 94 | } |
97 | R_CURLY if is_last(|it| it != L_CURLY, true) => { | 95 | R_CURLY if is_last(|it| it != L_CURLY, true) => { |
98 | indent = indent.checked_sub(1).unwrap_or(0); | 96 | indent = indent.checked_sub(1).unwrap_or(0); |
99 | format!("\n}}{}", " ".repeat(indent)) | 97 | format!("\n{}}}", " ".repeat(indent)) |
100 | } | ||
101 | R_CURLY => { | ||
102 | indent = indent.checked_sub(1).unwrap_or(0); | ||
103 | format!("}}\n{}", " ".repeat(indent)) | ||
104 | } | 98 | } |
99 | R_CURLY => format!("}}\n{}", " ".repeat(indent)), | ||
105 | T![;] => format!(";\n{}", " ".repeat(indent)), | 100 | T![;] => format!(";\n{}", " ".repeat(indent)), |
106 | T![->] => " -> ".to_string(), | 101 | T![->] => " -> ".to_string(), |
107 | T![=] => " = ".to_string(), | 102 | T![=] => " = ".to_string(), |
@@ -112,7 +107,11 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { | |||
112 | last = Some(token.kind()); | 107 | last = Some(token.kind()); |
113 | } | 108 | } |
114 | 109 | ||
115 | res | 110 | return res; |
111 | |||
112 | fn is_text(k: SyntaxKind) -> bool { | ||
113 | k.is_keyword() || k.is_literal() || k == IDENT | ||
114 | } | ||
116 | } | 115 | } |
117 | 116 | ||
118 | #[cfg(test)] | 117 | #[cfg(test)] |
@@ -175,4 +174,47 @@ fn some_thing() -> u32 { | |||
175 | } | 174 | } |
176 | "###); | 175 | "###); |
177 | } | 176 | } |
177 | |||
178 | #[test] | ||
179 | fn macro_expand_match_ast() { | ||
180 | let res = check_expand_macro( | ||
181 | r#" | ||
182 | //- /lib.rs | ||
183 | macro_rules! match_ast { | ||
184 | (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; | ||
185 | |||
186 | (match ($node:expr) { | ||
187 | $( ast::$ast:ident($it:ident) => $res:block, )* | ||
188 | _ => $catch_all:expr $(,)? | ||
189 | }) => {{ | ||
190 | $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* | ||
191 | { $catch_all } | ||
192 | }}; | ||
193 | } | ||
194 | |||
195 | fn main() { | ||
196 | mat<|>ch_ast! { | ||
197 | match container { | ||
198 | ast::TraitDef(it) => {}, | ||
199 | ast::ImplBlock(it) => {}, | ||
200 | _ => { continue }, | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | "#, | ||
205 | ); | ||
206 | |||
207 | assert_eq!(res.name, "match_ast"); | ||
208 | assert_snapshot!(res.expansion, @r###" | ||
209 | { | ||
210 | if let Some(it) = ast::TraitDef::cast(container.clone()){} | ||
211 | else if let Some(it) = ast::ImplBlock::cast(container.clone()){} | ||
212 | else { | ||
213 | { | ||
214 | continue | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | "###); | ||
219 | } | ||
178 | } | 220 | } |
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index d1c49c0b3..1de399fee 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -5,6 +5,7 @@ use ra_syntax::{ | |||
5 | ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode, | 5 | ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode, |
6 | SyntaxTreeBuilder, TextRange, TextUnit, T, | 6 | SyntaxTreeBuilder, TextRange, TextUnit, T, |
7 | }; | 7 | }; |
8 | use std::iter::successors; | ||
8 | use tt::buffer::{Cursor, TokenBuffer}; | 9 | use tt::buffer::{Cursor, TokenBuffer}; |
9 | 10 | ||
10 | use crate::subtree_source::SubtreeTokenSource; | 11 | use crate::subtree_source::SubtreeTokenSource; |
@@ -160,6 +161,31 @@ impl Convertor { | |||
160 | 161 | ||
161 | let first_child = tt.first_child_or_token()?; | 162 | let first_child = tt.first_child_or_token()?; |
162 | let last_child = tt.last_child_or_token()?; | 163 | let last_child = tt.last_child_or_token()?; |
164 | |||
165 | // ignore trivial first_child and last_child | ||
166 | let first_child = successors(Some(first_child), |it| { | ||
167 | if it.kind().is_trivia() { | ||
168 | it.next_sibling_or_token() | ||
169 | } else { | ||
170 | None | ||
171 | } | ||
172 | }) | ||
173 | .last() | ||
174 | .unwrap(); | ||
175 | if first_child.kind().is_trivia() { | ||
176 | return Some(tt::Subtree { token_trees: vec![], delimiter: tt::Delimiter::None }); | ||
177 | } | ||
178 | |||
179 | let last_child = successors(Some(last_child), |it| { | ||
180 | if it.kind().is_trivia() { | ||
181 | it.prev_sibling_or_token() | ||
182 | } else { | ||
183 | None | ||
184 | } | ||
185 | }) | ||
186 | .last() | ||
187 | .unwrap(); | ||
188 | |||
163 | let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) { | 189 | let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) { |
164 | (T!['('], T![')']) => (tt::Delimiter::Parenthesis, true), | 190 | (T!['('], T![')']) => (tt::Delimiter::Parenthesis, true), |
165 | (T!['{'], T!['}']) => (tt::Delimiter::Brace, true), | 191 | (T!['{'], T!['}']) => (tt::Delimiter::Brace, true), |
@@ -363,6 +389,7 @@ mod tests { | |||
363 | use super::*; | 389 | use super::*; |
364 | use crate::tests::{create_rules, expand}; | 390 | use crate::tests::{create_rules, expand}; |
365 | use ra_parser::TokenSource; | 391 | use ra_parser::TokenSource; |
392 | use ra_syntax::algo::{insert_children, InsertPosition}; | ||
366 | 393 | ||
367 | #[test] | 394 | #[test] |
368 | fn convert_tt_token_source() { | 395 | fn convert_tt_token_source() { |
@@ -423,4 +450,45 @@ mod tests { | |||
423 | let expansion = expand(&rules, "stmts!();"); | 450 | let expansion = expand(&rules, "stmts!();"); |
424 | assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err()); | 451 | assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err()); |
425 | } | 452 | } |
453 | |||
454 | #[test] | ||
455 | fn test_token_tree_last_child_is_white_space() { | ||
456 | let source_file = ast::SourceFile::parse("f!({} );").ok().unwrap(); | ||
457 | let macro_call = source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | ||
458 | let token_tree = macro_call.token_tree().unwrap(); | ||
459 | |||
460 | // Token Tree now is : | ||
461 | // TokenTree | ||
462 | // - T!['('] | ||
463 | // - TokenTree | ||
464 | // - T!['{'] | ||
465 | // - T!['}'] | ||
466 | // - WHITE_SPACE | ||
467 | // - T![')'] | ||
468 | |||
469 | let rbrace = | ||
470 | token_tree.syntax().descendants_with_tokens().find(|it| it.kind() == T!['}']).unwrap(); | ||
471 | let space = token_tree | ||
472 | .syntax() | ||
473 | .descendants_with_tokens() | ||
474 | .find(|it| it.kind() == SyntaxKind::WHITESPACE) | ||
475 | .unwrap(); | ||
476 | |||
477 | // reorder th white space, such that the white is inside the inner token-tree. | ||
478 | let token_tree = insert_children( | ||
479 | &rbrace.parent().unwrap(), | ||
480 | InsertPosition::Last, | ||
481 | &mut std::iter::once(space), | ||
482 | ); | ||
483 | |||
484 | // Token Tree now is : | ||
485 | // TokenTree | ||
486 | // - T!['{'] | ||
487 | // - T!['}'] | ||
488 | // - WHITE_SPACE | ||
489 | let token_tree = ast::TokenTree::cast(token_tree).unwrap(); | ||
490 | let tt = ast_to_token_tree(&token_tree).unwrap().0; | ||
491 | |||
492 | assert_eq!(tt.delimiter, tt::Delimiter::Brace); | ||
493 | } | ||
426 | } | 494 | } |