aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock74
-rw-r--r--crates/ra_assists/src/assists/early_return.rs10
-rw-r--r--crates/ra_hir/Cargo.toml1
-rw-r--r--crates/ra_hir/src/code_model.rs35
-rw-r--r--crates/ra_hir/src/db.rs4
-rw-r--r--crates/ra_hir/src/from_source.rs93
-rw-r--r--crates/ra_hir/src/has_source.rs16
-rw-r--r--crates/ra_hir/src/lib.rs4
-rw-r--r--crates/ra_hir/src/source_binder.rs11
-rw-r--r--crates/ra_hir_def/Cargo.toml1
-rw-r--r--crates/ra_hir_def/src/adt.rs2
-rw-r--r--crates/ra_hir_def/src/body.rs76
-rw-r--r--crates/ra_hir_def/src/body/lower.rs60
-rw-r--r--crates/ra_hir_def/src/child_by_source.rs101
-rw-r--r--crates/ra_hir_def/src/data.rs147
-rw-r--r--crates/ra_hir_def/src/db.rs11
-rw-r--r--crates/ra_hir_def/src/expr.rs1
-rw-r--r--crates/ra_hir_def/src/item_scope.rs155
-rw-r--r--crates/ra_hir_def/src/lang_item.rs2
-rw-r--r--crates/ra_hir_def/src/lib.rs289
-rw-r--r--crates/ra_hir_def/src/nameres.rs119
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs106
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs78
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs19
-rw-r--r--crates/ra_hir_def/src/nameres/tests/incremental.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/tests/macros.rs4
-rw-r--r--crates/ra_hir_def/src/path.rs3
-rw-r--r--crates/ra_hir_def/src/resolver.rs22
-rw-r--r--crates/ra_hir_def/src/src.rs82
-rw-r--r--crates/ra_hir_def/src/trace.rs8
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs142
-rw-r--r--crates/ra_hir_expand/src/db.rs10
-rw-r--r--crates/ra_hir_expand/src/name.rs3
-rw-r--r--crates/ra_hir_expand/src/quote.rs2
-rw-r--r--crates/ra_hir_ty/src/autoderef.rs4
-rw-r--r--crates/ra_hir_ty/src/infer.rs29
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs4
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs35
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs8
-rw-r--r--crates/ra_hir_ty/src/lib.rs10
-rw-r--r--crates/ra_hir_ty/src/lower.rs4
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs14
-rw-r--r--crates/ra_hir_ty/src/test_db.rs2
-rw-r--r--crates/ra_hir_ty/src/tests.rs2
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs86
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs42
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs55
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs42
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs12
-rw-r--r--crates/ra_hir_ty/src/utils.rs8
-rw-r--r--crates/ra_ide/src/change.rs2
-rw-r--r--crates/ra_ide/src/completion/complete_path.rs18
-rw-r--r--crates/ra_ide/src/completion/complete_postfix.rs2
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs21
-rw-r--r--crates/ra_ide/src/display.rs2
-rw-r--r--crates/ra_ide/src/expand_macro.rs13
-rw-r--r--crates/ra_ide/src/extend_selection.rs2
-rw-r--r--crates/ra_ide/src/goto_definition.rs110
-rw-r--r--crates/ra_ide/src/hover.rs80
-rw-r--r--crates/ra_ide/src/inlay_hints.rs11
-rw-r--r--crates/ra_ide/src/marks.rs9
-rw-r--r--crates/ra_ide/src/references/classify.rs9
-rw-r--r--crates/ra_ide/src/snapshots/highlighting.html4
-rw-r--r--crates/ra_ide/src/snapshots/rainbow_highlighting.html1
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs65
-rw-r--r--crates/ra_lsp_server/Cargo.toml2
-rw-r--r--crates/ra_lsp_server/src/caps.rs13
-rw-r--r--crates/ra_lsp_server/src/conv.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs5
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs5
-rw-r--r--crates/ra_lsp_server/src/main_loop/pending_requests.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop/subscriptions.rs2
-rw-r--r--crates/ra_lsp_server/src/markdown.rs2
-rw-r--r--crates/ra_lsp_server/src/req.rs29
-rw-r--r--crates/ra_lsp_server/src/world.rs25
-rw-r--r--crates/ra_mbe/src/lib.rs4
-rw-r--r--crates/ra_parser/src/grammar/items.rs30
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs2
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs8
-rw-r--r--crates/ra_syntax/src/ast/edit.rs4
-rw-r--r--crates/ra_syntax/src/ast/generated.rs3
-rw-r--r--crates/ra_syntax/src/ast/make.rs3
-rw-r--r--crates/ra_syntax/src/grammar.ron6
-rw-r--r--crates/ra_syntax/test_data/parser/err/0028_macro_2.0.txt328
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt9
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt43
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt20
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.rs (renamed from crates/ra_syntax/test_data/parser/err/0028_macro_2.0.rs)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt174
-rw-r--r--editors/code/package-lock.json50
-rw-r--r--editors/code/package.json16
-rw-r--r--editors/code/src/commands/cargo_watch.ts9
-rw-r--r--xtask/src/main.rs2
95 files changed, 1722 insertions, 1480 deletions
diff --git a/Cargo.lock b/Cargo.lock
index af874945c..55afcda7b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -110,8 +110,8 @@ version = "0.9.1"
110source = "registry+https://github.com/rust-lang/crates.io-index" 110source = "registry+https://github.com/rust-lang/crates.io-index"
111dependencies = [ 111dependencies = [
112 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 112 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
113 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 113 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
114 "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 114 "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
115 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 115 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
116] 116]
117 117
@@ -433,7 +433,7 @@ dependencies = [
433 433
434[[package]] 434[[package]]
435name = "hermit-abi" 435name = "hermit-abi"
436version = "0.1.3" 436version = "0.1.5"
437source = "registry+https://github.com/rust-lang/crates.io-index" 437source = "registry+https://github.com/rust-lang/crates.io-index"
438dependencies = [ 438dependencies = [
439 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 439 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -491,7 +491,7 @@ dependencies = [
491 "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 491 "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
492 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 492 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
493 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 493 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
494 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 494 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
495 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 495 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
496 "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", 496 "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
497 "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 497 "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -614,17 +614,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
614dependencies = [ 614dependencies = [
615 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 615 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
616 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 616 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
617 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 617 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
618 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 618 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
619] 619]
620 620
621[[package]] 621[[package]]
622name = "lsp-types" 622name = "lsp-types"
623version = "0.63.1" 623version = "0.65.0"
624source = "registry+https://github.com/rust-lang/crates.io-index" 624source = "registry+https://github.com/rust-lang/crates.io-index"
625dependencies = [ 625dependencies = [
626 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 626 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
627 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 627 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
628 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 628 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
629 "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 629 "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
630 "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 630 "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -729,7 +729,7 @@ name = "num_cpus"
729version = "1.11.1" 729version = "1.11.1"
730source = "registry+https://github.com/rust-lang/crates.io-index" 730source = "registry+https://github.com/rust-lang/crates.io-index"
731dependencies = [ 731dependencies = [
732 "hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 732 "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
733 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 733 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
734] 734]
735 735
@@ -761,7 +761,7 @@ dependencies = [
761 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 761 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
762 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 762 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
763 "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 763 "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
764 "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 764 "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
765 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 765 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
766] 766]
767 767
@@ -948,6 +948,7 @@ dependencies = [
948 "ra_hir_def 0.1.0", 948 "ra_hir_def 0.1.0",
949 "ra_hir_expand 0.1.0", 949 "ra_hir_expand 0.1.0",
950 "ra_hir_ty 0.1.0", 950 "ra_hir_ty 0.1.0",
951 "ra_prof 0.1.0",
951 "ra_syntax 0.1.0", 952 "ra_syntax 0.1.0",
952 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 953 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
953] 954]
@@ -957,6 +958,7 @@ name = "ra_hir_def"
957version = "0.1.0" 958version = "0.1.0"
958dependencies = [ 959dependencies = [
959 "anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 960 "anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
961 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
960 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 962 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
961 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 963 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
962 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 964 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1048,7 +1050,7 @@ dependencies = [
1048 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1050 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1049 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1051 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1050 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1052 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1051 "lsp-types 0.63.1 (registry+https://github.com/rust-lang/crates.io-index)", 1053 "lsp-types 0.65.0 (registry+https://github.com/rust-lang/crates.io-index)",
1052 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 1054 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1053 "ra_ide 0.1.0", 1055 "ra_ide 0.1.0",
1054 "ra_prof 0.1.0", 1056 "ra_prof 0.1.0",
@@ -1059,7 +1061,7 @@ dependencies = [
1059 "ra_vfs_glob 0.1.0", 1061 "ra_vfs_glob 0.1.0",
1060 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1062 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1061 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1063 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1062 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1064 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1063 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 1065 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
1064 "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1066 "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1065 "test_utils 0.1.0", 1067 "test_utils 0.1.0",
@@ -1075,7 +1077,7 @@ dependencies = [
1075 "ra_syntax 0.1.0", 1077 "ra_syntax 0.1.0",
1076 "ra_tt 0.1.0", 1078 "ra_tt 0.1.0",
1077 "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)",
1078 "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1080 "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1079 "test_utils 0.1.0", 1081 "test_utils 0.1.0",
1080] 1082]
1081 1083
@@ -1107,7 +1109,7 @@ dependencies = [
1107 "ra_cfg 0.1.0", 1109 "ra_cfg 0.1.0",
1108 "ra_db 0.1.0", 1110 "ra_db 0.1.0",
1109 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1111 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1110 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1112 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1111 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 1113 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
1112] 1114]
1113 1115
@@ -1120,10 +1122,10 @@ dependencies = [
1120 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1122 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1121 "ra_parser 0.1.0", 1123 "ra_parser 0.1.0",
1122 "ra_text_edit 0.1.0", 1124 "ra_text_edit 0.1.0",
1123 "rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1125 "rowan 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
1124 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1126 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1125 "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1127 "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1126 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1128 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1127 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 1129 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
1128 "test_utils 0.1.0", 1130 "test_utils 0.1.0",
1129 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1131 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1381,12 +1383,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1381dependencies = [ 1383dependencies = [
1382 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1384 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1383 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1385 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1384 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1386 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1385] 1387]
1386 1388
1387[[package]] 1389[[package]]
1388name = "rowan" 1390name = "rowan"
1389version = "0.8.1" 1391version = "0.8.2"
1390source = "registry+https://github.com/rust-lang/crates.io-index" 1392source = "registry+https://github.com/rust-lang/crates.io-index"
1391dependencies = [ 1393dependencies = [
1392 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1394 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1441,7 +1443,7 @@ dependencies = [
1441 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1443 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1442 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1444 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1443 "salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", 1445 "salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
1444 "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1446 "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1445] 1447]
1446 1448
1447[[package]] 1449[[package]]
@@ -1474,7 +1476,7 @@ version = "0.9.0"
1474source = "registry+https://github.com/rust-lang/crates.io-index" 1476source = "registry+https://github.com/rust-lang/crates.io-index"
1475dependencies = [ 1477dependencies = [
1476 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1478 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
1477 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1479 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1478] 1480]
1479 1481
1480[[package]] 1482[[package]]
@@ -1484,15 +1486,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1484 1486
1485[[package]] 1487[[package]]
1486name = "serde" 1488name = "serde"
1487version = "1.0.103" 1489version = "1.0.104"
1488source = "registry+https://github.com/rust-lang/crates.io-index" 1490source = "registry+https://github.com/rust-lang/crates.io-index"
1489dependencies = [ 1491dependencies = [
1490 "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1492 "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1491] 1493]
1492 1494
1493[[package]] 1495[[package]]
1494name = "serde_derive" 1496name = "serde_derive"
1495version = "1.0.103" 1497version = "1.0.104"
1496source = "registry+https://github.com/rust-lang/crates.io-index" 1498source = "registry+https://github.com/rust-lang/crates.io-index"
1497dependencies = [ 1499dependencies = [
1498 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1500 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1507,7 +1509,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1507dependencies = [ 1509dependencies = [
1508 "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1510 "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1509 "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1511 "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1510 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1512 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1511] 1513]
1512 1514
1513[[package]] 1515[[package]]
@@ -1527,7 +1529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1527dependencies = [ 1529dependencies = [
1528 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1530 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1529 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1531 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
1530 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1532 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1531 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1533 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
1532] 1534]
1533 1535
@@ -1538,7 +1540,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1538 1540
1539[[package]] 1541[[package]]
1540name = "smallvec" 1542name = "smallvec"
1541version = "1.0.0" 1543version = "1.1.0"
1542source = "registry+https://github.com/rust-lang/crates.io-index" 1544source = "registry+https://github.com/rust-lang/crates.io-index"
1543 1545
1544[[package]] 1546[[package]]
@@ -1546,7 +1548,7 @@ name = "smol_str"
1546version = "0.1.15" 1548version = "0.1.15"
1547source = "registry+https://github.com/rust-lang/crates.io-index" 1549source = "registry+https://github.com/rust-lang/crates.io-index"
1548dependencies = [ 1550dependencies = [
1549 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1551 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1550] 1552]
1551 1553
1552[[package]] 1554[[package]]
@@ -1641,7 +1643,7 @@ name = "unicode-normalization"
1641version = "0.1.11" 1643version = "0.1.11"
1642source = "registry+https://github.com/rust-lang/crates.io-index" 1644source = "registry+https://github.com/rust-lang/crates.io-index"
1643dependencies = [ 1645dependencies = [
1644 "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1646 "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1645] 1647]
1646 1648
1647[[package]] 1649[[package]]
@@ -1662,7 +1664,7 @@ dependencies = [
1662 "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1664 "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1663 "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1665 "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
1664 "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1666 "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1665 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1667 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1666] 1668]
1667 1669
1668[[package]] 1670[[package]]
@@ -1671,7 +1673,7 @@ version = "0.8.1"
1671source = "registry+https://github.com/rust-lang/crates.io-index" 1673source = "registry+https://github.com/rust-lang/crates.io-index"
1672dependencies = [ 1674dependencies = [
1673 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1675 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1674 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1676 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1675] 1677]
1676 1678
1677[[package]] 1679[[package]]
@@ -1749,7 +1751,7 @@ dependencies = [
1749 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1751 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
1750 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1752 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1751 "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1753 "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1752 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1754 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1753 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1755 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
1754] 1756]
1755 1757
@@ -1816,7 +1818,7 @@ dependencies = [
1816"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" 1818"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
1817"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" 1819"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2"
1818"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 1820"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
1819"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" 1821"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7"
1820"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 1822"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
1821"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1823"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
1822"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" 1824"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
@@ -1840,7 +1842,7 @@ dependencies = [
1840"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" 1842"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586"
1841"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1843"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
1842"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12" 1844"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12"
1843"checksum lsp-types 0.63.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70090cea3cd5db0aa923575e03874b33da90c4d0fe1eaf63fa51b8925a78ef03" 1845"checksum lsp-types 0.65.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fe9e427e63e6172699737b47f1044bcade7046e2404d59ebd90c459da47cd2b"
1844"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1846"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
1845"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1847"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
1846"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" 1848"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
@@ -1891,7 +1893,7 @@ dependencies = [
1891"checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954" 1893"checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954"
1892"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 1894"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
1893"checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5" 1895"checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5"
1894"checksum rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "769d42f547015b761f70c3086ccb3f7bff355124d52e9bf96d17de41774ede4b" 1896"checksum rowan 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3eb10a10a48f0f809a217bcf074b85a03dcf79831bae80e7f1a043d0897463e2"
1895"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1897"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
1896"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" 1898"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
1897"checksum rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5" 1899"checksum rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5"
@@ -1903,13 +1905,13 @@ dependencies = [
1903"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 1905"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
1904"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1906"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
1905"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1907"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
1906"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" 1908"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
1907"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" 1909"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
1908"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" 1910"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
1909"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" 1911"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
1910"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" 1912"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
1911"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1913"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
1912"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" 1914"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
1913"checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b" 1915"checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b"
1914"checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" 1916"checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
1915"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" 1917"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
diff --git a/crates/ra_assists/src/assists/early_return.rs b/crates/ra_assists/src/assists/early_return.rs
index 264412526..023917aca 100644
--- a/crates/ra_assists/src/assists/early_return.rs
+++ b/crates/ra_assists/src/assists/early_return.rs
@@ -83,8 +83,8 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Opt
83 let parent_container = parent_block.syntax().parent()?.parent()?; 83 let parent_container = parent_block.syntax().parent()?.parent()?;
84 84
85 let early_expression: ast::Expr = match parent_container.kind() { 85 let early_expression: ast::Expr = match parent_container.kind() {
86 WHILE_EXPR | LOOP_EXPR => make::expr_continue().into(), 86 WHILE_EXPR | LOOP_EXPR => make::expr_continue(),
87 FN_DEF => make::expr_return().into(), 87 FN_DEF => make::expr_return(),
88 _ => return None, 88 _ => return None,
89 }; 89 };
90 90
@@ -116,13 +116,13 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Opt
116 ) 116 )
117 .into(), 117 .into(),
118 ), 118 ),
119 make::expr_path(make::path_from_name_ref(make::name_ref("it"))).into(), 119 make::expr_path(make::path_from_name_ref(make::name_ref("it"))),
120 ); 120 );
121 121
122 let sad_arm = make::match_arm( 122 let sad_arm = make::match_arm(
123 // FIXME: would be cool to use `None` or `Err(_)` if appropriate 123 // FIXME: would be cool to use `None` or `Err(_)` if appropriate
124 once(make::placeholder_pat().into()), 124 once(make::placeholder_pat().into()),
125 early_expression.into(), 125 early_expression,
126 ); 126 );
127 127
128 make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm])) 128 make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm]))
@@ -130,7 +130,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Opt
130 130
131 let let_stmt = make::let_stmt( 131 let let_stmt = make::let_stmt(
132 make::bind_pat(make::name(&bound_ident.syntax().to_string())).into(), 132 make::bind_pat(make::name(&bound_ident.syntax().to_string())).into(),
133 Some(match_expr.into()), 133 Some(match_expr),
134 ); 134 );
135 let let_stmt = if_indent_level.increase_indent(let_stmt); 135 let let_stmt = if_indent_level.increase_indent(let_stmt);
136 replace(let_stmt.syntax(), &then_block, &parent_block, &if_expr) 136 replace(let_stmt.syntax(), &then_block, &parent_block, &if_expr)
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index 6ca9cc2e7..7dc31ad3c 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -14,6 +14,7 @@ either = "1.5"
14 14
15ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
16ra_db = { path = "../ra_db" } 16ra_db = { path = "../ra_db" }
17ra_prof = { path = "../ra_prof" }
17hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } 18hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
18hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } 19hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
19hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } 20hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 8dbc0d667..4cd28eb4e 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -12,8 +12,8 @@ use hir_def::{
12 resolver::HasResolver, 12 resolver::HasResolver,
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, 14 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId,
15 LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, 15 LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
16 TraitId, TypeAliasId, TypeParamId, UnionId, 16 TypeParamId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
19 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -180,13 +180,11 @@ impl Module {
180 } 180 }
181 181
182 /// Returns a `ModuleScope`: a set of items, visible in this module. 182 /// Returns a `ModuleScope`: a set of items, visible in this module.
183 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { 183 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> {
184 db.crate_def_map(self.id.krate)[self.id.local_id] 184 db.crate_def_map(self.id.krate)[self.id.local_id]
185 .scope 185 .scope
186 .entries() 186 .entries()
187 .map(|(name, res)| { 187 .map(|(name, res)| (name.clone(), res.def.into()))
188 (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id }))
189 })
190 .collect() 188 .collect()
191 } 189 }
192 190
@@ -221,7 +219,7 @@ impl Module {
221 219
222 pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { 220 pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> {
223 let def_map = db.crate_def_map(self.id.krate); 221 let def_map = db.crate_def_map(self.id.krate);
224 def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() 222 def_map[self.id.local_id].scope.impls().map(ImplBlock::from).collect()
225 } 223 }
226 224
227 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { 225 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module {
@@ -229,11 +227,6 @@ impl Module {
229 } 227 }
230} 228}
231 229
232pub struct Import {
233 pub(crate) parent: Module,
234 pub(crate) id: LocalImportId,
235}
236
237#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 230#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
238pub struct StructField { 231pub struct StructField {
239 pub(crate) parent: VariantDef, 232 pub(crate) parent: VariantDef,
@@ -269,7 +262,7 @@ pub struct Struct {
269 262
270impl Struct { 263impl Struct {
271 pub fn module(self, db: &impl DefDatabase) -> Module { 264 pub fn module(self, db: &impl DefDatabase) -> Module {
272 Module { id: self.id.lookup(db).container } 265 Module { id: self.id.lookup(db).container.module(db) }
273 } 266 }
274 267
275 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 268 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -290,7 +283,7 @@ impl Struct {
290 } 283 }
291 284
292 pub fn ty(self, db: &impl HirDatabase) -> Type { 285 pub fn ty(self, db: &impl HirDatabase) -> Type {
293 Type::from_def(db, self.id.lookup(db).container.krate, self.id) 286 Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
294 } 287 }
295 288
296 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 289 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
@@ -309,11 +302,11 @@ impl Union {
309 } 302 }
310 303
311 pub fn module(self, db: &impl DefDatabase) -> Module { 304 pub fn module(self, db: &impl DefDatabase) -> Module {
312 Module { id: self.id.lookup(db).container } 305 Module { id: self.id.lookup(db).container.module(db) }
313 } 306 }
314 307
315 pub fn ty(self, db: &impl HirDatabase) -> Type { 308 pub fn ty(self, db: &impl HirDatabase) -> Type {
316 Type::from_def(db, self.id.lookup(db).container.krate, self.id) 309 Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
317 } 310 }
318 311
319 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 312 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
@@ -337,7 +330,7 @@ pub struct Enum {
337 330
338impl Enum { 331impl Enum {
339 pub fn module(self, db: &impl DefDatabase) -> Module { 332 pub fn module(self, db: &impl DefDatabase) -> Module {
340 Module { id: self.id.lookup(db).container } 333 Module { id: self.id.lookup(db).container.module(db) }
341 } 334 }
342 335
343 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 336 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -357,7 +350,7 @@ impl Enum {
357 } 350 }
358 351
359 pub fn ty(self, db: &impl HirDatabase) -> Type { 352 pub fn ty(self, db: &impl HirDatabase) -> Type {
360 Type::from_def(db, self.id.lookup(db).container.krate, self.id) 353 Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
361 } 354 }
362} 355}
363 356
@@ -553,7 +546,7 @@ pub struct Trait {
553 546
554impl Trait { 547impl Trait {
555 pub fn module(self, db: &impl DefDatabase) -> Module { 548 pub fn module(self, db: &impl DefDatabase) -> Module {
556 Module { id: self.id.lookup(db).container } 549 Module { id: self.id.lookup(db).container.module(db) }
557 } 550 }
558 551
559 pub fn name(self, db: &impl DefDatabase) -> Name { 552 pub fn name(self, db: &impl DefDatabase) -> Name {
@@ -754,7 +747,7 @@ impl ImplBlock {
754 let environment = TraitEnvironment::lower(db, &resolver); 747 let environment = TraitEnvironment::lower(db, &resolver);
755 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); 748 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
756 Type { 749 Type {
757 krate: self.id.lookup(db).container.krate, 750 krate: self.id.lookup(db).container.module(db).krate,
758 ty: InEnvironment { value: ty, environment }, 751 ty: InEnvironment { value: ty, environment },
759 } 752 }
760 } 753 }
@@ -768,7 +761,7 @@ impl ImplBlock {
768 } 761 }
769 762
770 pub fn module(&self, db: &impl DefDatabase) -> Module { 763 pub fn module(&self, db: &impl DefDatabase) -> Module {
771 self.id.lookup(db).container.into() 764 self.id.lookup(db).container.module(db).into()
772 } 765 }
773 766
774 pub fn krate(&self, db: &impl DefDatabase) -> Crate { 767 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index bfae3660b..f5ffd64fa 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -4,8 +4,8 @@ pub use hir_def::db::{
4 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, 4 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
5 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, 5 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, 6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
7 LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, 7 LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, StaticDataQuery, StructDataQuery,
8 StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, 8 TraitDataQuery, TypeAliasDataQuery,
9}; 9};
10pub use hir_expand::db::{ 10pub use hir_expand::db::{
11 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 11 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 7abb4bd75..6314be8d4 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,24 +1,28 @@
1//! FIXME: write short doc here 1//! Finds a corresponding hir data structure for a syntax node in a specific
2//! file.
3
2use hir_def::{ 4use hir_def::{
3 child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, 5 child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource,
4 ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, StaticId, StructId, 6 ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId,
5 TraitId, TypeAliasId, UnionId, VariantId, 7 StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
6}; 8};
7use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 9use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
10use ra_db::FileId;
11use ra_prof::profile;
8use ra_syntax::{ 12use ra_syntax::{
9 ast::{self, AstNode, NameOwner}, 13 ast::{self, AstNode, NameOwner},
10 match_ast, SyntaxNode, 14 match_ast, SyntaxNode,
11}; 15};
12 16
13use crate::{ 17use crate::{
14 db::{AstDatabase, DefDatabase, HirDatabase}, 18 db::{DefDatabase, HirDatabase},
15 Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local, 19 Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local,
16 MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, 20 MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
17}; 21};
18 22
19pub trait FromSource: Sized { 23pub trait FromSource: Sized {
20 type Ast; 24 type Ast;
21 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>; 25 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>;
22} 26}
23 27
24pub trait FromSourceByContainer: Sized { 28pub trait FromSourceByContainer: Sized {
@@ -32,7 +36,7 @@ where
32 T: From<<T as FromSourceByContainer>::Id>, 36 T: From<<T as FromSourceByContainer>::Id>,
33{ 37{
34 type Ast = <T as FromSourceByContainer>::Ast; 38 type Ast = <T as FromSourceByContainer>::Ast;
35 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 39 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> {
36 analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] 40 analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY]
37 .get(&src) 41 .get(&src)
38 .copied() 42 .copied()
@@ -64,7 +68,7 @@ from_source_by_container_impls![
64 68
65impl FromSource for MacroDef { 69impl FromSource for MacroDef {
66 type Ast = ast::MacroCall; 70 type Ast = ast::MacroCall;
67 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 71 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> {
68 let kind = MacroDefKind::Declarative; 72 let kind = MacroDefKind::Declarative;
69 73
70 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 74 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
@@ -80,7 +84,7 @@ impl FromSource for MacroDef {
80 84
81impl FromSource for EnumVariant { 85impl FromSource for EnumVariant {
82 type Ast = ast::EnumVariant; 86 type Ast = ast::EnumVariant;
83 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 87 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> {
84 let parent_enum = src.value.parent_enum(); 88 let parent_enum = src.value.parent_enum();
85 let src_enum = InFile { file_id: src.file_id, value: parent_enum }; 89 let src_enum = InFile { file_id: src.file_id, value: parent_enum };
86 let parent_enum = Enum::from_source(db, src_enum)?; 90 let parent_enum = Enum::from_source(db, src_enum)?;
@@ -93,7 +97,7 @@ impl FromSource for EnumVariant {
93 97
94impl FromSource for StructField { 98impl FromSource for StructField {
95 type Ast = FieldSource; 99 type Ast = FieldSource;
96 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 100 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> {
97 let src = src.as_ref(); 101 let src = src.as_ref();
98 102
99 // FIXME this is buggy 103 // FIXME this is buggy
@@ -167,6 +171,7 @@ impl TypeParam {
167 171
168impl Module { 172impl Module {
169 pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> { 173 pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> {
174 let _p = profile("Module::from_declaration");
170 let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); 175 let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
171 176
172 let parent_module = match parent_declaration { 177 let parent_module = match parent_declaration {
@@ -189,6 +194,7 @@ impl Module {
189 } 194 }
190 195
191 pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> { 196 pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> {
197 let _p = profile("Module::from_definition");
192 match src.value { 198 match src.value {
193 ModuleSource::Module(ref module) => { 199 ModuleSource::Module(ref module) => {
194 assert!(!module.has_semi()); 200 assert!(!module.has_semi());
@@ -201,10 +207,14 @@ impl Module {
201 }; 207 };
202 208
203 let original_file = src.file_id.original_file(db); 209 let original_file = src.file_id.original_file(db);
210 Module::from_file(db, original_file)
211 }
204 212
205 let (krate, local_id) = db.relevant_crates(original_file).iter().find_map(|&crate_id| { 213 fn from_file(db: &impl DefDatabase, file: FileId) -> Option<Self> {
214 let _p = profile("Module::from_file");
215 let (krate, local_id) = db.relevant_crates(file).iter().find_map(|&crate_id| {
206 let crate_def_map = db.crate_def_map(crate_id); 216 let crate_def_map = db.crate_def_map(crate_id);
207 let local_id = crate_def_map.modules_for_file(original_file).next()?; 217 let local_id = crate_def_map.modules_for_file(file).next()?;
208 Some((crate_id, local_id)) 218 Some((crate_id, local_id))
209 })?; 219 })?;
210 Some(Module { id: ModuleId { krate, local_id } }) 220 Some(Module { id: ModuleId { krate, local_id } })
@@ -212,29 +222,44 @@ impl Module {
212} 222}
213 223
214fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { 224fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap {
215 _analyze_container(db, src).unwrap_or_default() 225 let _p = profile("analyze_container");
216} 226 return child_by_source(db, src).unwrap_or_default();
217 227
218fn _analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { 228 fn child_by_source(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> {
219 // FIXME: this doesn't try to handle nested declarations 229 for container in src.value.ancestors().skip(1) {
220 for container in src.value.ancestors().skip(1) { 230 let res = match_ast! {
221 let res = match_ast! { 231 match container {
222 match container { 232 ast::TraitDef(it) => {
223 ast::TraitDef(it) => { 233 let def = Trait::from_source(db, src.with_value(it))?;
224 let c = Trait::from_source(db, src.with_value(it))?; 234 def.id.child_by_source(db)
225 c.id.child_by_source(db) 235 },
226 }, 236 ast::ImplBlock(it) => {
227 ast::ImplBlock(it) => { 237 let def = ImplBlock::from_source(db, src.with_value(it))?;
228 let c = ImplBlock::from_source(db, src.with_value(it))?; 238 def.id.child_by_source(db)
229 c.id.child_by_source(db) 239 },
230 }, 240 ast::FnDef(it) => {
231 _ => { continue }, 241 let def = Function::from_source(db, src.with_value(it))?;
232 } 242 DefWithBodyId::from(def.id)
233 }; 243 .child_by_source(db)
234 return Some(res); 244 },
235 } 245 ast::StaticDef(it) => {
246 let def = Static::from_source(db, src.with_value(it))?;
247 DefWithBodyId::from(def.id)
248 .child_by_source(db)
249 },
250 ast::ConstDef(it) => {
251 let def = Const::from_source(db, src.with_value(it))?;
252 DefWithBodyId::from(def.id)
253 .child_by_source(db)
254 },
255 _ => { continue },
256 }
257 };
258 return Some(res);
259 }
236 260
237 let module_source = ModuleSource::from_child_node(db, src); 261 let module_source = ModuleSource::from_child_node(db, src);
238 let c = Module::from_definition(db, src.with_value(module_source))?; 262 let c = Module::from_definition(db, src.with_value(module_source))?;
239 Some(c.id.child_by_source(db)) 263 Some(c.id.child_by_source(db))
264 }
240} 265}
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs
index 72afecf26..5541266e2 100644
--- a/crates/ra_hir/src/has_source.rs
+++ b/crates/ra_hir/src/has_source.rs
@@ -9,8 +9,8 @@ use hir_def::{
9use ra_syntax::ast; 9use ra_syntax::ast;
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef, 12 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, MacroDef, Module,
13 Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, 13 Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
14}; 14};
15 15
16pub use hir_expand::InFile; 16pub use hir_expand::InFile;
@@ -117,18 +117,6 @@ impl HasSource for ImplBlock {
117 self.id.lookup(db).source(db) 117 self.id.lookup(db).source(db)
118 } 118 }
119} 119}
120impl HasSource for Import {
121 type Ast = Either<ast::UseTree, ast::ExternCrateItem>;
122
123 /// Returns the syntax of the last path segment corresponding to this import
124 fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast> {
125 let src = self.parent.definition_source(db);
126 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
127 let root = db.parse_or_expand(src.file_id).unwrap();
128 let ptr = source_map.get(self.id);
129 src.with_value(ptr.map_left(|it| it.to_node(&root)).map_right(|it| it.to_node(&root)))
130 }
131}
132 120
133impl HasSource for TypeParam { 121impl HasSource for TypeParam {
134 type Ast = Either<ast::TraitDef, ast::TypeParam>; 122 type Ast = Either<ast::TraitDef, ast::TypeParam>;
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 7f9aef770..0008a8858 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -40,8 +40,8 @@ mod from_source;
40pub use crate::{ 40pub use crate::{
41 code_model::{ 41 code_model::{
42 Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, 42 Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum,
43 EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Import, Local, 43 EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Local, MacroDef,
44 MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, 44 Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias,
45 TypeParam, Union, VariantDef, 45 TypeParam, Union, VariantDef,
46 }, 46 },
47 from_source::FromSource, 47 from_source::FromSource,
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index d326169b3..85b378483 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -26,6 +26,7 @@ use hir_ty::{
26 method_resolution::{self, implements_trait}, 26 method_resolution::{self, implements_trait},
27 Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty, 27 Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty,
28}; 28};
29use ra_prof::profile;
29use ra_syntax::{ 30use ra_syntax::{
30 ast::{self, AstNode}, 31 ast::{self, AstNode},
31 match_ast, AstPtr, 32 match_ast, AstPtr,
@@ -83,6 +84,7 @@ fn def_with_body_from_child_node(
83 db: &impl HirDatabase, 84 db: &impl HirDatabase,
84 child: InFile<&SyntaxNode>, 85 child: InFile<&SyntaxNode>,
85) -> Option<DefWithBody> { 86) -> Option<DefWithBody> {
87 let _p = profile("def_with_body_from_child_node");
86 child.cloned().ancestors_with_macros(db).find_map(|node| { 88 child.cloned().ancestors_with_macros(db).find_map(|node| {
87 let n = &node.value; 89 let n = &node.value;
88 match_ast! { 90 match_ast! {
@@ -169,6 +171,7 @@ impl SourceAnalyzer {
169 node: InFile<&SyntaxNode>, 171 node: InFile<&SyntaxNode>,
170 offset: Option<TextUnit>, 172 offset: Option<TextUnit>,
171 ) -> SourceAnalyzer { 173 ) -> SourceAnalyzer {
174 let _p = profile("SourceAnalyzer::new");
172 let def_with_body = def_with_body_from_child_node(db, node); 175 let def_with_body = def_with_body_from_child_node(db, node);
173 if let Some(def) = def_with_body { 176 if let Some(def) = def_with_body {
174 let (_body, source_map) = db.body_with_source_map(def.into()); 177 let (_body, source_map) = db.body_with_source_map(def.into());
@@ -237,7 +240,13 @@ impl SourceAnalyzer {
237 } 240 }
238 241
239 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { 242 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
240 let expr_id = self.expr_id(&field.expr()?)?; 243 let expr_id = match field.expr() {
244 Some(it) => self.expr_id(&it)?,
245 None => {
246 let src = InFile { file_id: self.file_id, value: field };
247 self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?
248 }
249 };
241 self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) 250 self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into())
242 } 251 }
243 252
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index b1923bbf2..2c368f690 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -13,6 +13,7 @@ once_cell = "1.0.1"
13rustc-hash = "1.0" 13rustc-hash = "1.0"
14either = "1.5" 14either = "1.5"
15anymap = "0.12" 15anymap = "0.12"
16drop_bomb = "0.1.4"
16 17
17ra_arena = { path = "../ra_arena" } 18ra_arena = { path = "../ra_arena" }
18ra_db = { path = "../ra_db" } 19ra_db = { path = "../ra_db" }
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index ec3d57d1a..d9ea693e3 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -8,6 +8,7 @@ use hir_expand::{
8 InFile, 8 InFile,
9}; 9};
10use ra_arena::{map::ArenaMap, Arena}; 10use ra_arena::{map::ArenaMap, Arena};
11use ra_prof::profile;
11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 12use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
12 13
13use crate::{ 14use crate::{
@@ -72,6 +73,7 @@ impl StructData {
72 73
73impl EnumData { 74impl EnumData {
74 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> { 75 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> {
76 let _p = profile("enum_data_query");
75 let src = e.lookup(db).source(db); 77 let src = e.lookup(db).source(db);
76 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 78 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
77 let mut trace = Trace::new_for_arena(); 79 let mut trace = Trace::new_for_arena();
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index d4cab0561..148ff007e 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -3,42 +3,53 @@
3mod lower; 3mod lower;
4pub mod scope; 4pub mod scope;
5 5
6use std::{ops::Index, sync::Arc}; 6use std::{mem, ops::Index, sync::Arc};
7 7
8use drop_bomb::DropBomb;
8use either::Either; 9use either::Either;
9use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId}; 10use hir_expand::{
11 ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId,
12};
10use ra_arena::{map::ArenaMap, Arena}; 13use ra_arena::{map::ArenaMap, Arena};
14use ra_prof::profile;
11use ra_syntax::{ast, AstNode, AstPtr}; 15use ra_syntax::{ast, AstNode, AstPtr};
12use rustc_hash::FxHashMap; 16use rustc_hash::FxHashMap;
13 17
14use crate::{ 18use crate::{
15 db::DefDatabase, 19 db::DefDatabase,
16 expr::{Expr, ExprId, Pat, PatId}, 20 expr::{Expr, ExprId, Pat, PatId},
17 nameres::{BuiltinShadowMode, CrateDefMap}, 21 item_scope::BuiltinShadowMode,
22 nameres::CrateDefMap,
18 path::{ModPath, Path}, 23 path::{ModPath, Path},
19 src::HasSource, 24 src::HasSource,
20 DefWithBodyId, HasModule, Lookup, ModuleId, 25 DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId,
21}; 26};
22 27
23struct Expander { 28pub(crate) struct Expander {
24 crate_def_map: Arc<CrateDefMap>, 29 crate_def_map: Arc<CrateDefMap>,
25 current_file_id: HirFileId, 30 current_file_id: HirFileId,
26 hygiene: Hygiene, 31 hygiene: Hygiene,
32 ast_id_map: Arc<AstIdMap>,
27 module: ModuleId, 33 module: ModuleId,
28} 34}
29 35
30impl Expander { 36impl Expander {
31 fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { 37 pub(crate) fn new(
38 db: &impl DefDatabase,
39 current_file_id: HirFileId,
40 module: ModuleId,
41 ) -> Expander {
32 let crate_def_map = db.crate_def_map(module.krate); 42 let crate_def_map = db.crate_def_map(module.krate);
33 let hygiene = Hygiene::new(db, current_file_id); 43 let hygiene = Hygiene::new(db, current_file_id);
34 Expander { crate_def_map, current_file_id, hygiene, module } 44 let ast_id_map = db.ast_id_map(current_file_id);
45 Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module }
35 } 46 }
36 47
37 fn enter_expand( 48 pub(crate) fn enter_expand<T: ast::AstNode, DB: DefDatabase>(
38 &mut self, 49 &mut self,
39 db: &impl DefDatabase, 50 db: &DB,
40 macro_call: ast::MacroCall, 51 macro_call: ast::MacroCall,
41 ) -> Option<(Mark, ast::Expr)> { 52 ) -> Option<(Mark, T)> {
42 let ast_id = AstId::new( 53 let ast_id = AstId::new(
43 self.current_file_id, 54 self.current_file_id,
44 db.ast_id_map(self.current_file_id).ast_id(&macro_call), 55 db.ast_id_map(self.current_file_id).ast_id(&macro_call),
@@ -49,12 +60,17 @@ impl Expander {
49 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); 60 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id));
50 let file_id = call_id.as_file(); 61 let file_id = call_id.as_file();
51 if let Some(node) = db.parse_or_expand(file_id) { 62 if let Some(node) = db.parse_or_expand(file_id) {
52 if let Some(expr) = ast::Expr::cast(node) { 63 if let Some(expr) = T::cast(node) {
53 log::debug!("macro expansion {:#?}", expr.syntax()); 64 log::debug!("macro expansion {:#?}", expr.syntax());
54 65
55 let mark = Mark { file_id: self.current_file_id }; 66 let mark = Mark {
67 file_id: self.current_file_id,
68 ast_id_map: mem::take(&mut self.ast_id_map),
69 bomb: DropBomb::new("expansion mark dropped"),
70 };
56 self.hygiene = Hygiene::new(db, file_id); 71 self.hygiene = Hygiene::new(db, file_id);
57 self.current_file_id = file_id; 72 self.current_file_id = file_id;
73 self.ast_id_map = db.ast_id_map(file_id);
58 74
59 return Some((mark, expr)); 75 return Some((mark, expr));
60 } 76 }
@@ -67,13 +83,14 @@ impl Expander {
67 None 83 None
68 } 84 }
69 85
70 fn exit(&mut self, db: &impl DefDatabase, mark: Mark) { 86 pub(crate) fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) {
71 self.hygiene = Hygiene::new(db, mark.file_id); 87 self.hygiene = Hygiene::new(db, mark.file_id);
72 self.current_file_id = mark.file_id; 88 self.current_file_id = mark.file_id;
73 std::mem::forget(mark); 89 self.ast_id_map = mem::take(&mut mark.ast_id_map);
90 mark.bomb.defuse();
74 } 91 }
75 92
76 fn to_source<T>(&self, value: T) -> InFile<T> { 93 pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> {
77 InFile { file_id: self.current_file_id, value } 94 InFile { file_id: self.current_file_id, value }
78 } 95 }
79 96
@@ -91,18 +108,17 @@ impl Expander {
91 .0 108 .0
92 .take_macros() 109 .take_macros()
93 } 110 }
94}
95 111
96struct Mark { 112 fn ast_id<N: AstNode>(&self, item: &N) -> AstId<N> {
97 file_id: HirFileId, 113 let file_local_id = self.ast_id_map.ast_id(item);
114 AstId::new(self.current_file_id, file_local_id)
115 }
98} 116}
99 117
100impl Drop for Mark { 118pub(crate) struct Mark {
101 fn drop(&mut self) { 119 file_id: HirFileId,
102 if !std::thread::panicking() { 120 ast_id_map: Arc<AstIdMap>,
103 panic!("dropped mark") 121 bomb: DropBomb,
104 }
105 }
106} 122}
107 123
108/// The body of an item (function, const etc.). 124/// The body of an item (function, const etc.).
@@ -119,6 +135,7 @@ pub struct Body {
119 pub params: Vec<PatId>, 135 pub params: Vec<PatId>,
120 /// The `ExprId` of the actual body expression. 136 /// The `ExprId` of the actual body expression.
121 pub body_expr: ExprId, 137 pub body_expr: ExprId,
138 pub defs: Vec<ModuleDefId>,
122} 139}
123 140
124pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; 141pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
@@ -152,6 +169,7 @@ impl Body {
152 db: &impl DefDatabase, 169 db: &impl DefDatabase,
153 def: DefWithBodyId, 170 def: DefWithBodyId,
154 ) -> (Arc<Body>, Arc<BodySourceMap>) { 171 ) -> (Arc<Body>, Arc<BodySourceMap>) {
172 let _p = profile("body_with_source_map_query");
155 let mut params = None; 173 let mut params = None;
156 174
157 let (file_id, module, body) = match def { 175 let (file_id, module, body) = match def {
@@ -173,7 +191,7 @@ impl Body {
173 } 191 }
174 }; 192 };
175 let expander = Expander::new(db, file_id, module); 193 let expander = Expander::new(db, file_id, module);
176 let (body, source_map) = Body::new(db, expander, params, body); 194 let (body, source_map) = Body::new(db, def, expander, params, body);
177 (Arc::new(body), Arc::new(source_map)) 195 (Arc::new(body), Arc::new(source_map))
178 } 196 }
179 197
@@ -183,11 +201,12 @@ impl Body {
183 201
184 fn new( 202 fn new(
185 db: &impl DefDatabase, 203 db: &impl DefDatabase,
204 def: DefWithBodyId,
186 expander: Expander, 205 expander: Expander,
187 params: Option<ast::ParamList>, 206 params: Option<ast::ParamList>,
188 body: Option<ast::Expr>, 207 body: Option<ast::Expr>,
189 ) -> (Body, BodySourceMap) { 208 ) -> (Body, BodySourceMap) {
190 lower::lower(db, expander, params, body) 209 lower::lower(db, def, expander, params, body)
191 } 210 }
192} 211}
193 212
@@ -217,6 +236,11 @@ impl BodySourceMap {
217 self.expr_map.get(&src).cloned() 236 self.expr_map.get(&src).cloned()
218 } 237 }
219 238
239 pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> {
240 let src = node.map(|it| Either::Right(AstPtr::new(it)));
241 self.expr_map.get(&src).cloned()
242 }
243
220 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> { 244 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> {
221 self.pat_map_back.get(pat).copied() 245 self.pat_map_back.get(pat).copied()
222 } 246 }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 61193b4d8..be5d17d85 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -2,11 +2,12 @@
2//! representation. 2//! representation.
3 3
4use either::Either; 4use either::Either;
5
5use hir_expand::name::{name, AsName, Name}; 6use hir_expand::name::{name, AsName, Name};
6use ra_arena::Arena; 7use ra_arena::Arena;
7use ra_syntax::{ 8use ra_syntax::{
8 ast::{ 9 ast::{
9 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, 10 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner,
10 TypeAscriptionOwner, 11 TypeAscriptionOwner,
11 }, 12 },
12 AstNode, AstPtr, 13 AstNode, AstPtr,
@@ -24,23 +25,28 @@ use crate::{
24 path::GenericArgs, 25 path::GenericArgs,
25 path::Path, 26 path::Path,
26 type_ref::{Mutability, TypeRef}, 27 type_ref::{Mutability, TypeRef},
28 ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc,
29 StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
27}; 30};
28 31
29pub(super) fn lower( 32pub(super) fn lower(
30 db: &impl DefDatabase, 33 db: &impl DefDatabase,
34 def: DefWithBodyId,
31 expander: Expander, 35 expander: Expander,
32 params: Option<ast::ParamList>, 36 params: Option<ast::ParamList>,
33 body: Option<ast::Expr>, 37 body: Option<ast::Expr>,
34) -> (Body, BodySourceMap) { 38) -> (Body, BodySourceMap) {
35 ExprCollector { 39 ExprCollector {
36 expander,
37 db, 40 db,
41 def,
42 expander,
38 source_map: BodySourceMap::default(), 43 source_map: BodySourceMap::default(),
39 body: Body { 44 body: Body {
40 exprs: Arena::default(), 45 exprs: Arena::default(),
41 pats: Arena::default(), 46 pats: Arena::default(),
42 params: Vec::new(), 47 params: Vec::new(),
43 body_expr: ExprId::dummy(), 48 body_expr: ExprId::dummy(),
49 defs: Vec::new(),
44 }, 50 },
45 } 51 }
46 .collect(params, body) 52 .collect(params, body)
@@ -48,6 +54,7 @@ pub(super) fn lower(
48 54
49struct ExprCollector<DB> { 55struct ExprCollector<DB> {
50 db: DB, 56 db: DB,
57 def: DefWithBodyId,
51 expander: Expander, 58 expander: Expander,
52 59
53 body: Body, 60 body: Body,
@@ -365,8 +372,9 @@ where
365 arg_types.push(type_ref); 372 arg_types.push(type_ref);
366 } 373 }
367 } 374 }
375 let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast);
368 let body = self.collect_expr_opt(e.body()); 376 let body = self.collect_expr_opt(e.body());
369 self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) 377 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
370 } 378 }
371 ast::Expr::BinExpr(e) => { 379 ast::Expr::BinExpr(e) => {
372 let lhs = self.collect_expr_opt(e.lhs()); 380 let lhs = self.collect_expr_opt(e.lhs());
@@ -466,6 +474,7 @@ where
466 Some(block) => block, 474 Some(block) => block,
467 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), 475 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
468 }; 476 };
477 self.collect_block_items(&block);
469 let statements = block 478 let statements = block
470 .statements() 479 .statements()
471 .map(|s| match s { 480 .map(|s| match s {
@@ -482,6 +491,51 @@ where
482 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 491 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
483 } 492 }
484 493
494 fn collect_block_items(&mut self, block: &ast::Block) {
495 let container = ContainerId::DefWithBodyId(self.def);
496 for item in block.items() {
497 let def: ModuleDefId = match item {
498 ast::ModuleItem::FnDef(def) => {
499 let ast_id = self.expander.ast_id(&def);
500 FunctionLoc { container: container.into(), ast_id }.intern(self.db).into()
501 }
502 ast::ModuleItem::TypeAliasDef(def) => {
503 let ast_id = self.expander.ast_id(&def);
504 TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into()
505 }
506 ast::ModuleItem::ConstDef(def) => {
507 let ast_id = self.expander.ast_id(&def);
508 ConstLoc { container: container.into(), ast_id }.intern(self.db).into()
509 }
510 ast::ModuleItem::StaticDef(def) => {
511 let ast_id = self.expander.ast_id(&def);
512 StaticLoc { container, ast_id }.intern(self.db).into()
513 }
514 ast::ModuleItem::StructDef(def) => {
515 let ast_id = self.expander.ast_id(&def);
516 StructLoc { container, ast_id }.intern(self.db).into()
517 }
518 ast::ModuleItem::EnumDef(def) => {
519 let ast_id = self.expander.ast_id(&def);
520 EnumLoc { container, ast_id }.intern(self.db).into()
521 }
522 ast::ModuleItem::UnionDef(def) => {
523 let ast_id = self.expander.ast_id(&def);
524 UnionLoc { container, ast_id }.intern(self.db).into()
525 }
526 ast::ModuleItem::TraitDef(def) => {
527 let ast_id = self.expander.ast_id(&def);
528 TraitLoc { container, ast_id }.intern(self.db).into()
529 }
530 ast::ModuleItem::ImplBlock(_)
531 | ast::ModuleItem::UseItem(_)
532 | ast::ModuleItem::ExternCrateItem(_)
533 | ast::ModuleItem::Module(_) => continue,
534 };
535 self.body.defs.push(def)
536 }
537 }
538
485 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { 539 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
486 if let Some(block) = expr { 540 if let Some(block) = expr {
487 self.collect_block(block) 541 self.collect_block(block)
diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs
index 3c9379b15..4488e8502 100644
--- a/crates/ra_hir_def/src/child_by_source.rs
+++ b/crates/ra_hir_def/src/child_by_source.rs
@@ -11,8 +11,8 @@ use crate::{
11 dyn_map::DynMap, 11 dyn_map::DynMap,
12 keys, 12 keys,
13 src::{HasChildSource, HasSource}, 13 src::{HasChildSource, HasSource},
14 AdtId, AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, 14 AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId,
15 StructFieldId, TraitId, VariantId, 15 ModuleId, StructFieldId, TraitId, VariantId,
16}; 16};
17 17
18pub trait ChildBySource { 18pub trait ChildBySource {
@@ -76,55 +76,59 @@ impl ChildBySource for ModuleId {
76 let mut res = DynMap::default(); 76 let mut res = DynMap::default();
77 77
78 let crate_def_map = db.crate_def_map(self.krate); 78 let crate_def_map = db.crate_def_map(self.krate);
79 for item in crate_def_map[self.local_id].scope.declarations() { 79 let module_data = &crate_def_map[self.local_id];
80 match item {
81 ModuleDefId::FunctionId(func) => {
82 let src = func.lookup(db).source(db);
83 res[keys::FUNCTION].insert(src, func)
84 }
85 ModuleDefId::ConstId(konst) => {
86 let src = konst.lookup(db).source(db);
87 res[keys::CONST].insert(src, konst)
88 }
89 ModuleDefId::StaticId(statik) => {
90 let src = statik.lookup(db).source(db);
91 res[keys::STATIC].insert(src, statik)
92 }
93 ModuleDefId::TypeAliasId(ty) => {
94 let src = ty.lookup(db).source(db);
95 res[keys::TYPE_ALIAS].insert(src, ty)
96 }
97 ModuleDefId::TraitId(trait_) => {
98 let src = trait_.lookup(db).source(db);
99 res[keys::TRAIT].insert(src, trait_)
100 }
101 ModuleDefId::AdtId(adt) => match adt {
102 AdtId::StructId(strukt) => {
103 let src = strukt.lookup(db).source(db);
104 res[keys::STRUCT].insert(src, strukt)
105 }
106 AdtId::UnionId(union_) => {
107 let src = union_.lookup(db).source(db);
108 res[keys::UNION].insert(src, union_)
109 }
110 AdtId::EnumId(enum_) => {
111 let src = enum_.lookup(db).source(db);
112 res[keys::ENUM].insert(src, enum_)
113 }
114 },
115 _ => (),
116 }
117 }
118 80
119 for &impl_ in crate_def_map[self.local_id].impls.iter() { 81 module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item));
120 let src = impl_.lookup(db).source(db); 82
121 res[keys::IMPL].insert(src, impl_) 83 for imp in module_data.scope.impls() {
84 let src = imp.lookup(db).source(db);
85 res[keys::IMPL].insert(src, imp)
122 } 86 }
123 87
124 res 88 res
125 } 89 }
126} 90}
127 91
92fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) {
93 match item {
94 ModuleDefId::FunctionId(func) => {
95 let src = func.lookup(db).source(db);
96 map[keys::FUNCTION].insert(src, func)
97 }
98 ModuleDefId::ConstId(konst) => {
99 let src = konst.lookup(db).source(db);
100 map[keys::CONST].insert(src, konst)
101 }
102 ModuleDefId::StaticId(statik) => {
103 let src = statik.lookup(db).source(db);
104 map[keys::STATIC].insert(src, statik)
105 }
106 ModuleDefId::TypeAliasId(ty) => {
107 let src = ty.lookup(db).source(db);
108 map[keys::TYPE_ALIAS].insert(src, ty)
109 }
110 ModuleDefId::TraitId(trait_) => {
111 let src = trait_.lookup(db).source(db);
112 map[keys::TRAIT].insert(src, trait_)
113 }
114 ModuleDefId::AdtId(adt) => match adt {
115 AdtId::StructId(strukt) => {
116 let src = strukt.lookup(db).source(db);
117 map[keys::STRUCT].insert(src, strukt)
118 }
119 AdtId::UnionId(union_) => {
120 let src = union_.lookup(db).source(db);
121 map[keys::UNION].insert(src, union_)
122 }
123 AdtId::EnumId(enum_) => {
124 let src = enum_.lookup(db).source(db);
125 map[keys::ENUM].insert(src, enum_)
126 }
127 },
128 _ => (),
129 }
130}
131
128impl ChildBySource for VariantId { 132impl ChildBySource for VariantId {
129 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { 133 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap {
130 let mut res = DynMap::default(); 134 let mut res = DynMap::default();
@@ -160,3 +164,12 @@ impl ChildBySource for EnumId {
160 res 164 res
161 } 165 }
162} 166}
167
168impl ChildBySource for DefWithBodyId {
169 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap {
170 let mut res = DynMap::default();
171 let body = db.body(*self);
172 body.defs.iter().copied().for_each(|item| add_module_def(db, &mut res, item));
173 res
174 }
175}
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 4f4ef57cc..1aa9a9b7d 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -4,16 +4,16 @@ use std::sync::Arc;
4 4
5use hir_expand::{ 5use hir_expand::{
6 name::{name, AsName, Name}, 6 name::{name, AsName, Name},
7 AstId, 7 AstId, InFile,
8}; 8};
9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 9use ra_syntax::ast::{self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner};
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase, 12 db::DefDatabase,
13 src::HasSource, 13 src::HasSource,
14 type_ref::{Mutability, TypeRef}, 14 type_ref::{Mutability, TypeRef},
15 AssocItemId, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, Intern, Lookup, 15 AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule,
16 StaticId, TraitId, TypeAliasId, TypeAliasLoc, 16 ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
17}; 17};
18 18
19#[derive(Debug, Clone, PartialEq, Eq)] 19#[derive(Debug, Clone, PartialEq, Eq)]
@@ -99,7 +99,7 @@ impl TraitData {
99 let auto = src.value.is_auto(); 99 let auto = src.value.is_auto();
100 let ast_id_map = db.ast_id_map(src.file_id); 100 let ast_id_map = db.ast_id_map(src.file_id);
101 101
102 let container = ContainerId::TraitId(tr); 102 let container = AssocContainerId::TraitId(tr);
103 let items = if let Some(item_list) = src.value.item_list() { 103 let items = if let Some(item_list) = src.value.item_list() {
104 item_list 104 item_list
105 .impl_items() 105 .impl_items()
@@ -167,46 +167,24 @@ pub struct ImplData {
167 167
168impl ImplData { 168impl ImplData {
169 pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> { 169 pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> {
170 let src = id.lookup(db).source(db); 170 let impl_loc = id.lookup(db);
171 let items = db.ast_id_map(src.file_id); 171 let src = impl_loc.source(db);
172 172
173 let target_trait = src.value.target_trait().map(TypeRef::from_ast); 173 let target_trait = src.value.target_trait().map(TypeRef::from_ast);
174 let target_type = TypeRef::from_ast_opt(src.value.target_type()); 174 let target_type = TypeRef::from_ast_opt(src.value.target_type());
175 let is_negative = src.value.is_negative(); 175 let is_negative = src.value.is_negative();
176 let module_id = impl_loc.container.module(db);
176 177
177 let items = if let Some(item_list) = src.value.item_list() { 178 let mut items = Vec::new();
178 item_list 179 if let Some(item_list) = src.value.item_list() {
179 .impl_items() 180 items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id));
180 .map(|item_node| match item_node { 181 items.extend(collect_impl_items_in_macros(
181 ast::ImplItem::FnDef(it) => { 182 db,
182 let def = FunctionLoc { 183 module_id,
183 container: ContainerId::ImplId(id), 184 &src.with_value(item_list),
184 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 185 id,
185 } 186 ));
186 .intern(db); 187 }
187 def.into()
188 }
189 ast::ImplItem::ConstDef(it) => {
190 let def = ConstLoc {
191 container: ContainerId::ImplId(id),
192 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
193 }
194 .intern(db);
195 def.into()
196 }
197 ast::ImplItem::TypeAliasDef(it) => {
198 let def = TypeAliasLoc {
199 container: ContainerId::ImplId(id),
200 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
201 }
202 .intern(db);
203 def.into()
204 }
205 })
206 .collect()
207 } else {
208 Vec::new()
209 };
210 188
211 let res = ImplData { target_trait, target_type, items, is_negative }; 189 let res = ImplData { target_trait, target_type, items, is_negative };
212 Arc::new(res) 190 Arc::new(res)
@@ -237,3 +215,92 @@ impl ConstData {
237 ConstData { name, type_ref } 215 ConstData { name, type_ref }
238 } 216 }
239} 217}
218
219fn collect_impl_items_in_macros(
220 db: &impl DefDatabase,
221 module_id: ModuleId,
222 impl_block: &InFile<ast::ItemList>,
223 id: ImplId,
224) -> Vec<AssocItemId> {
225 let mut expander = Expander::new(db, impl_block.file_id, module_id);
226 let mut res = Vec::new();
227
228 // We set a limit to protect against infinite recursion
229 let limit = 100;
230
231 for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) {
232 res.extend(collect_impl_items_in_macro(db, &mut expander, m, id, limit))
233 }
234
235 res
236}
237
238fn collect_impl_items_in_macro(
239 db: &impl DefDatabase,
240 expander: &mut Expander,
241 m: ast::MacroCall,
242 id: ImplId,
243 limit: usize,
244) -> Vec<AssocItemId> {
245 if limit == 0 {
246 return Vec::new();
247 }
248
249 if let Some((mark, items)) = expander.enter_expand(db, m) {
250 let items: InFile<ast::MacroItems> = expander.to_source(items);
251 let mut res = collect_impl_items(
252 db,
253 items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())),
254 items.file_id,
255 id,
256 );
257 // Recursive collect macros
258 // Note that ast::ModuleItem do not include ast::MacroCall
259 // We cannot use ModuleItemOwner::items here
260 for it in items.value.syntax().children().filter_map(ast::MacroCall::cast) {
261 res.extend(collect_impl_items_in_macro(db, expander, it, id, limit - 1))
262 }
263 expander.exit(db, mark);
264 res
265 } else {
266 Vec::new()
267 }
268}
269
270fn collect_impl_items(
271 db: &impl DefDatabase,
272 impl_items: impl Iterator<Item = ImplItem>,
273 file_id: crate::HirFileId,
274 id: ImplId,
275) -> Vec<AssocItemId> {
276 let items = db.ast_id_map(file_id);
277
278 impl_items
279 .map(|item_node| match item_node {
280 ast::ImplItem::FnDef(it) => {
281 let def = FunctionLoc {
282 container: AssocContainerId::ImplId(id),
283 ast_id: AstId::new(file_id, items.ast_id(&it)),
284 }
285 .intern(db);
286 def.into()
287 }
288 ast::ImplItem::ConstDef(it) => {
289 let def = ConstLoc {
290 container: AssocContainerId::ImplId(id),
291 ast_id: AstId::new(file_id, items.ast_id(&it)),
292 }
293 .intern(db);
294 def.into()
295 }
296 ast::ImplItem::TypeAliasDef(it) => {
297 let def = TypeAliasLoc {
298 container: AssocContainerId::ImplId(id),
299 ast_id: AstId::new(file_id, items.ast_id(&it)),
300 }
301 .intern(db);
302 def.into()
303 }
304 })
305 .collect()
306}
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 98bff6cb7..c55fd4111 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -13,10 +13,7 @@ use crate::{
13 docs::Documentation, 13 docs::Documentation,
14 generics::GenericParams, 14 generics::GenericParams,
15 lang_item::{LangItemTarget, LangItems}, 15 lang_item::{LangItemTarget, LangItems},
16 nameres::{ 16 nameres::{raw::RawItems, CrateDefMap},
17 raw::{ImportSourceMap, RawItems},
18 CrateDefMap,
19 },
20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 17 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
21 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, 18 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
22 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, 19 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
@@ -46,12 +43,6 @@ pub trait InternDatabase: SourceDatabase {
46 43
47#[salsa::query_group(DefDatabaseStorage)] 44#[salsa::query_group(DefDatabaseStorage)]
48pub trait DefDatabase: InternDatabase + AstDatabase { 45pub trait DefDatabase: InternDatabase + AstDatabase {
49 #[salsa::invoke(RawItems::raw_items_with_source_map_query)]
50 fn raw_items_with_source_map(
51 &self,
52 file_id: HirFileId,
53 ) -> (Arc<RawItems>, Arc<ImportSourceMap>);
54
55 #[salsa::invoke(RawItems::raw_items_query)] 46 #[salsa::invoke(RawItems::raw_items_query)]
56 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; 47 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
57 48
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index 6fad80a8d..a75ef9970 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -143,6 +143,7 @@ pub enum Expr {
143 Lambda { 143 Lambda {
144 args: Vec<PatId>, 144 args: Vec<PatId>,
145 arg_types: Vec<Option<TypeRef>>, 145 arg_types: Vec<Option<TypeRef>>,
146 ret_type: Option<TypeRef>,
146 body: ExprId, 147 body: ExprId,
147 }, 148 },
148 Tuple { 149 Tuple {
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
new file mode 100644
index 000000000..9e082c5f7
--- /dev/null
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -0,0 +1,155 @@
1//! Describes items defined or visible (ie, imported) in a certain scope.
2//! This is shared between modules and blocks.
3
4use hir_expand::name::Name;
5use once_cell::sync::Lazy;
6use rustc_hash::FxHashMap;
7
8use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId};
9
10#[derive(Debug, Default, PartialEq, Eq)]
11pub struct ItemScope {
12 items: FxHashMap<Name, Resolution>,
13 impls: Vec<ImplId>,
14 /// Macros visible in current module in legacy textual scope
15 ///
16 /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first.
17 /// If it yields no result, then it turns to module scoped `macros`.
18 /// It macros with name qualified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
19 /// and only normal scoped `macros` will be searched in.
20 ///
21 /// Note that this automatically inherit macros defined textually before the definition of module itself.
22 ///
23 /// Module scoped macros will be inserted into `items` instead of here.
24 // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
25 // be all resolved to the last one defined if shadowing happens.
26 legacy_macros: FxHashMap<Name, MacroDefId>,
27}
28
29static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
30 BuiltinType::ALL
31 .iter()
32 .map(|(name, ty)| {
33 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: false })
34 })
35 .collect()
36});
37
38/// Shadow mode for builtin type which can be shadowed by module.
39#[derive(Debug, Copy, Clone, PartialEq, Eq)]
40pub(crate) enum BuiltinShadowMode {
41 // Prefer Module
42 Module,
43 // Prefer Other Types
44 Other,
45}
46
47/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
48/// Other methods will only resolve values, types and module scoped macros only.
49impl ItemScope {
50 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
51 //FIXME: shadowing
52 self.items.iter().chain(BUILTIN_SCOPE.iter())
53 }
54
55 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
56 self.entries()
57 .filter_map(|(_name, res)| if !res.import { Some(res.def) } else { None })
58 .flat_map(|per_ns| {
59 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
60 })
61 }
62
63 pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
64 self.impls.iter().copied()
65 }
66
67 /// Iterate over all module scoped macros
68 pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
69 self.items
70 .iter()
71 .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_)))
72 }
73
74 /// Iterate over all legacy textual scoped macros visible at the end of the module
75 pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
76 self.legacy_macros.iter().map(|(name, def)| (name, *def))
77 }
78
79 /// Get a name from current module scope, legacy macros are not included
80 pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
81 match shadow {
82 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
83 BuiltinShadowMode::Other => {
84 let item = self.items.get(name);
85 if let Some(res) = item {
86 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
87 return BUILTIN_SCOPE.get(name).or(item);
88 }
89 }
90
91 item.or_else(|| BUILTIN_SCOPE.get(name))
92 }
93 }
94 }
95
96 pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
97 self.items.values().filter_map(|r| match r.def.take_types() {
98 Some(ModuleDefId::TraitId(t)) => Some(t),
99 _ => None,
100 })
101 }
102
103 pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
104 self.legacy_macros.get(name).copied()
105 }
106
107 pub(crate) fn define_impl(&mut self, imp: ImplId) {
108 self.impls.push(imp)
109 }
110
111 pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) {
112 self.legacy_macros.insert(name, mac);
113 }
114
115 pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, import: bool) -> bool {
116 let mut changed = false;
117 let existing = self.items.entry(name.clone()).or_default();
118
119 if existing.def.types.is_none() && res.def.types.is_some() {
120 existing.def.types = res.def.types;
121 existing.import = import || res.import;
122 changed = true;
123 }
124 if existing.def.values.is_none() && res.def.values.is_some() {
125 existing.def.values = res.def.values;
126 existing.import = import || res.import;
127 changed = true;
128 }
129 if existing.def.macros.is_none() && res.def.macros.is_some() {
130 existing.def.macros = res.def.macros;
131 existing.import = import || res.import;
132 changed = true;
133 }
134
135 if existing.def.is_none() && res.def.is_none() && !existing.import && res.import {
136 existing.import = res.import;
137 }
138 changed
139 }
140
141 pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> {
142 self.items.iter().map(|(name, res)| (name.clone(), res.clone())).collect()
143 }
144
145 pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> {
146 self.legacy_macros.clone()
147 }
148}
149
150#[derive(Debug, Clone, PartialEq, Eq, Default)]
151pub struct Resolution {
152 /// None for unresolved
153 pub def: PerNs,
154 pub(crate) import: bool,
155}
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index f4fdbdcfc..cef061837 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -81,7 +81,7 @@ impl LangItems {
81 // Look for impl targets 81 // Look for impl targets
82 let def_map = db.crate_def_map(module.krate); 82 let def_map = db.crate_def_map(module.krate);
83 let module_data = &def_map[module.local_id]; 83 let module_data = &def_map[module.local_id];
84 for &impl_block in module_data.impls.iter() { 84 for impl_block in module_data.scope.impls() {
85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId) 85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId)
86 } 86 }
87 87
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index f085bbe87..f6c7f38d1 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -15,6 +15,7 @@ pub mod type_ref;
15pub mod builtin_type; 15pub mod builtin_type;
16pub mod diagnostics; 16pub mod diagnostics;
17pub mod per_ns; 17pub mod per_ns;
18pub mod item_scope;
18 19
19pub mod dyn_map; 20pub mod dyn_map;
20pub mod keys; 21pub mod keys;
@@ -45,15 +46,12 @@ use std::hash::Hash;
45use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; 46use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId};
46use ra_arena::{impl_arena_id, RawId}; 47use ra_arena::{impl_arena_id, RawId};
47use ra_db::{impl_intern_key, salsa, CrateId}; 48use ra_db::{impl_intern_key, salsa, CrateId};
48use ra_syntax::ast; 49use ra_syntax::{ast, AstNode};
49 50
51use crate::body::Expander;
50use crate::builtin_type::BuiltinType; 52use crate::builtin_type::BuiltinType;
51 53
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53pub struct LocalImportId(RawId);
54impl_arena_id!(LocalImportId);
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
57pub struct ModuleId { 55pub struct ModuleId {
58 pub krate: CrateId, 56 pub krate: CrateId,
59 pub local_id: LocalModuleId, 57 pub local_id: LocalModuleId,
@@ -65,101 +63,57 @@ pub struct ModuleId {
65pub struct LocalModuleId(RawId); 63pub struct LocalModuleId(RawId);
66impl_arena_id!(LocalModuleId); 64impl_arena_id!(LocalModuleId);
67 65
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
69pub struct FunctionId(salsa::InternId);
70impl_intern_key!(FunctionId);
71
72#[derive(Debug, Clone, PartialEq, Eq, Hash)] 66#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct FunctionLoc { 67pub struct ItemLoc<N: AstNode> {
74 pub container: ContainerId, 68 pub container: ContainerId,
75 pub ast_id: AstId<ast::FnDef>, 69 pub ast_id: AstId<N>,
76} 70}
77 71
78impl Intern for FunctionLoc { 72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
79 type ID = FunctionId; 73pub struct AssocItemLoc<N: AstNode> {
80 fn intern(self, db: &impl db::DefDatabase) -> FunctionId { 74 pub container: AssocContainerId,
81 db.intern_function(self) 75 pub ast_id: AstId<N>,
82 }
83} 76}
84 77
85impl Lookup for FunctionId { 78macro_rules! impl_intern {
86 type Data = FunctionLoc; 79 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
87 fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc { 80 impl_intern_key!($id);
88 db.lookup_intern_function(*self)
89 }
90}
91 81
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 82 impl Intern for $loc {
93pub struct StructId(salsa::InternId); 83 type ID = $id;
94impl_intern_key!(StructId); 84 fn intern(self, db: &impl db::DefDatabase) -> $id {
85 db.$intern(self)
86 }
87 }
95 88
96#[derive(Debug, Clone, PartialEq, Eq, Hash)] 89 impl Lookup for $id {
97pub struct StructLoc { 90 type Data = $loc;
98 pub container: ModuleId, 91 fn lookup(&self, db: &impl db::DefDatabase) -> $loc {
99 pub ast_id: AstId<ast::StructDef>, 92 db.$lookup(*self)
93 }
94 }
95 };
100} 96}
101 97
102impl Intern for StructLoc { 98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
103 type ID = StructId; 99pub struct FunctionId(salsa::InternId);
104 fn intern(self, db: &impl db::DefDatabase) -> StructId { 100type FunctionLoc = AssocItemLoc<ast::FnDef>;
105 db.intern_struct(self) 101impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
106 }
107}
108 102
109impl Lookup for StructId { 103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
110 type Data = StructLoc; 104pub struct StructId(salsa::InternId);
111 fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { 105type StructLoc = ItemLoc<ast::StructDef>;
112 db.lookup_intern_struct(*self) 106impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
113 }
114}
115 107
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub struct UnionId(salsa::InternId); 109pub struct UnionId(salsa::InternId);
118impl_intern_key!(UnionId); 110pub type UnionLoc = ItemLoc<ast::UnionDef>;
119 111impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
120#[derive(Debug, Clone, PartialEq, Eq, Hash)]
121pub struct UnionLoc {
122 pub container: ModuleId,
123 pub ast_id: AstId<ast::UnionDef>,
124}
125
126impl Intern for UnionLoc {
127 type ID = UnionId;
128 fn intern(self, db: &impl db::DefDatabase) -> UnionId {
129 db.intern_union(self)
130 }
131}
132
133impl Lookup for UnionId {
134 type Data = UnionLoc;
135 fn lookup(&self, db: &impl db::DefDatabase) -> UnionLoc {
136 db.lookup_intern_union(*self)
137 }
138}
139 112
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 113#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141pub struct EnumId(salsa::InternId); 114pub struct EnumId(salsa::InternId);
142impl_intern_key!(EnumId); 115pub type EnumLoc = ItemLoc<ast::EnumDef>;
143 116impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub struct EnumLoc {
146 pub container: ModuleId,
147 pub ast_id: AstId<ast::EnumDef>,
148}
149
150impl Intern for EnumLoc {
151 type ID = EnumId;
152 fn intern(self, db: &impl db::DefDatabase) -> EnumId {
153 db.intern_enum(self)
154 }
155}
156
157impl Lookup for EnumId {
158 type Data = EnumLoc;
159 fn lookup(&self, db: &impl db::DefDatabase) -> EnumLoc {
160 db.lookup_intern_enum(*self)
161 }
162}
163 117
164// FIXME: rename to `VariantId`, only enums can ave variants 118// FIXME: rename to `VariantId`, only enums can ave variants
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -184,122 +138,38 @@ impl_arena_id!(LocalStructFieldId);
184 138
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub struct ConstId(salsa::InternId); 140pub struct ConstId(salsa::InternId);
187impl_intern_key!(ConstId); 141type ConstLoc = AssocItemLoc<ast::ConstDef>;
188#[derive(Debug, Clone, PartialEq, Eq, Hash)] 142impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
189pub struct ConstLoc {
190 pub container: ContainerId,
191 pub ast_id: AstId<ast::ConstDef>,
192}
193
194impl Intern for ConstLoc {
195 type ID = ConstId;
196 fn intern(self, db: &impl db::DefDatabase) -> ConstId {
197 db.intern_const(self)
198 }
199}
200
201impl Lookup for ConstId {
202 type Data = ConstLoc;
203 fn lookup(&self, db: &impl db::DefDatabase) -> ConstLoc {
204 db.lookup_intern_const(*self)
205 }
206}
207 143
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209pub struct StaticId(salsa::InternId); 145pub struct StaticId(salsa::InternId);
210impl_intern_key!(StaticId); 146pub type StaticLoc = ItemLoc<ast::StaticDef>;
211 147impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
212#[derive(Debug, Clone, PartialEq, Eq, Hash)]
213pub struct StaticLoc {
214 pub container: ModuleId,
215 pub ast_id: AstId<ast::StaticDef>,
216}
217
218impl Intern for StaticLoc {
219 type ID = StaticId;
220 fn intern(self, db: &impl db::DefDatabase) -> StaticId {
221 db.intern_static(self)
222 }
223}
224
225impl Lookup for StaticId {
226 type Data = StaticLoc;
227 fn lookup(&self, db: &impl db::DefDatabase) -> StaticLoc {
228 db.lookup_intern_static(*self)
229 }
230}
231 148
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233pub struct TraitId(salsa::InternId); 150pub struct TraitId(salsa::InternId);
234impl_intern_key!(TraitId); 151pub type TraitLoc = ItemLoc<ast::TraitDef>;
235 152impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
236#[derive(Debug, Clone, PartialEq, Eq, Hash)]
237pub struct TraitLoc {
238 pub container: ModuleId,
239 pub ast_id: AstId<ast::TraitDef>,
240}
241
242impl Intern for TraitLoc {
243 type ID = TraitId;
244 fn intern(self, db: &impl db::DefDatabase) -> TraitId {
245 db.intern_trait(self)
246 }
247}
248
249impl Lookup for TraitId {
250 type Data = TraitLoc;
251 fn lookup(&self, db: &impl db::DefDatabase) -> TraitLoc {
252 db.lookup_intern_trait(*self)
253 }
254}
255 153
256#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
257pub struct TypeAliasId(salsa::InternId); 155pub struct TypeAliasId(salsa::InternId);
258impl_intern_key!(TypeAliasId); 156type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>;
259 157impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
260#[derive(Debug, Clone, PartialEq, Eq, Hash)]
261pub struct TypeAliasLoc {
262 pub container: ContainerId,
263 pub ast_id: AstId<ast::TypeAliasDef>,
264}
265
266impl Intern for TypeAliasLoc {
267 type ID = TypeAliasId;
268 fn intern(self, db: &impl db::DefDatabase) -> TypeAliasId {
269 db.intern_type_alias(self)
270 }
271}
272
273impl Lookup for TypeAliasId {
274 type Data = TypeAliasLoc;
275 fn lookup(&self, db: &impl db::DefDatabase) -> TypeAliasLoc {
276 db.lookup_intern_type_alias(*self)
277 }
278}
279 158
280#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 159#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
281pub struct ImplId(salsa::InternId); 160pub struct ImplId(salsa::InternId);
282impl_intern_key!(ImplId); 161type ImplLoc = ItemLoc<ast::ImplBlock>;
162impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
283 163
284#[derive(Debug, Clone, PartialEq, Eq, Hash)] 164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
285pub struct ImplLoc { 165pub struct TypeParamId {
286 pub container: ModuleId, 166 pub parent: GenericDefId,
287 pub ast_id: AstId<ast::ImplBlock>, 167 pub local_id: LocalTypeParamId,
288}
289
290impl Intern for ImplLoc {
291 type ID = ImplId;
292 fn intern(self, db: &impl db::DefDatabase) -> ImplId {
293 db.intern_impl(self)
294 }
295} 168}
296 169
297impl Lookup for ImplId { 170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
298 type Data = ImplLoc; 171pub struct LocalTypeParamId(RawId);
299 fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { 172impl_arena_id!(LocalTypeParamId);
300 db.lookup_intern_impl(*self)
301 }
302}
303 173
304macro_rules! impl_froms { 174macro_rules! impl_froms {
305 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { 175 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
@@ -321,21 +191,18 @@ macro_rules! impl_froms {
321} 191}
322 192
323#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
324pub struct TypeParamId { 194pub enum ContainerId {
325 pub parent: GenericDefId, 195 ModuleId(ModuleId),
326 pub local_id: LocalTypeParamId, 196 DefWithBodyId(DefWithBodyId),
327} 197}
328 198
329#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 199#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
330pub struct LocalTypeParamId(RawId); 200pub enum AssocContainerId {
331impl_arena_id!(LocalTypeParamId); 201 ContainerId(ContainerId),
332
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
334pub enum ContainerId {
335 ModuleId(ModuleId),
336 ImplId(ImplId), 202 ImplId(ImplId),
337 TraitId(TraitId), 203 TraitId(TraitId),
338} 204}
205impl_froms!(AssocContainerId: ContainerId);
339 206
340/// A Data Type 207/// A Data Type
341#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 208#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -478,33 +345,28 @@ pub trait HasModule {
478 fn module(&self, db: &impl db::DefDatabase) -> ModuleId; 345 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
479} 346}
480 347
481impl HasModule for FunctionLoc { 348impl HasModule for ContainerId {
482 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 349 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
483 match self.container { 350 match *self {
484 ContainerId::ModuleId(it) => it, 351 ContainerId::ModuleId(it) => it,
485 ContainerId::ImplId(it) => it.lookup(db).container, 352 ContainerId::DefWithBodyId(it) => it.module(db),
486 ContainerId::TraitId(it) => it.lookup(db).container,
487 } 353 }
488 } 354 }
489} 355}
490 356
491impl HasModule for TypeAliasLoc { 357impl HasModule for AssocContainerId {
492 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 358 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
493 match self.container { 359 match *self {
494 ContainerId::ModuleId(it) => it, 360 AssocContainerId::ContainerId(it) => it.module(db),
495 ContainerId::ImplId(it) => it.lookup(db).container, 361 AssocContainerId::ImplId(it) => it.lookup(db).container.module(db),
496 ContainerId::TraitId(it) => it.lookup(db).container, 362 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db),
497 } 363 }
498 } 364 }
499} 365}
500 366
501impl HasModule for ConstLoc { 367impl<N: AstNode> HasModule for AssocItemLoc<N> {
502 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 368 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
503 match self.container { 369 self.container.module(db)
504 ContainerId::ModuleId(it) => it,
505 ContainerId::ImplId(it) => it.lookup(db).container,
506 ContainerId::TraitId(it) => it.lookup(db).container,
507 }
508 } 370 }
509} 371}
510 372
@@ -515,6 +377,7 @@ impl HasModule for AdtId {
515 AdtId::UnionId(it) => it.lookup(db).container, 377 AdtId::UnionId(it) => it.lookup(db).container,
516 AdtId::EnumId(it) => it.lookup(db).container, 378 AdtId::EnumId(it) => it.lookup(db).container,
517 } 379 }
380 .module(db)
518 } 381 }
519} 382}
520 383
@@ -533,17 +396,17 @@ impl HasModule for GenericDefId {
533 match self { 396 match self {
534 GenericDefId::FunctionId(it) => it.lookup(db).module(db), 397 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
535 GenericDefId::AdtId(it) => it.module(db), 398 GenericDefId::AdtId(it) => it.module(db),
536 GenericDefId::TraitId(it) => it.lookup(db).container, 399 GenericDefId::TraitId(it) => it.lookup(db).container.module(db),
537 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 400 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
538 GenericDefId::ImplId(it) => it.lookup(db).container, 401 GenericDefId::ImplId(it) => it.lookup(db).container.module(db),
539 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container, 402 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
540 GenericDefId::ConstId(it) => it.lookup(db).module(db), 403 GenericDefId::ConstId(it) => it.lookup(db).module(db),
541 } 404 }
542 } 405 }
543} 406}
544 407
545impl HasModule for StaticLoc { 408impl HasModule for StaticLoc {
546 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 409 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
547 self.container 410 self.container.module(db)
548 } 411 }
549} 412}
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 9aae7e48e..5d4ca73a3 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -57,10 +57,7 @@ mod tests;
57 57
58use std::sync::Arc; 58use std::sync::Arc;
59 59
60use hir_expand::{ 60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
61 ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId,
62};
63use once_cell::sync::Lazy;
64use ra_arena::Arena; 61use ra_arena::Arena;
65use ra_db::{CrateId, Edition, FileId, FilePosition}; 62use ra_db::{CrateId, Edition, FileId, FilePosition};
66use ra_prof::profile; 63use ra_prof::profile;
@@ -71,12 +68,12 @@ use ra_syntax::{
71use rustc_hash::FxHashMap; 68use rustc_hash::FxHashMap;
72 69
73use crate::{ 70use crate::{
74 builtin_type::BuiltinType,
75 db::DefDatabase, 71 db::DefDatabase,
72 item_scope::{BuiltinShadowMode, ItemScope},
76 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, 73 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
77 path::ModPath, 74 path::ModPath,
78 per_ns::PerNs, 75 per_ns::PerNs,
79 AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, 76 AstId, LocalModuleId, ModuleDefId, ModuleId,
80}; 77};
81 78
82/// Contains all top-level defs from a macro-expanded crate 79/// Contains all top-level defs from a macro-expanded crate
@@ -168,118 +165,10 @@ impl ModuleOrigin {
168pub struct ModuleData { 165pub struct ModuleData {
169 pub parent: Option<LocalModuleId>, 166 pub parent: Option<LocalModuleId>,
170 pub children: FxHashMap<Name, LocalModuleId>, 167 pub children: FxHashMap<Name, LocalModuleId>,
171 pub scope: ModuleScope, 168 pub scope: ItemScope,
172 169
173 /// Where does this module come from? 170 /// Where does this module come from?
174 pub origin: ModuleOrigin, 171 pub origin: ModuleOrigin,
175
176 pub impls: Vec<ImplId>,
177}
178
179#[derive(Default, Debug, PartialEq, Eq)]
180pub(crate) struct Declarations {
181 fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>,
182}
183
184#[derive(Debug, Default, PartialEq, Eq)]
185pub struct ModuleScope {
186 items: FxHashMap<Name, Resolution>,
187 /// Macros visable in current module in legacy textual scope
188 ///
189 /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first.
190 /// If it yields no result, then it turns to module scoped `macros`.
191 /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
192 /// and only normal scoped `macros` will be searched in.
193 ///
194 /// Note that this automatically inherit macros defined textually before the definition of module itself.
195 ///
196 /// Module scoped macros will be inserted into `items` instead of here.
197 // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
198 // be all resolved to the last one defined if shadowing happens.
199 legacy_macros: FxHashMap<Name, MacroDefId>,
200}
201
202static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
203 BuiltinType::ALL
204 .iter()
205 .map(|(name, ty)| {
206 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
207 })
208 .collect()
209});
210
211/// Shadow mode for builtin type which can be shadowed by module.
212#[derive(Debug, Copy, Clone, PartialEq, Eq)]
213pub enum BuiltinShadowMode {
214 // Prefer Module
215 Module,
216 // Prefer Other Types
217 Other,
218}
219
220/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
221/// Other methods will only resolve values, types and module scoped macros only.
222impl ModuleScope {
223 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
224 //FIXME: shadowing
225 self.items.iter().chain(BUILTIN_SCOPE.iter())
226 }
227
228 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
229 self.entries()
230 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
231 .flat_map(|per_ns| {
232 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
233 })
234 }
235
236 /// Iterate over all module scoped macros
237 pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
238 self.items
239 .iter()
240 .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_)))
241 }
242
243 /// Iterate over all legacy textual scoped macros visable at the end of the module
244 pub fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
245 self.legacy_macros.iter().map(|(name, def)| (name, *def))
246 }
247
248 /// Get a name from current module scope, legacy macros are not included
249 pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
250 match shadow {
251 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
252 BuiltinShadowMode::Other => {
253 let item = self.items.get(name);
254 if let Some(res) = item {
255 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
256 return BUILTIN_SCOPE.get(name).or(item);
257 }
258 }
259
260 item.or_else(|| BUILTIN_SCOPE.get(name))
261 }
262 }
263 }
264
265 pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
266 self.items.values().filter_map(|r| match r.def.take_types() {
267 Some(ModuleDefId::TraitId(t)) => Some(t),
268 _ => None,
269 })
270 }
271
272 fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
273 self.legacy_macros.get(name).copied()
274 }
275}
276
277#[derive(Debug, Clone, PartialEq, Eq, Default)]
278pub struct Resolution {
279 /// None for unresolved
280 pub def: PerNs,
281 /// ident by which this is imported into local scope.
282 pub import: Option<LocalImportId>,
283} 172}
284 173
285impl CrateDefMap { 174impl CrateDefMap {
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 8bbf7ffa2..2b194f488 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -18,15 +18,15 @@ use test_utils::tested_by;
18use crate::{ 18use crate::{
19 attr::Attrs, 19 attr::Attrs,
20 db::DefDatabase, 20 db::DefDatabase,
21 item_scope::Resolution,
21 nameres::{ 22 nameres::{
22 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 23 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
23 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode, 24 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode,
24 }, 25 },
25 path::{ModPath, PathKind}, 26 path::{ModPath, PathKind},
26 per_ns::PerNs, 27 per_ns::PerNs,
27 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, 28 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
28 LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, 29 LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
29 TypeAliasLoc, UnionLoc,
30}; 30};
31 31
32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -92,7 +92,7 @@ impl PartialResolvedImport {
92#[derive(Clone, Debug, Eq, PartialEq)] 92#[derive(Clone, Debug, Eq, PartialEq)]
93struct ImportDirective { 93struct ImportDirective {
94 module_id: LocalModuleId, 94 module_id: LocalModuleId,
95 import_id: LocalImportId, 95 import_id: raw::Import,
96 import: raw::ImportData, 96 import: raw::ImportData,
97 status: PartialResolvedImport, 97 status: PartialResolvedImport,
98} 98}
@@ -109,7 +109,7 @@ struct MacroDirective {
109struct DefCollector<'a, DB> { 109struct DefCollector<'a, DB> {
110 db: &'a DB, 110 db: &'a DB,
111 def_map: CrateDefMap, 111 def_map: CrateDefMap,
112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>, 112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, raw::Import)>>,
113 unresolved_imports: Vec<ImportDirective>, 113 unresolved_imports: Vec<ImportDirective>,
114 resolved_imports: Vec<ImportDirective>, 114 resolved_imports: Vec<ImportDirective>,
115 unexpanded_macros: Vec<MacroDirective>, 115 unexpanded_macros: Vec<MacroDirective>,
@@ -218,21 +218,21 @@ where
218 self.update( 218 self.update(
219 self.def_map.root, 219 self.def_map.root,
220 None, 220 None,
221 &[(name, Resolution { def: PerNs::macros(macro_), import: None })], 221 &[(name, Resolution { def: PerNs::macros(macro_), import: false })],
222 ); 222 );
223 } 223 }
224 } 224 }
225 225
226 /// Define a legacy textual scoped macro in module 226 /// Define a legacy textual scoped macro in module
227 /// 227 ///
228 /// We use a map `legacy_macros` to store all legacy textual scoped macros visable per module. 228 /// We use a map `legacy_macros` to store all legacy textual scoped macros visible per module.
229 /// It will clone all macros from parent legacy scope, whose definition is prior to 229 /// It will clone all macros from parent legacy scope, whose definition is prior to
230 /// the definition of current module. 230 /// the definition of current module.
231 /// And also, `macro_use` on a module will import all legacy macros visable inside to 231 /// And also, `macro_use` on a module will import all legacy macros visible inside to
232 /// current legacy scope, with possible shadowing. 232 /// current legacy scope, with possible shadowing.
233 fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, macro_: MacroDefId) { 233 fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroDefId) {
234 // Always shadowing 234 // Always shadowing
235 self.def_map.modules[module_id].scope.legacy_macros.insert(name, macro_); 235 self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
236 } 236 }
237 237
238 /// Import macros from `#[macro_use] extern crate`. 238 /// Import macros from `#[macro_use] extern crate`.
@@ -371,11 +371,7 @@ where
371 let scope = &item_map[m.local_id].scope; 371 let scope = &item_map[m.local_id].scope;
372 372
373 // Module scoped macros is included 373 // Module scoped macros is included
374 let items = scope 374 let items = scope.collect_resolutions();
375 .items
376 .iter()
377 .map(|(name, res)| (name.clone(), res.clone()))
378 .collect::<Vec<_>>();
379 375
380 self.update(module_id, Some(import_id), &items); 376 self.update(module_id, Some(import_id), &items);
381 } else { 377 } else {
@@ -385,11 +381,7 @@ where
385 let scope = &self.def_map[m.local_id].scope; 381 let scope = &self.def_map[m.local_id].scope;
386 382
387 // Module scoped macros is included 383 // Module scoped macros is included
388 let items = scope 384 let items = scope.collect_resolutions();
389 .items
390 .iter()
391 .map(|(name, res)| (name.clone(), res.clone()))
392 .collect::<Vec<_>>();
393 385
394 self.update(module_id, Some(import_id), &items); 386 self.update(module_id, Some(import_id), &items);
395 // record the glob import in case we add further items 387 // record the glob import in case we add further items
@@ -406,14 +398,14 @@ where
406 let resolutions = enum_data 398 let resolutions = enum_data
407 .variants 399 .variants
408 .iter() 400 .iter()
409 .filter_map(|(local_id, variant_data)| { 401 .map(|(local_id, variant_data)| {
410 let name = variant_data.name.clone(); 402 let name = variant_data.name.clone();
411 let variant = EnumVariantId { parent: e, local_id }; 403 let variant = EnumVariantId { parent: e, local_id };
412 let res = Resolution { 404 let res = Resolution {
413 def: PerNs::both(variant.into(), variant.into()), 405 def: PerNs::both(variant.into(), variant.into()),
414 import: Some(import_id), 406 import: true,
415 }; 407 };
416 Some((name, res)) 408 (name, res)
417 }) 409 })
418 .collect::<Vec<_>>(); 410 .collect::<Vec<_>>();
419 self.update(module_id, Some(import_id), &resolutions); 411 self.update(module_id, Some(import_id), &resolutions);
@@ -438,7 +430,7 @@ where
438 } 430 }
439 } 431 }
440 432
441 let resolution = Resolution { def, import: Some(import_id) }; 433 let resolution = Resolution { def, import: true };
442 self.update(module_id, Some(import_id), &[(name, resolution)]); 434 self.update(module_id, Some(import_id), &[(name, resolution)]);
443 } 435 }
444 None => tested_by!(bogus_paths), 436 None => tested_by!(bogus_paths),
@@ -449,7 +441,7 @@ where
449 fn update( 441 fn update(
450 &mut self, 442 &mut self,
451 module_id: LocalModuleId, 443 module_id: LocalModuleId,
452 import: Option<LocalImportId>, 444 import: Option<raw::Import>,
453 resolutions: &[(Name, Resolution)], 445 resolutions: &[(Name, Resolution)],
454 ) { 446 ) {
455 self.update_recursive(module_id, import, resolutions, 0) 447 self.update_recursive(module_id, import, resolutions, 0)
@@ -458,7 +450,7 @@ where
458 fn update_recursive( 450 fn update_recursive(
459 &mut self, 451 &mut self,
460 module_id: LocalModuleId, 452 module_id: LocalModuleId,
461 import: Option<LocalImportId>, 453 import: Option<raw::Import>,
462 resolutions: &[(Name, Resolution)], 454 resolutions: &[(Name, Resolution)],
463 depth: usize, 455 depth: usize,
464 ) { 456 ) {
@@ -466,34 +458,10 @@ where
466 // prevent stack overflows (but this shouldn't be possible) 458 // prevent stack overflows (but this shouldn't be possible)
467 panic!("infinite recursion in glob imports!"); 459 panic!("infinite recursion in glob imports!");
468 } 460 }
469 let module_items = &mut self.def_map.modules[module_id].scope; 461 let scope = &mut self.def_map.modules[module_id].scope;
470 let mut changed = false; 462 let mut changed = false;
471 for (name, res) in resolutions { 463 for (name, res) in resolutions {
472 let existing = module_items.items.entry(name.clone()).or_default(); 464 changed |= scope.push_res(name.clone(), res, import.is_some());
473
474 if existing.def.types.is_none() && res.def.types.is_some() {
475 existing.def.types = res.def.types;
476 existing.import = import.or(res.import);
477 changed = true;
478 }
479 if existing.def.values.is_none() && res.def.values.is_some() {
480 existing.def.values = res.def.values;
481 existing.import = import.or(res.import);
482 changed = true;
483 }
484 if existing.def.macros.is_none() && res.def.macros.is_some() {
485 existing.def.macros = res.def.macros;
486 existing.import = import.or(res.import);
487 changed = true;
488 }
489
490 if existing.def.is_none()
491 && res.def.is_none()
492 && existing.import.is_none()
493 && res.import.is_some()
494 {
495 existing.import = res.import;
496 }
497 } 465 }
498 466
499 if !changed { 467 if !changed {
@@ -661,11 +629,14 @@ where
661 krate: self.def_collector.def_map.krate, 629 krate: self.def_collector.def_map.krate,
662 local_id: self.module_id, 630 local_id: self.module_id,
663 }; 631 };
632 let container = ContainerId::ModuleId(module);
664 let ast_id = self.raw_items[imp].ast_id; 633 let ast_id = self.raw_items[imp].ast_id;
665 let impl_id = 634 let impl_id =
666 ImplLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 635 ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
667 .intern(self.def_collector.db); 636 .intern(self.def_collector.db);
668 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) 637 self.def_collector.def_map.modules[self.module_id]
638 .scope
639 .define_impl(impl_id)
669 } 640 }
670 } 641 }
671 } 642 }
@@ -739,13 +710,15 @@ where
739 let res = modules.alloc(ModuleData::default()); 710 let res = modules.alloc(ModuleData::default());
740 modules[res].parent = Some(self.module_id); 711 modules[res].parent = Some(self.module_id);
741 modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration); 712 modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration);
742 modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); 713 for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() {
714 modules[res].scope.define_legacy_macro(name, mac)
715 }
743 modules[self.module_id].children.insert(name.clone(), res); 716 modules[self.module_id].children.insert(name.clone(), res);
744 let resolution = Resolution { 717 let resolution = Resolution {
745 def: PerNs::types( 718 def: PerNs::types(
746 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), 719 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(),
747 ), 720 ),
748 import: None, 721 import: false,
749 }; 722 };
750 self.def_collector.update(self.module_id, None, &[(name, resolution)]); 723 self.def_collector.update(self.module_id, None, &[(name, resolution)]);
751 res 724 res
@@ -760,10 +733,11 @@ where
760 self.collect_derives(attrs, def); 733 self.collect_derives(attrs, def);
761 734
762 let name = def.name.clone(); 735 let name = def.name.clone();
736 let container = ContainerId::ModuleId(module);
763 let def: PerNs = match def.kind { 737 let def: PerNs = match def.kind {
764 raw::DefKind::Function(ast_id) => { 738 raw::DefKind::Function(ast_id) => {
765 let def = FunctionLoc { 739 let def = FunctionLoc {
766 container: ContainerId::ModuleId(module), 740 container: container.into(),
767 ast_id: AstId::new(self.file_id, ast_id), 741 ast_id: AstId::new(self.file_id, ast_id),
768 } 742 }
769 .intern(self.def_collector.db); 743 .intern(self.def_collector.db);
@@ -771,23 +745,23 @@ where
771 PerNs::values(def.into()) 745 PerNs::values(def.into())
772 } 746 }
773 raw::DefKind::Struct(ast_id) => { 747 raw::DefKind::Struct(ast_id) => {
774 let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 748 let def = StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
775 .intern(self.def_collector.db); 749 .intern(self.def_collector.db);
776 PerNs::both(def.into(), def.into()) 750 PerNs::both(def.into(), def.into())
777 } 751 }
778 raw::DefKind::Union(ast_id) => { 752 raw::DefKind::Union(ast_id) => {
779 let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 753 let def = UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
780 .intern(self.def_collector.db); 754 .intern(self.def_collector.db);
781 PerNs::both(def.into(), def.into()) 755 PerNs::both(def.into(), def.into())
782 } 756 }
783 raw::DefKind::Enum(ast_id) => { 757 raw::DefKind::Enum(ast_id) => {
784 let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 758 let def = EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
785 .intern(self.def_collector.db); 759 .intern(self.def_collector.db);
786 PerNs::types(def.into()) 760 PerNs::types(def.into())
787 } 761 }
788 raw::DefKind::Const(ast_id) => { 762 raw::DefKind::Const(ast_id) => {
789 let def = ConstLoc { 763 let def = ConstLoc {
790 container: ContainerId::ModuleId(module), 764 container: container.into(),
791 ast_id: AstId::new(self.file_id, ast_id), 765 ast_id: AstId::new(self.file_id, ast_id),
792 } 766 }
793 .intern(self.def_collector.db); 767 .intern(self.def_collector.db);
@@ -795,20 +769,20 @@ where
795 PerNs::values(def.into()) 769 PerNs::values(def.into())
796 } 770 }
797 raw::DefKind::Static(ast_id) => { 771 raw::DefKind::Static(ast_id) => {
798 let def = StaticLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 772 let def = StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
799 .intern(self.def_collector.db); 773 .intern(self.def_collector.db);
800 774
801 PerNs::values(def.into()) 775 PerNs::values(def.into())
802 } 776 }
803 raw::DefKind::Trait(ast_id) => { 777 raw::DefKind::Trait(ast_id) => {
804 let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 778 let def = TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
805 .intern(self.def_collector.db); 779 .intern(self.def_collector.db);
806 780
807 PerNs::types(def.into()) 781 PerNs::types(def.into())
808 } 782 }
809 raw::DefKind::TypeAlias(ast_id) => { 783 raw::DefKind::TypeAlias(ast_id) => {
810 let def = TypeAliasLoc { 784 let def = TypeAliasLoc {
811 container: ContainerId::ModuleId(module), 785 container: container.into(),
812 ast_id: AstId::new(self.file_id, ast_id), 786 ast_id: AstId::new(self.file_id, ast_id),
813 } 787 }
814 .intern(self.def_collector.db); 788 .intern(self.def_collector.db);
@@ -816,7 +790,7 @@ where
816 PerNs::types(def.into()) 790 PerNs::types(def.into())
817 } 791 }
818 }; 792 };
819 let resolution = Resolution { def, import: None }; 793 let resolution = Resolution { def, import: false };
820 self.def_collector.update(self.module_id, None, &[(name, resolution)]) 794 self.def_collector.update(self.module_id, None, &[(name, resolution)])
821 } 795 }
822 796
@@ -902,7 +876,7 @@ where
902 } 876 }
903 877
904 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { 878 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
905 let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone(); 879 let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros();
906 for (name, macro_) in macros { 880 for (name, macro_) in macros {
907 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); 881 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_);
908 } 882 }
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index ecb4d7c03..73dc08745 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -7,24 +7,21 @@
7 7
8use std::{ops::Index, sync::Arc}; 8use std::{ops::Index, sync::Arc};
9 9
10use either::Either;
11use hir_expand::{ 10use hir_expand::{
12 ast_id_map::AstIdMap, 11 ast_id_map::AstIdMap,
13 db::AstDatabase, 12 db::AstDatabase,
14 hygiene::Hygiene, 13 hygiene::Hygiene,
15 name::{AsName, Name}, 14 name::{AsName, Name},
16}; 15};
17use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 16use ra_arena::{impl_arena_id, Arena, RawId};
17use ra_prof::profile;
18use ra_syntax::{ 18use ra_syntax::{
19 ast::{self, AttrsOwner, NameOwner}, 19 ast::{self, AttrsOwner, NameOwner},
20 AstNode, AstPtr, 20 AstNode,
21}; 21};
22use test_utils::tested_by; 22use test_utils::tested_by;
23 23
24use crate::{ 24use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile};
25 attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile,
26 LocalImportId,
27};
28 25
29/// `RawItems` is a set of top-level items in a file (except for impls). 26/// `RawItems` is a set of top-level items in a file (except for impls).
30/// 27///
@@ -33,7 +30,7 @@ use crate::{
33#[derive(Debug, Default, PartialEq, Eq)] 30#[derive(Debug, Default, PartialEq, Eq)]
34pub struct RawItems { 31pub struct RawItems {
35 modules: Arena<Module, ModuleData>, 32 modules: Arena<Module, ModuleData>,
36 imports: Arena<LocalImportId, ImportData>, 33 imports: Arena<Import, ImportData>,
37 defs: Arena<Def, DefData>, 34 defs: Arena<Def, DefData>,
38 macros: Arena<Macro, MacroData>, 35 macros: Arena<Macro, MacroData>,
39 impls: Arena<Impl, ImplData>, 36 impls: Arena<Impl, ImplData>,
@@ -41,35 +38,15 @@ pub struct RawItems {
41 items: Vec<RawItem>, 38 items: Vec<RawItem>,
42} 39}
43 40
44#[derive(Debug, Default, PartialEq, Eq)]
45pub struct ImportSourceMap {
46 map: ArenaMap<LocalImportId, ImportSourcePtr>,
47}
48
49type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
50
51impl ImportSourceMap {
52 pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
53 self.map[import].clone()
54 }
55}
56
57impl RawItems { 41impl RawItems {
58 pub(crate) fn raw_items_query( 42 pub(crate) fn raw_items_query(
59 db: &(impl DefDatabase + AstDatabase), 43 db: &(impl DefDatabase + AstDatabase),
60 file_id: HirFileId, 44 file_id: HirFileId,
61 ) -> Arc<RawItems> { 45 ) -> Arc<RawItems> {
62 db.raw_items_with_source_map(file_id).0 46 let _p = profile("raw_items_query");
63 }
64
65 pub(crate) fn raw_items_with_source_map_query(
66 db: &(impl DefDatabase + AstDatabase),
67 file_id: HirFileId,
68 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
69 let mut collector = RawItemsCollector { 47 let mut collector = RawItemsCollector {
70 raw_items: RawItems::default(), 48 raw_items: RawItems::default(),
71 source_ast_id_map: db.ast_id_map(file_id), 49 source_ast_id_map: db.ast_id_map(file_id),
72 imports: Trace::new(),
73 file_id, 50 file_id,
74 hygiene: Hygiene::new(db, file_id), 51 hygiene: Hygiene::new(db, file_id),
75 }; 52 };
@@ -80,11 +57,8 @@ impl RawItems {
80 collector.process_module(None, item_list); 57 collector.process_module(None, item_list);
81 } 58 }
82 } 59 }
83 let mut raw_items = collector.raw_items; 60 let raw_items = collector.raw_items;
84 let (arena, map) = collector.imports.into_arena_and_map(); 61 Arc::new(raw_items)
85 raw_items.imports = arena;
86 let source_map = ImportSourceMap { map };
87 (Arc::new(raw_items), Arc::new(source_map))
88 } 62 }
89 63
90 pub(super) fn items(&self) -> &[RawItem] { 64 pub(super) fn items(&self) -> &[RawItem] {
@@ -99,9 +73,9 @@ impl Index<Module> for RawItems {
99 } 73 }
100} 74}
101 75
102impl Index<LocalImportId> for RawItems { 76impl Index<Import> for RawItems {
103 type Output = ImportData; 77 type Output = ImportData;
104 fn index(&self, idx: LocalImportId) -> &ImportData { 78 fn index(&self, idx: Import) -> &ImportData {
105 &self.imports[idx] 79 &self.imports[idx]
106 } 80 }
107} 81}
@@ -136,7 +110,7 @@ pub(super) struct RawItem {
136#[derive(Debug, PartialEq, Eq, Clone, Copy)] 110#[derive(Debug, PartialEq, Eq, Clone, Copy)]
137pub(super) enum RawItemKind { 111pub(super) enum RawItemKind {
138 Module(Module), 112 Module(Module),
139 Import(LocalImportId), 113 Import(Import),
140 Def(Def), 114 Def(Def),
141 Macro(Macro), 115 Macro(Macro),
142 Impl(Impl), 116 Impl(Impl),
@@ -152,6 +126,10 @@ pub(super) enum ModuleData {
152 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, 126 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
153} 127}
154 128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
130pub(crate) struct Import(RawId);
131impl_arena_id!(Import);
132
155#[derive(Debug, Clone, PartialEq, Eq)] 133#[derive(Debug, Clone, PartialEq, Eq)]
156pub struct ImportData { 134pub struct ImportData {
157 pub(super) path: ModPath, 135 pub(super) path: ModPath,
@@ -223,7 +201,6 @@ pub(super) struct ImplData {
223 201
224struct RawItemsCollector { 202struct RawItemsCollector {
225 raw_items: RawItems, 203 raw_items: RawItems,
226 imports: Trace<LocalImportId, ImportData, ImportSourcePtr>,
227 source_ast_id_map: Arc<AstIdMap>, 204 source_ast_id_map: Arc<AstIdMap>,
228 file_id: HirFileId, 205 file_id: HirFileId,
229 hygiene: Hygiene, 206 hygiene: Hygiene,
@@ -330,7 +307,7 @@ impl RawItemsCollector {
330 ModPath::expand_use_item( 307 ModPath::expand_use_item(
331 InFile { value: use_item, file_id: self.file_id }, 308 InFile { value: use_item, file_id: self.file_id },
332 &self.hygiene, 309 &self.hygiene,
333 |path, use_tree, is_glob, alias| { 310 |path, _use_tree, is_glob, alias| {
334 let import_data = ImportData { 311 let import_data = ImportData {
335 path, 312 path,
336 alias, 313 alias,
@@ -339,11 +316,11 @@ impl RawItemsCollector {
339 is_extern_crate: false, 316 is_extern_crate: false,
340 is_macro_use: false, 317 is_macro_use: false,
341 }; 318 };
342 buf.push((import_data, Either::Left(AstPtr::new(use_tree)))); 319 buf.push(import_data);
343 }, 320 },
344 ); 321 );
345 for (import_data, ptr) in buf { 322 for import_data in buf {
346 self.push_import(current_module, attrs.clone(), import_data, ptr); 323 self.push_import(current_module, attrs.clone(), import_data);
347 } 324 }
348 } 325 }
349 326
@@ -366,12 +343,7 @@ impl RawItemsCollector {
366 is_extern_crate: true, 343 is_extern_crate: true,
367 is_macro_use, 344 is_macro_use,
368 }; 345 };
369 self.push_import( 346 self.push_import(current_module, attrs, import_data);
370 current_module,
371 attrs,
372 import_data,
373 Either::Right(AstPtr::new(&extern_crate)),
374 );
375 } 347 }
376 } 348 }
377 349
@@ -402,14 +374,8 @@ impl RawItemsCollector {
402 self.push_item(current_module, attrs, RawItemKind::Impl(imp)) 374 self.push_item(current_module, attrs, RawItemKind::Impl(imp))
403 } 375 }
404 376
405 fn push_import( 377 fn push_import(&mut self, current_module: Option<Module>, attrs: Attrs, data: ImportData) {
406 &mut self, 378 let import = self.raw_items.imports.alloc(data);
407 current_module: Option<Module>,
408 attrs: Attrs,
409 data: ImportData,
410 source: ImportSourcePtr,
411 ) {
412 let import = self.imports.alloc(|| source, || data);
413 self.push_item(current_module, attrs, RawItemKind::Import(import)) 379 self.push_item(current_module, attrs, RawItemKind::Import(import))
414 } 380 }
415 381
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 61cdd768e..4e968bcc8 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -32,27 +32,22 @@ fn render_crate_def_map(map: &CrateDefMap) -> String {
32 *buf += path; 32 *buf += path;
33 *buf += "\n"; 33 *buf += "\n";
34 34
35 let mut entries = map.modules[module] 35 let mut entries = map.modules[module].scope.collect_resolutions();
36 .scope 36 entries.sort_by_key(|(name, _)| name.clone());
37 .items
38 .iter()
39 .map(|(name, res)| (name, res.def))
40 .collect::<Vec<_>>();
41 entries.sort_by_key(|(name, _)| *name);
42 37
43 for (name, res) in entries { 38 for (name, res) in entries {
44 *buf += &format!("{}:", name); 39 *buf += &format!("{}:", name);
45 40
46 if res.types.is_some() { 41 if res.def.types.is_some() {
47 *buf += " t"; 42 *buf += " t";
48 } 43 }
49 if res.values.is_some() { 44 if res.def.values.is_some() {
50 *buf += " v"; 45 *buf += " v";
51 } 46 }
52 if res.macros.is_some() { 47 if res.def.macros.is_some() {
53 *buf += " m"; 48 *buf += " m";
54 } 49 }
55 if res.is_none() { 50 if res.def.is_none() {
56 *buf += " _"; 51 *buf += " _";
57 } 52 }
58 53
@@ -587,6 +582,6 @@ mod b {
587 ⋮T: v 582 ⋮T: v
588 583
589 ⋮crate::a 584 ⋮crate::a
590 ⋮T: t v 585 ⋮T: t v
591"###); 586"###);
592} 587}
diff --git a/crates/ra_hir_def/src/nameres/tests/incremental.rs b/crates/ra_hir_def/src/nameres/tests/incremental.rs
index 903a22771..ef2e9435c 100644
--- a/crates/ra_hir_def/src/nameres/tests/incremental.rs
+++ b/crates/ra_hir_def/src/nameres/tests/incremental.rs
@@ -116,7 +116,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
116 let events = db.log_executed(|| { 116 let events = db.log_executed(|| {
117 let crate_def_map = db.crate_def_map(krate); 117 let crate_def_map = db.crate_def_map(krate);
118 let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); 118 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
119 assert_eq!(module_data.scope.items.len(), 1); 119 assert_eq!(module_data.scope.collect_resolutions().len(), 1);
120 }); 120 });
121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
122 } 122 }
@@ -126,7 +126,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
126 let events = db.log_executed(|| { 126 let events = db.log_executed(|| {
127 let crate_def_map = db.crate_def_map(krate); 127 let crate_def_map = db.crate_def_map(krate);
128 let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); 128 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
129 assert_eq!(module_data.scope.items.len(), 1); 129 assert_eq!(module_data.scope.collect_resolutions().len(), 1);
130 }); 130 });
131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
132 } 132 }
diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs
index cfa4ecb1a..d104f5993 100644
--- a/crates/ra_hir_def/src/nameres/tests/macros.rs
+++ b/crates/ra_hir_def/src/nameres/tests/macros.rs
@@ -610,7 +610,7 @@ fn expand_derive() {
610 struct Foo; 610 struct Foo;
611 ", 611 ",
612 ); 612 );
613 assert_eq!(map.modules[map.root].impls.len(), 1); 613 assert_eq!(map.modules[map.root].scope.impls().len(), 1);
614} 614}
615 615
616#[test] 616#[test]
@@ -622,5 +622,5 @@ fn expand_multiple_derive() {
622 struct Foo; 622 struct Foo;
623 ", 623 ",
624 ); 624 );
625 assert_eq!(map.modules[map.root].impls.len(), 2); 625 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
626} 626}
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 7302cf0f1..8e1294201 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -135,7 +135,7 @@ impl Path {
135 } 135 }
136 136
137 pub fn type_anchor(&self) -> Option<&TypeRef> { 137 pub fn type_anchor(&self) -> Option<&TypeRef> {
138 self.type_anchor.as_ref().map(|it| &**it) 138 self.type_anchor.as_deref()
139 } 139 }
140 140
141 pub fn segments(&self) -> PathSegments<'_> { 141 pub fn segments(&self) -> PathSegments<'_> {
@@ -257,6 +257,7 @@ macro_rules! __known_path {
257 (std::ops::Try) => {}; 257 (std::ops::Try) => {};
258 (std::ops::Neg) => {}; 258 (std::ops::Neg) => {};
259 (std::ops::Not) => {}; 259 (std::ops::Not) => {};
260 (std::ops::Index) => {};
260 ($path:path) => { 261 ($path:path) => {
261 compile_error!("Please register your known path in the path module") 262 compile_error!("Please register your known path in the path module")
262 }; 263 };
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 2694c0438..83013fed3 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -14,12 +14,13 @@ use crate::{
14 db::DefDatabase,