aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock49
-rw-r--r--crates/ra_assists/src/assists/add_import.rs2
-rw-r--r--crates/ra_hir/src/code_model.rs80
-rw-r--r--crates/ra_hir/src/from_source.rs80
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/source_binder.rs8
-rw-r--r--crates/ra_hir_def/Cargo.toml1
-rw-r--r--crates/ra_hir_def/src/body.rs63
-rw-r--r--crates/ra_hir_def/src/body/lower.rs57
-rw-r--r--crates/ra_hir_def/src/child_by_source.rs97
-rw-r--r--crates/ra_hir_def/src/data.rs12
-rw-r--r--crates/ra_hir_def/src/lib.rs283
-rw-r--r--crates/ra_hir_def/src/marks.rs1
-rw-r--r--crates/ra_hir_def/src/nameres.rs11
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs20
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs5
-rw-r--r--crates/ra_hir_def/src/nameres/tests/globs.rs21
-rw-r--r--crates/ra_hir_def/src/path.rs41
-rw-r--r--crates/ra_hir_def/src/path/lower.rs6
-rw-r--r--crates/ra_hir_def/src/path/lower/lower_use.rs12
-rw-r--r--crates/ra_hir_def/src/resolver.rs19
-rw-r--r--crates/ra_hir_def/src/src.rs82
-rw-r--r--crates/ra_hir_ty/src/display.rs12
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs4
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs12
-rw-r--r--crates/ra_hir_ty/src/lib.rs41
-rw-r--r--crates/ra_hir_ty/src/lower.rs10
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs12
-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/call_info.rs43
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs15
-rw-r--r--crates/ra_ide/src/goto_definition.rs243
-rw-r--r--crates/ra_ide/src/hover.rs19
-rw-r--r--crates/ra_ide/src/inlay_hints.rs26
-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.rs11
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs14
-rw-r--r--crates/ra_mbe/src/tests.rs669
-rw-r--r--crates/ra_parser/src/grammar.rs2
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs3
-rw-r--r--crates/ra_parser/src/lib.rs1
-rw-r--r--crates/ra_parser/src/parser.rs2
-rw-r--r--crates/ra_parser/src/token_set.rs8
-rw-r--r--crates/test_utils/src/lib.rs4
-rw-r--r--docs/user/README.md29
-rw-r--r--xtask/src/lib.rs1
-rw-r--r--xtask/src/main.rs2
51 files changed, 1089 insertions, 1089 deletions
diff --git a/Cargo.lock b/Cargo.lock
index af874945c..3f2cbc8ab 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,7 +614,7 @@ 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
@@ -624,7 +624,7 @@ version = "0.63.1"
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
@@ -957,6 +957,7 @@ name = "ra_hir_def"
957version = "0.1.0" 957version = "0.1.0"
958dependencies = [ 958dependencies = [
959 "anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 959 "anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
960 "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)", 961 "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)", 962 "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)", 963 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1059,7 +1060,7 @@ dependencies = [
1059 "ra_vfs_glob 0.1.0", 1060 "ra_vfs_glob 0.1.0",
1060 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1061 "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)", 1062 "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)", 1063 "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)", 1064 "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)", 1065 "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1065 "test_utils 0.1.0", 1066 "test_utils 0.1.0",
@@ -1107,7 +1108,7 @@ dependencies = [
1107 "ra_cfg 0.1.0", 1108 "ra_cfg 0.1.0",
1108 "ra_db 0.1.0", 1109 "ra_db 0.1.0",
1109 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1110 "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)", 1111 "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)", 1112 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
1112] 1113]
1113 1114
@@ -1123,7 +1124,7 @@ dependencies = [
1123 "rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1124 "rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
1124 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1125 "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)", 1126 "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)", 1127 "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)", 1128 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
1128 "test_utils 0.1.0", 1129 "test_utils 0.1.0",
1129 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1130 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1381,7 +1382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1381dependencies = [ 1382dependencies = [
1382 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1383 "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)", 1384 "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)", 1385 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1385] 1386]
1386 1387
1387[[package]] 1388[[package]]
@@ -1474,7 +1475,7 @@ version = "0.9.0"
1474source = "registry+https://github.com/rust-lang/crates.io-index" 1475source = "registry+https://github.com/rust-lang/crates.io-index"
1475dependencies = [ 1476dependencies = [
1476 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1477 "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)", 1478 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1478] 1479]
1479 1480
1480[[package]] 1481[[package]]
@@ -1484,15 +1485,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1484 1485
1485[[package]] 1486[[package]]
1486name = "serde" 1487name = "serde"
1487version = "1.0.103" 1488version = "1.0.104"
1488source = "registry+https://github.com/rust-lang/crates.io-index" 1489source = "registry+https://github.com/rust-lang/crates.io-index"
1489dependencies = [ 1490dependencies = [
1490 "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1491 "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1491] 1492]
1492 1493
1493[[package]] 1494[[package]]
1494name = "serde_derive" 1495name = "serde_derive"
1495version = "1.0.103" 1496version = "1.0.104"
1496source = "registry+https://github.com/rust-lang/crates.io-index" 1497source = "registry+https://github.com/rust-lang/crates.io-index"
1497dependencies = [ 1498dependencies = [
1498 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1499 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1507,7 +1508,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1507dependencies = [ 1508dependencies = [
1508 "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1509 "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)", 1510 "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)", 1511 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1511] 1512]
1512 1513
1513[[package]] 1514[[package]]
@@ -1527,7 +1528,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1527dependencies = [ 1528dependencies = [
1528 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1529 "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)", 1530 "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)", 1531 "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)", 1532 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
1532] 1533]
1533 1534
@@ -1546,7 +1547,7 @@ name = "smol_str"
1546version = "0.1.15" 1547version = "0.1.15"
1547source = "registry+https://github.com/rust-lang/crates.io-index" 1548source = "registry+https://github.com/rust-lang/crates.io-index"
1548dependencies = [ 1549dependencies = [
1549 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1550 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1550] 1551]
1551 1552
1552[[package]] 1553[[package]]
@@ -1662,7 +1663,7 @@ dependencies = [
1662 "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1663 "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)", 1664 "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)", 1665 "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)", 1666 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1666] 1667]
1667 1668
1668[[package]] 1669[[package]]
@@ -1671,7 +1672,7 @@ version = "0.8.1"
1671source = "registry+https://github.com/rust-lang/crates.io-index" 1672source = "registry+https://github.com/rust-lang/crates.io-index"
1672dependencies = [ 1673dependencies = [
1673 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1674 "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)", 1675 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1675] 1676]
1676 1677
1677[[package]] 1678[[package]]
@@ -1749,7 +1750,7 @@ dependencies = [
1749 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1750 "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)", 1751 "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)", 1752 "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)", 1753 "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)", 1754 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
1754] 1755]
1755 1756
@@ -1816,7 +1817,7 @@ dependencies = [
1816"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" 1817"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" 1818"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" 1819"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" 1820"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" 1821"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" 1822"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" 1823"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
@@ -1903,8 +1904,8 @@ dependencies = [
1903"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 1904"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" 1905"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" 1906"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" 1907"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" 1908"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" 1909"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" 1910"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" 1911"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
diff --git a/crates/ra_assists/src/assists/add_import.rs b/crates/ra_assists/src/assists/add_import.rs
index ceffee9b8..b8752cbad 100644
--- a/crates/ra_assists/src/assists/add_import.rs
+++ b/crates/ra_assists/src/assists/add_import.rs
@@ -590,7 +590,7 @@ fn collect_hir_path_segments(path: &hir::Path) -> Option<Vec<SmolStr>> {
590 } 590 }
591 ps.push(chain.into()); 591 ps.push(chain.into());
592 } 592 }
593 hir::PathKind::Type(_) | hir::PathKind::DollarCrate(_) => return None, 593 hir::PathKind::DollarCrate(_) => return None,
594 } 594 }
595 ps.extend(path.segments().iter().map(|it| it.name.to_string().into())); 595 ps.extend(path.segments().iter().map(|it| it.name.to_string().into()));
596 Some(ps) 596 Some(ps)
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 7850ea9a7..ecf883272 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -11,9 +11,9 @@ use hir_def::{
11 per_ns::PerNs, 11 per_ns::PerNs,
12 resolver::HasResolver, 12 resolver::HasResolver,
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, 14 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId,
15 LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, 15 LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId,
16 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, 16 TraitId, TypeAliasId, TypeParamId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
19 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -269,7 +269,7 @@ pub struct Struct {
269 269
270impl Struct { 270impl Struct {
271 pub fn module(self, db: &impl DefDatabase) -> Module { 271 pub fn module(self, db: &impl DefDatabase) -> Module {
272 Module { id: self.id.lookup(db).container } 272 Module { id: self.id.lookup(db).container.module(db) }
273 } 273 }
274 274
275 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 275 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -290,7 +290,7 @@ impl Struct {
290 } 290 }
291 291
292 pub fn ty(self, db: &impl HirDatabase) -> Type { 292 pub fn ty(self, db: &impl HirDatabase) -> Type {
293 Type::from_def(db, self.id.lookup(db).container.krate, self.id) 293 Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
294 } 294 }
295 295
296 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 296 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
@@ -309,11 +309,11 @@ impl Union {
309 } 309 }
310 310
311 pub fn module(self, db: &impl DefDatabase) -> Module { 311 pub fn module(self, db: &impl DefDatabase) -> Module {
312 Module { id: self.id.lookup(db).container } 312 Module { id: self.id.lookup(db).container.module(db) }
313 } 313 }
314 314
315 pub fn ty(self, db: &impl HirDatabase) -> Type { 315 pub fn ty(self, db: &impl HirDatabase) -> Type {
316 Type::from_def(db, self.id.lookup(db).container.krate, self.id) 316 Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
317 } 317 }
318 318
319 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 319 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
@@ -337,7 +337,7 @@ pub struct Enum {
337 337
338impl Enum { 338impl Enum {
339 pub fn module(self, db: &impl DefDatabase) -> Module { 339 pub fn module(self, db: &impl DefDatabase) -> Module {
340 Module { id: self.id.lookup(db).container } 340 Module { id: self.id.lookup(db).container.module(db) }
341 } 341 }
342 342
343 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 343 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -357,7 +357,7 @@ impl Enum {
357 } 357 }
358 358
359 pub fn ty(self, db: &impl HirDatabase) -> Type { 359 pub fn ty(self, db: &impl HirDatabase) -> Type {
360 Type::from_def(db, self.id.lookup(db).container.krate, self.id) 360 Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
361 } 361 }
362} 362}
363 363
@@ -529,30 +529,6 @@ impl Const {
529 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 529 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
530 db.const_data(self.id).name.clone() 530 db.const_data(self.id).name.clone()
531 } 531 }
532
533 /// The containing impl block, if this is a type alias.
534 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
535 match self.container(db) {
536 Some(Container::ImplBlock(it)) => Some(it),
537 _ => None,
538 }
539 }
540
541 /// The containing trait, if this is a trait type alias definition.
542 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
543 match self.container(db) {
544 Some(Container::Trait(it)) => Some(it),
545 _ => None,
546 }
547 }
548
549 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
550 match self.id.lookup(db).container {
551 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
552 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
553 ContainerId::ModuleId(_) => None,
554 }
555 }
556} 532}
557 533
558#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 534#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -577,7 +553,7 @@ pub struct Trait {
577 553
578impl Trait { 554impl Trait {
579 pub fn module(self, db: &impl DefDatabase) -> Module { 555 pub fn module(self, db: &impl DefDatabase) -> Module {
580 Module { id: self.id.lookup(db).container } 556 Module { id: self.id.lookup(db).container.module(db) }
581 } 557 }
582 558
583 pub fn name(self, db: &impl DefDatabase) -> Name { 559 pub fn name(self, db: &impl DefDatabase) -> Name {
@@ -612,30 +588,6 @@ impl TypeAlias {
612 Some(self.module(db).krate()) 588 Some(self.module(db).krate())
613 } 589 }
614 590
615 /// The containing impl block, if this is a type alias.
616 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
617 match self.container(db) {
618 Some(Container::ImplBlock(it)) => Some(it),
619 _ => None,
620 }
621 }
622
623 /// The containing trait, if this is a trait type alias definition.
624 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
625 match self.container(db) {
626 Some(Container::Trait(it)) => Some(it),
627 _ => None,
628 }
629 }
630
631 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
632 match self.id.lookup(db).container {
633 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
634 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
635 ContainerId::ModuleId(_) => None,
636 }
637 }
638
639 pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { 591 pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> {
640 db.type_alias_data(self.id).type_ref.clone() 592 db.type_alias_data(self.id).type_ref.clone()
641 } 593 }
@@ -654,14 +606,6 @@ pub struct MacroDef {
654 pub(crate) id: MacroDefId, 606 pub(crate) id: MacroDefId,
655} 607}
656 608
657impl MacroDef {}
658
659pub enum Container {
660 Trait(Trait),
661 ImplBlock(ImplBlock),
662}
663impl_froms!(Container: Trait, ImplBlock);
664
665#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 609#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
666pub enum AssocItem { 610pub enum AssocItem {
667 Function(Function), 611 Function(Function),
@@ -810,7 +754,7 @@ impl ImplBlock {
810 let environment = TraitEnvironment::lower(db, &resolver); 754 let environment = TraitEnvironment::lower(db, &resolver);
811 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); 755 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
812 Type { 756 Type {
813 krate: self.id.lookup(db).container.krate, 757 krate: self.id.lookup(db).container.module(db).krate,
814 ty: InEnvironment { value: ty, environment }, 758 ty: InEnvironment { value: ty, environment },
815 } 759 }
816 } 760 }
@@ -824,7 +768,7 @@ impl ImplBlock {
824 } 768 }
825 769
826 pub fn module(&self, db: &impl DefDatabase) -> Module { 770 pub fn module(&self, db: &impl DefDatabase) -> Module {
827 self.id.lookup(db).container.into() 771 self.id.lookup(db).container.module(db).into()
828 } 772 }
829 773
830 pub fn krate(&self, db: &impl DefDatabase) -> Crate { 774 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 7abb4bd75..42ca55fe7 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,8 +1,10 @@
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};
8use ra_syntax::{ 10use ra_syntax::{
@@ -11,14 +13,14 @@ use ra_syntax::{
11}; 13};
12 14
13use crate::{ 15use crate::{
14 db::{AstDatabase, DefDatabase, HirDatabase}, 16 db::{DefDatabase, HirDatabase},
15 Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local, 17 Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local,
16 MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, 18 MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
17}; 19};
18 20
19pub trait FromSource: Sized { 21pub trait FromSource: Sized {
20 type Ast; 22 type Ast;
21 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>; 23 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>;
22} 24}
23 25
24pub trait FromSourceByContainer: Sized { 26pub trait FromSourceByContainer: Sized {
@@ -32,7 +34,7 @@ where
32 T: From<<T as FromSourceByContainer>::Id>, 34 T: From<<T as FromSourceByContainer>::Id>,
33{ 35{
34 type Ast = <T as FromSourceByContainer>::Ast; 36 type Ast = <T as FromSourceByContainer>::Ast;
35 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 37 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] 38 analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY]
37 .get(&src) 39 .get(&src)
38 .copied() 40 .copied()
@@ -64,7 +66,7 @@ from_source_by_container_impls![
64 66
65impl FromSource for MacroDef { 67impl FromSource for MacroDef {
66 type Ast = ast::MacroCall; 68 type Ast = ast::MacroCall;
67 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 69 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> {
68 let kind = MacroDefKind::Declarative; 70 let kind = MacroDefKind::Declarative;
69 71
70 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 72 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
@@ -80,7 +82,7 @@ impl FromSource for MacroDef {
80 82
81impl FromSource for EnumVariant { 83impl FromSource for EnumVariant {
82 type Ast = ast::EnumVariant; 84 type Ast = ast::EnumVariant;
83 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 85 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> {
84 let parent_enum = src.value.parent_enum(); 86 let parent_enum = src.value.parent_enum();
85 let src_enum = InFile { file_id: src.file_id, value: parent_enum }; 87 let src_enum = InFile { file_id: src.file_id, value: parent_enum };
86 let parent_enum = Enum::from_source(db, src_enum)?; 88 let parent_enum = Enum::from_source(db, src_enum)?;
@@ -93,7 +95,7 @@ impl FromSource for EnumVariant {
93 95
94impl FromSource for StructField { 96impl FromSource for StructField {
95 type Ast = FieldSource; 97 type Ast = FieldSource;
96 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 98 fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> {
97 let src = src.as_ref(); 99 let src = src.as_ref();
98 100
99 // FIXME this is buggy 101 // FIXME this is buggy
@@ -212,29 +214,43 @@ impl Module {
212} 214}
213 215
214fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { 216fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap {
215 _analyze_container(db, src).unwrap_or_default() 217 return child_by_source(db, src).unwrap_or_default();
216}
217 218
218fn _analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { 219 fn child_by_source(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> {
219 // FIXME: this doesn't try to handle nested declarations 220 for container in src.value.ancestors().skip(1) {
220 for container in src.value.ancestors().skip(1) { 221 let res = match_ast! {
221 let res = match_ast! { 222 match container {
222 match container { 223 ast::TraitDef(it) => {
223 ast::TraitDef(it) => { 224 let def = Trait::from_source(db, src.with_value(it))?;
224 let c = Trait::from_source(db, src.with_value(it))?; 225 def.id.child_by_source(db)
225 c.id.child_by_source(db) 226 },
226 }, 227 ast::ImplBlock(it) => {
227 ast::ImplBlock(it) => { 228 let def = ImplBlock::from_source(db, src.with_value(it))?;
228 let c = ImplBlock::from_source(db, src.with_value(it))?; 229 def.id.child_by_source(db)
229 c.id.child_by_source(db) 230 },
230 }, 231 ast::FnDef(it) => {
231 _ => { continue }, 232 let def = Function::from_source(db, src.with_value(it))?;
232 } 233 DefWithBodyId::from(def.id)
233 }; 234 .child_by_source(db)
234 return Some(res); 235 },
235 } 236 ast::StaticDef(it) => {
237 let def = Static::from_source(db, src.with_value(it))?;
238 DefWithBodyId::from(def.id)
239 .child_by_source(db)
240 },
241 ast::ConstDef(it) => {
242 let def = Const::from_source(db, src.with_value(it))?;
243 DefWithBodyId::from(def.id)
244 .child_by_source(db)
245 },
246 _ => { continue },
247 }
248 };
249 return Some(res);
250 }
236 251
237 let module_source = ModuleSource::from_child_node(db, src); 252 let module_source = ModuleSource::from_child_node(db, src);
238 let c = Module::from_definition(db, src.with_value(module_source))?; 253 let c = Module::from_definition(db, src.with_value(module_source))?;
239 Some(c.id.child_by_source(db)) 254 Some(c.id.child_by_source(db))
255 }
240} 256}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 2e52a1f5c..7f9aef770 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -39,7 +39,7 @@ mod from_source;
39 39
40pub use crate::{ 40pub use crate::{
41 code_model::{ 41 code_model::{
42 Adt, AssocItem, AttrDef, Const, Container, 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, Import, Local,
44 MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, 44 MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias,
45 TypeParam, Union, VariantDef, 45 TypeParam, Union, VariantDef,
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index d326169b3..b60a6b87e 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -237,7 +237,13 @@ impl SourceAnalyzer {
237 } 237 }
238 238
239 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { 239 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
240 let expr_id = self.expr_id(&field.expr()?)?; 240 let expr_id = match field.expr() {
241 Some(it) => self.expr_id(&it)?,
242 None => {
243 let src = InFile { file_id: self.file_id, value: field };
244 self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?
245 }
246 };
241 self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) 247 self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into())
242 } 248 }
243 249
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/body.rs b/crates/ra_hir_def/src/body.rs
index 7787cb87f..401fe0b9b 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -3,10 +3,13 @@
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};
11use ra_syntax::{ast, AstNode, AstPtr}; 14use ra_syntax::{ast, AstNode, AstPtr};
12use rustc_hash::FxHashMap; 15use rustc_hash::FxHashMap;
@@ -15,15 +18,16 @@ use crate::{
15 db::DefDatabase, 18 db::DefDatabase,
16 expr::{Expr, ExprId, Pat, PatId}, 19 expr::{Expr, ExprId, Pat, PatId},
17 nameres::{BuiltinShadowMode, CrateDefMap}, 20 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::Path, 21 path::{ModPath, Path},
19 src::HasSource, 22 src::HasSource,
20 DefWithBodyId, HasModule, Lookup, ModuleId, 23 DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId,
21}; 24};
22 25
23struct Expander { 26struct Expander {
24 crate_def_map: Arc<CrateDefMap>, 27 crate_def_map: Arc<CrateDefMap>,
25 current_file_id: HirFileId, 28 current_file_id: HirFileId,
26 hygiene: Hygiene, 29 hygiene: Hygiene,
30 ast_id_map: Arc<AstIdMap>,
27 module: ModuleId, 31 module: ModuleId,
28} 32}
29 33
@@ -31,7 +35,8 @@ impl Expander {
31 fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { 35 fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander {
32 let crate_def_map = db.crate_def_map(module.krate); 36 let crate_def_map = db.crate_def_map(module.krate);
33 let hygiene = Hygiene::new(db, current_file_id); 37 let hygiene = Hygiene::new(db, current_file_id);
34 Expander { crate_def_map, current_file_id, hygiene, module } 38 let ast_id_map = db.ast_id_map(current_file_id);
39 Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module }
35 } 40 }
36 41
37 fn enter_expand( 42 fn enter_expand(
@@ -44,7 +49,7 @@ impl Expander {
44 db.ast_id_map(self.current_file_id).ast_id(&macro_call), 49 db.ast_id_map(self.current_file_id).ast_id(&macro_call),
45 ); 50 );
46 51
47 if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { 52 if let Some(path) = macro_call.path().and_then(|path| self.parse_mod_path(path)) {
48 if let Some(def) = self.resolve_path_as_macro(db, &path) { 53 if let Some(def) = self.resolve_path_as_macro(db, &path) {
49 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); 54 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id));
50 let file_id = call_id.as_file(); 55 let file_id = call_id.as_file();
@@ -52,9 +57,14 @@ impl Expander {
52 if let Some(expr) = ast::Expr::cast(node) { 57 if let Some(expr) = ast::Expr::cast(node) {
53 log::debug!("macro expansion {:#?}", expr.syntax()); 58 log::debug!("macro expansion {:#?}", expr.syntax());
54 59
55 let mark = Mark { file_id: self.current_file_id }; 60 let mark = Mark {
61 file_id: self.current_file_id,
62 ast_id_map: mem::take(&mut self.ast_id_map),
63 bomb: DropBomb::new("expansion mark dropped"),
64 };
56 self.hygiene = Hygiene::new(db, file_id); 65 self.hygiene = Hygiene::new(db, file_id);
57 self.current_file_id = file_id; 66 self.current_file_id = file_id;
67 self.ast_id_map = db.ast_id_map(file_id);
58 68
59 return Some((mark, expr)); 69 return Some((mark, expr));
60 } 70 }
@@ -67,10 +77,11 @@ impl Expander {
67 None 77 None
68 } 78 }
69 79
70 fn exit(&mut self, db: &impl DefDatabase, mark: Mark) { 80 fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) {
71 self.hygiene = Hygiene::new(db, mark.file_id); 81 self.hygiene = Hygiene::new(db, mark.file_id);
72 self.current_file_id = mark.file_id; 82 self.current_file_id = mark.file_id;
73 std::mem::forget(mark); 83 self.ast_id_map = mem::take(&mut mark.ast_id_map);
84 mark.bomb.defuse();
74 } 85 }
75 86
76 fn to_source<T>(&self, value: T) -> InFile<T> { 87 fn to_source<T>(&self, value: T) -> InFile<T> {
@@ -81,24 +92,27 @@ impl Expander {
81 Path::from_src(path, &self.hygiene) 92 Path::from_src(path, &self.hygiene)
82 } 93 }
83 94
84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 95 fn parse_mod_path(&mut self, path: ast::Path) -> Option<ModPath> {
96 ModPath::from_src(path, &self.hygiene)
97 }
98
99 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &ModPath) -> Option<MacroDefId> {
85 self.crate_def_map 100 self.crate_def_map
86 .resolve_path(db, self.module.local_id, path.mod_path(), BuiltinShadowMode::Other) 101 .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other)
87 .0 102 .0
88 .take_macros() 103 .take_macros()
89 } 104 }
105
106 fn ast_id<N: AstNode>(&self, item: &N) -> AstId<N> {
107 let file_local_id = self.ast_id_map.ast_id(item);
108 AstId::new(self.current_file_id, file_local_id)
109 }
90} 110}
91 111
92struct Mark { 112struct Mark {
93 file_id: HirFileId, 113 file_id: HirFileId,
94} 114 ast_id_map: Arc<AstIdMap>,
95 115 bomb: DropBomb,
96impl Drop for Mark {
97 fn drop(&mut self) {
98 if !std::thread::panicking() {
99 panic!("dropped mark")
100 }
101 }
102} 116}
103 117
104/// The body of an item (function, const etc.). 118/// The body of an item (function, const etc.).
@@ -115,6 +129,7 @@ pub struct Body {
115 pub params: Vec<PatId>, 129 pub params: Vec<PatId>,
116 /// The `ExprId` of the actual body expression. 130 /// The `ExprId` of the actual body expression.
117 pub body_expr: ExprId, 131 pub body_expr: ExprId,
132 pub defs: Vec<ModuleDefId>,
118} 133}
119 134
120pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; 135pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
@@ -169,7 +184,7 @@ impl Body {
169 } 184 }
170 }; 185 };
171 let expander = Expander::new(db, file_id, module); 186 let expander = Expander::new(db, file_id, module);
172 let (body, source_map) = Body::new(db, expander, params, body); 187 let (body, source_map) = Body::new(db, def, expander, params, body);
173 (Arc::new(body), Arc::new(source_map)) 188 (Arc::new(body), Arc::new(source_map))
174 } 189 }
175 190
@@ -179,11 +194,12 @@ impl Body {
179 194
180 fn new( 195 fn new(
181 db: &impl DefDatabase, 196 db: &impl DefDatabase,
197 def: DefWithBodyId,
182 expander: Expander, 198 expander: Expander,
183 params: Option<ast::ParamList>, 199 params: Option<ast::ParamList>,
184 body: Option<ast::Expr>, 200 body: Option<ast::Expr>,
185 ) -> (Body, BodySourceMap) { 201 ) -> (Body, BodySourceMap) {
186 lower::lower(db, expander, params, body) 202 lower::lower(db, def, expander, params, body)
187 } 203 }
188} 204}
189 205
@@ -213,6 +229,11 @@ impl BodySourceMap {
213 self.expr_map.get(&src).cloned() 229 self.expr_map.get(&src).cloned()
214 } 230 }
215 231
232 pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> {
233 let src = node.map(|it| Either::Right(AstPtr::new(it)));
234 self.expr_map.get(&src).cloned()
235 }
236
216 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> { 237 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> {
217 self.pat_map_back.get(pat).copied() 238 self.pat_map_back.get(pat).copied()
218 } 239 }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 61193b4d8..853e17bae 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,
@@ -466,6 +473,7 @@ where
466 Some(block) => block, 473 Some(block) => block,
467 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), 474 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
468 }; 475 };
476 self.collect_block_items(&block);
469 let statements = block 477 let statements = block
470 .statements() 478 .statements()
471 .map(|s| match s { 479 .map(|s| match s {
@@ -482,6 +490,51 @@ where
482 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 490 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
483 } 491 }
484 492
493 fn collect_block_items(&mut self, block: &ast::Block) {
494 let container = ContainerId::DefWithBodyId(self.def);
495 for item in block.items() {
496 let def: ModuleDefId = match item {
497 ast::ModuleItem::FnDef(def) => {
498 let ast_id = self.expander.ast_id(&def);
499 FunctionLoc { container: container.into(), ast_id }.intern(self.db).into()
500 }
501 ast::ModuleItem::TypeAliasDef(def) => {
502 let ast_id = self.expander.ast_id(&def);
503 TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into()
504 }
505 ast::ModuleItem::ConstDef(def) => {
506 let ast_id = self.expander.ast_id(&def);
507 ConstLoc { container: container.into(), ast_id }.intern(self.db).into()
508 }
509 ast::ModuleItem::StaticDef(def) => {
510 let ast_id = self.expander.ast_id(&def);
511 StaticLoc { container, ast_id }.intern(self.db).into()
512 }
513 ast::ModuleItem::StructDef(def) => {
514 let ast_id = self.expander.ast_id(&def);
515 StructLoc { container, ast_id }.intern(self.db).into()
516 }
517 ast::ModuleItem::EnumDef(def) => {
518 let ast_id = self.expander.ast_id(&def);
519 EnumLoc { container, ast_id }.intern(self.db).into()
520 }
521 ast::ModuleItem::UnionDef(def) => {
522 let ast_id = self.expander.ast_id(&def);
523 UnionLoc { container, ast_id }.intern(self.db).into()
524 }
525 ast::ModuleItem::TraitDef(def) => {
526 let ast_id = self.expander.ast_id(&def);
527 TraitLoc { container, ast_id }.intern(self.db).into()
528 }
529 ast::ModuleItem::ImplBlock(_)
530 | ast::ModuleItem::UseItem(_)
531 | ast::ModuleItem::ExternCrateItem(_)
532 | ast::ModuleItem::Module(_) => continue,
533 };
534 self.body.defs.push(def)
535 }
536 }
537
485 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { 538 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
486 if let Some(block) = expr { 539 if let Some(block) = expr {
487 self.collect_block(block) 540 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..f5a65ad40 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,47 +76,11 @@ 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));
82
83 for &impl_ in module_data.impls.iter() {
120 let src = impl_.lookup(db).source(db); 84 let src = impl_.lookup(db).source(db);
121 res[keys::IMPL].insert(src, impl_) 85 res[keys::IMPL].insert(src, impl_)
122 } 86 }
@@ -125,6 +89,46 @@ impl ChildBySource for ModuleId {
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..14e86936b 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -12,8 +12,8 @@ use 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, FunctionId, FunctionLoc, ImplId, Intern,
16 StaticId, TraitId, TypeAliasId, TypeAliasLoc, 16 Lookup, 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()
@@ -180,7 +180,7 @@ impl ImplData {
180 .map(|item_node| match item_node { 180 .map(|item_node| match item_node {
181 ast::ImplItem::FnDef(it) => { 181 ast::ImplItem::FnDef(it) => {
182 let def = FunctionLoc { 182 let def = FunctionLoc {
183 container: ContainerId::ImplId(id), 183 container: AssocContainerId::ImplId(id),
184 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 184 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
185 } 185 }
186 .intern(db); 186 .intern(db);
@@ -188,7 +188,7 @@ impl ImplData {
188 } 188 }
189 ast::ImplItem::ConstDef(it) => { 189 ast::ImplItem::ConstDef(it) => {
190 let def = ConstLoc { 190 let def = ConstLoc {
191 container: ContainerId::ImplId(id), 191 container: AssocContainerId::ImplId(id),
192 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 192 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
193 } 193 }
194 .intern(db); 194 .intern(db);
@@ -196,7 +196,7 @@ impl ImplData {
196 } 196 }
197 ast::ImplItem::TypeAliasDef(it) => { 197 ast::ImplItem::TypeAliasDef(it) => {
198 let def = TypeAliasLoc { 198 let def = TypeAliasLoc {
199 container: ContainerId::ImplId(id), 199 container: AssocContainerId::ImplId(id),
200 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 200 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
201 } 201 }
202 .intern(db); 202 .intern(db);
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index f085bbe87..8ed1599ff 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -45,7 +45,7 @@ use std::hash::Hash;
45use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; 45use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId};
46use ra_arena::{impl_arena_id, RawId}; 46use ra_arena::{impl_arena_id, RawId};
47use ra_db::{impl_intern_key, salsa, CrateId}; 47use ra_db::{impl_intern_key, salsa, CrateId};
48use ra_syntax::ast; 48use ra_syntax::{ast, AstNode};
49 49
50use crate::builtin_type::BuiltinType; 50use crate::builtin_type::BuiltinType;
51 51
@@ -65,101 +65,57 @@ pub struct ModuleId {
65pub struct LocalModuleId(RawId); 65pub struct LocalModuleId(RawId);
66impl_arena_id!(LocalModuleId); 66impl_arena_id!(LocalModuleId);
67 67
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)] 68#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct FunctionLoc { 69pub struct ItemLoc<N: AstNode> {
74 pub container: ContainerId, 70 pub container: ContainerId,
75 pub ast_id: AstId<ast::FnDef>, 71 pub ast_id: AstId<N>,
76} 72}
77 73
78impl Intern for FunctionLoc { 74#[derive(Debug, Clone, PartialEq, Eq, Hash)]
79 type ID = FunctionId; 75pub struct AssocItemLoc<N: AstNode> {
80 fn intern(self, db: &impl db::DefDatabase) -> FunctionId { 76 pub container: AssocContainerId,
81 db.intern_function(self) 77 pub ast_id: AstId<N>,
82 }
83} 78}
84 79
85impl Lookup for FunctionId { 80macro_rules! impl_intern {
86 type Data = FunctionLoc; 81 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
87 fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc { 82 impl_intern_key!($id);
88 db.lookup_intern_function(*self)
89 }
90}
91 83
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 84 impl Intern for $loc {
93pub struct StructId(salsa::InternId); 85 type ID = $id;
94impl_intern_key!(StructId); 86 fn intern(self, db: &impl db::DefDatabase) -> $id {
87 db.$intern(self)
88 }
89 }
95 90
96#[derive(Debug, Clone, PartialEq, Eq, Hash)] 91 impl Lookup for $id {
97pub struct StructLoc { 92 type Data = $loc;
98 pub container: ModuleId, 93 fn lookup(&self, db: &impl db::DefDatabase) -> $loc {
99 pub ast_id: AstId<ast::StructDef>, 94 db.$lookup(*self)
95 }
96 }
97 };
100} 98}
101 99
102impl Intern for StructLoc { 100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
103 type ID = StructId; 101pub struct FunctionId(salsa::InternId);
104 fn intern(self, db: &impl db::DefDatabase) -> StructId { 102type FunctionLoc = AssocItemLoc<ast::FnDef>;
105 db.intern_struct(self) 103impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
106 }
107}
108 104
109impl Lookup for StructId { 105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
110 type Data = StructLoc; 106pub struct StructId(salsa::InternId);
111 fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { 107type StructLoc = ItemLoc<ast::StructDef>;
112 db.lookup_intern_struct(*self) 108impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
113 }
114}
115 109
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub struct UnionId(salsa::InternId); 111pub struct UnionId(salsa::InternId);
118impl_intern_key!(UnionId); 112pub type UnionLoc = ItemLoc<ast::UnionDef>;
119 113impl_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 114
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141pub struct EnumId(salsa::InternId); 116pub struct EnumId(salsa::InternId);
142impl_intern_key!(EnumId); 117pub type EnumLoc = ItemLoc<ast::EnumDef>;
143 118impl_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 119
164// FIXME: rename to `VariantId`, only enums can ave variants 120// FIXME: rename to `VariantId`, only enums can ave variants
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 121#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -184,122 +140,38 @@ impl_arena_id!(LocalStructFieldId);
184 140
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 141#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub struct ConstId(salsa::InternId); 142pub struct ConstId(salsa::InternId);
187impl_intern_key!(ConstId); 143type ConstLoc = AssocItemLoc<ast::ConstDef>;
188#[derive(Debug, Clone, PartialEq, Eq, Hash)] 144impl_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 145
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 146#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209pub struct StaticId(salsa::InternId); 147pub struct StaticId(salsa::InternId);
210impl_intern_key!(StaticId); 148pub type StaticLoc = ItemLoc<ast::StaticDef>;
211 149impl_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 150
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233pub struct TraitId(salsa::InternId); 152pub struct TraitId(salsa::InternId);
234impl_intern_key!(TraitId); 153pub type TraitLoc = ItemLoc<ast::TraitDef>;
235 154impl_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 155
256#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
257pub struct TypeAliasId(salsa::InternId); 157pub struct TypeAliasId(salsa::InternId);
258impl_intern_key!(TypeAliasId); 158type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>;
259 159impl_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 160
280#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 161#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
281pub struct ImplId(salsa::InternId); 162pub struct ImplId(salsa::InternId);
282impl_intern_key!(ImplId); 163type ImplLoc = ItemLoc<ast::ImplBlock>;
283 164impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
285pub struct ImplLoc {
286 pub container: ModuleId,
287 pub ast_id: AstId<ast::ImplBlock>,
288}
289 165
290impl Intern for ImplLoc { 166#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
291 type ID = ImplId; 167pub struct TypeParamId {
292 fn intern(self, db: &impl db::DefDatabase) -> ImplId { 168 pub parent: GenericDefId,
293 db.intern_impl(self) 169 pub local_id: LocalTypeParamId,
294 }
295} 170}
296 171
297impl Lookup for ImplId { 172#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
298 type Data = ImplLoc; 173pub struct LocalTypeParamId(RawId);
299 fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { 174impl_arena_id!(LocalTypeParamId);
300 db.lookup_intern_impl(*self)
301 }
302}
303 175
304macro_rules! impl_froms { 176macro_rules! impl_froms {
305 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { 177 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
@@ -321,21 +193,18 @@ macro_rules! impl_froms {
321} 193}
322 194
323#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 195#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
324pub struct TypeParamId { 196pub enum ContainerId {
325 pub parent: GenericDefId, 197 ModuleId(ModuleId),
326 pub local_id: LocalTypeParamId, 198 DefWithBodyId(DefWithBodyId),
327} 199}
328 200
329#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 201#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
330pub struct LocalTypeParamId(RawId); 202pub enum AssocContainerId {
331impl_arena_id!(LocalTypeParamId); 203 ContainerId(ContainerId),
332
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
334pub enum ContainerId {
335 ModuleId(ModuleId),
336 ImplId(ImplId), 204 ImplId(ImplId),
337 TraitId(TraitId), 205 TraitId(TraitId),
338} 206}
207impl_froms!(AssocContainerId: ContainerId);
339 208
340/// A Data Type 209/// A Data Type
341#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 210#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -478,33 +347,28 @@ pub trait HasModule {
478 fn module(&self, db: &impl db::DefDatabase) -> ModuleId; 347 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
479} 348}
480 349
481impl HasModule for FunctionLoc { 350impl HasModule for ContainerId {
482 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 351 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
483 match self.container { 352 match *self {
484 ContainerId::ModuleId(it) => it, 353 ContainerId::ModuleId(it) => it,
485 ContainerId::ImplId(it) => it.lookup(db).container, 354 ContainerId::DefWithBodyId(it) => it.module(db),
486 ContainerId::TraitId(it) => it.lookup(db).container,
487 } 355 }
488 } 356 }
489} 357}
490 358
491impl HasModule for TypeAliasLoc { 359impl HasModule for AssocContainerId {
492 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 360 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
493 match self.container { 361 match *self {
494 ContainerId::ModuleId(it) => it, 362 AssocContainerId::ContainerId(it) => it.module(db),
495 ContainerId::ImplId(it) => it.lookup(db).container, 363 AssocContainerId::ImplId(it) => it.lookup(db).container.module(db),
496 ContainerId::TraitId(it) => it.lookup(db).container, 364 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db),
497 } 365 }
498 } 366 }
499} 367}
500 368
501impl HasModule for ConstLoc { 369impl<N: AstNode> HasModule for AssocItemLoc<N> {
502 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 370 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
503 match self.container { 371 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 } 372 }
509} 373}
510 374
@@ -515,6 +379,7 @@ impl HasModule for AdtId {
515 AdtId::UnionId(it) => it.lookup(db).container, 379 AdtId::UnionId(it) => it.lookup(db).container,
516 AdtId::EnumId(it) => it.lookup(db).container, 380 AdtId::EnumId(it) => it.lookup(db).container,
517 } 381 }
382 .module(db)
518 } 383 }
519} 384}
520 385
@@ -533,17 +398,17 @@ impl HasModule for GenericDefId {
533 match self { 398 match self {
534 GenericDefId::FunctionId(it) => it.lookup(db).module(db), 399 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
535 GenericDefId::AdtId(it) => it.module(db), 400 GenericDefId::AdtId(it) => it.module(db),
536 GenericDefId::TraitId(it) => it.lookup(db).container, 401 GenericDefId::TraitId(it) => it.lookup(db).container.module(db),
537 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 402 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
538 GenericDefId::ImplId(it) => it.lookup(db).container, 403 GenericDefId::ImplId(it) => it.lookup(db).container.module(db),
539 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container, 404 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
540 GenericDefId::ConstId(it) => it.lookup(db).module(db), 405 GenericDefId::ConstId(it) => it.lookup(db).module(db),
541 } 406 }
542 } 407 }
543} 408}
544 409
545impl HasModule for StaticLoc { 410impl HasModule for StaticLoc {
546 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 411 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
547 self.container 412 self.container.module(db)
548 } 413 }
549} 414}
diff --git a/crates/ra_hir_def/src/marks.rs b/crates/ra_hir_def/src/marks.rs
index 65239ca0a..457ba4abe 100644
--- a/crates/ra_hir_def/src/marks.rs
+++ b/crates/ra_hir_def/src/marks.rs
@@ -5,6 +5,7 @@ test_utils::marks!(
5 name_res_works_for_broken_modules 5 name_res_works_for_broken_modules
6 can_import_enum_variant 6 can_import_enum_variant
7 glob_enum 7 glob_enum
8 glob_enum_group
8 glob_across_crates 9 glob_across_crates
9 std_prelude 10 std_prelude
10 macro_rules_from_other_crates_are_visible_with_macro_use 11 macro_rules_from_other_crates_are_visible_with_macro_use
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 9aae7e48e..af52fa36e 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -57,9 +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, MacroDefId};
61 ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId,
62};
63use once_cell::sync::Lazy; 61use once_cell::sync::Lazy;
64use ra_arena::Arena; 62use ra_arena::Arena;
65use ra_db::{CrateId, Edition, FileId, FilePosition}; 63use ra_db::{CrateId, Edition, FileId, FilePosition};
@@ -76,7 +74,7 @@ use crate::{
76 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, 74 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
77 path::ModPath, 75 path::ModPath,
78 per_ns::PerNs, 76 per_ns::PerNs,
79 AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, 77 AstId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId,
80}; 78};
81 79
82/// Contains all top-level defs from a macro-expanded crate 80/// Contains all top-level defs from a macro-expanded crate
@@ -176,11 +174,6 @@ pub struct ModuleData {
176 pub impls: Vec<ImplId>, 174 pub impls: Vec<ImplId>,
177} 175}
178 176
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)] 177#[derive(Debug, Default, PartialEq, Eq)]
185pub struct ModuleScope { 178pub struct ModuleScope {
186 items: FxHashMap<Name, Resolution>, 179 items: FxHashMap<Name, Resolution>,
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 8bbf7ffa2..e68bf4868 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -661,9 +661,10 @@ where
661 krate: self.def_collector.def_map.krate, 661 krate: self.def_collector.def_map.krate,
662 local_id: self.module_id, 662 local_id: self.module_id,
663 }; 663 };
664 let container = ContainerId::ModuleId(module);
664 let ast_id = self.raw_items[imp].ast_id; 665 let ast_id = self.raw_items[imp].ast_id;
665 let impl_id = 666 let impl_id =
666 ImplLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 667 ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
667 .intern(self.def_collector.db); 668 .intern(self.def_collector.db);
668 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) 669 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id)
669 } 670 }
@@ -760,10 +761,11 @@ where
760 self.collect_derives(attrs, def); 761 self.collect_derives(attrs, def);
761 762
762 let name = def.name.clone(); 763 let name = def.name.clone();
764 let container = ContainerId::ModuleId(module);
763 let def: PerNs = match def.kind { 765 let def: PerNs = match def.kind {
764 raw::DefKind::Function(ast_id) => { 766 raw::DefKind::Function(ast_id) => {
765 let def = FunctionLoc { 767 let def = FunctionLoc {
766 container: ContainerId::ModuleId(module), 768 container: container.into(),
767 ast_id: AstId::new(self.file_id, ast_id), 769 ast_id: AstId::new(self.file_id, ast_id),
768 } 770 }
769 .intern(self.def_collector.db); 771 .intern(self.def_collector.db);
@@ -771,23 +773,23 @@ where
771 PerNs::values(def.into()) 773 PerNs::values(def.into())
772 } 774 }
773 raw::DefKind::Struct(ast_id) => { 775 raw::DefKind::Struct(ast_id) => {
774 let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 776 let def = StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
775 .intern(self.def_collector.db); 777 .intern(self.def_collector.db);
776 PerNs::both(def.into(), def.into()) 778 PerNs::both(def.into(), def.into())
777 } 779 }
778 raw::DefKind::Union(ast_id) => { 780 raw::DefKind::Union(ast_id) => {
779 let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 781 let def = UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
780 .intern(self.def_collector.db); 782 .intern(self.def_collector.db);
781 PerNs::both(def.into(), def.into()) 783 PerNs::both(def.into(), def.into())
782 } 784 }
783 raw::DefKind::Enum(ast_id) => { 785 raw::DefKind::Enum(ast_id) => {
784 let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 786 let def = EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
785 .intern(self.def_collector.db); 787 .intern(self.def_collector.db);
786 PerNs::types(def.into()) 788 PerNs::types(def.into())
787 } 789 }
788 raw::DefKind::Const(ast_id) => { 790 raw::DefKind::Const(ast_id) => {
789 let def = ConstLoc { 791 let def = ConstLoc {
790 container: ContainerId::ModuleId(module), 792 container: container.into(),
791 ast_id: AstId::new(self.file_id, ast_id), 793 ast_id: AstId::new(self.file_id, ast_id),
792 } 794 }
793 .intern(self.def_collector.db); 795 .intern(self.def_collector.db);
@@ -795,20 +797,20 @@ where
795 PerNs::values(def.into()) 797 PerNs::values(def.into())
796 } 798 }
797 raw::DefKind::Static(ast_id) => { 799 raw::DefKind::Static(ast_id) => {
798 let def = StaticLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 800 let def = StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
799 .intern(self.def_collector.db); 801 .intern(self.def_collector.db);
800 802
801 PerNs::values(def.into()) 803 PerNs::values(def.into())
802 } 804 }
803 raw::DefKind::Trait(ast_id) => { 805 raw::DefKind::Trait(ast_id) => {
804 let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 806 let def = TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
805 .intern(self.def_collector.db); 807 .intern(self.def_collector.db);
806 808
807 PerNs::types(def.into()) 809 PerNs::types(def.into())
808 } 810 }
809 raw::DefKind::TypeAlias(ast_id) => { 811 raw::DefKind::TypeAlias(ast_id) => {
810 let def = TypeAliasLoc { 812 let def = TypeAliasLoc {
811 container: ContainerId::ModuleId(module), 813 container: container.into(),
812 ast_id: AstId::new(self.file_id, ast_id), 814 ast_id: AstId::new(self.file_id, ast_id),
813 } 815 }
814 .intern(self.def_collector.db); 816 .intern(self.def_collector.db);
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 1dbc4f371..2dd779b66 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -145,11 +145,6 @@ impl CrateDefMap {
145 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude 145 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
146 } 146 }
147 } 147 }
148 PathKind::Type(_) => {
149 // This is handled in `infer::infer_path_expr`
150 // The result returned here does not matter
151 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
152 }
153 }; 148 };
154 149
155 for (i, segment) in segments { 150 for (i, segment) in segments {
diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs
index 5b03fe365..5e24cb94d 100644
--- a/crates/ra_hir_def/src/nameres/tests/globs.rs
+++ b/crates/ra_hir_def/src/nameres/tests/globs.rs
@@ -112,3 +112,24 @@ fn glob_enum() {
112 "### 112 "###
113 ); 113 );
114} 114}
115
116#[test]
117fn glob_enum_group() {
118 covers!(glob_enum_group);
119 let map = def_map(
120 "
121 //- /lib.rs
122 enum Foo {
123 Bar, Baz
124 }
125 use self::Foo::{*};
126 ",
127 );
128 assert_snapshot!(map, @r###"
129 â‹®crate
130 â‹®Bar: t v
131 â‹®Baz: t v
132 â‹®Foo: t
133 "###
134 );
135}
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 9e37ac416..00325cd99 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -18,6 +18,18 @@ pub struct ModPath {
18 pub segments: Vec<Name>, 18 pub segments: Vec<Name>,
19} 19}
20 20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub enum PathKind {
23 Plain,
24 /// `self::` is `Super(0)`
25 Super(u8),
26 Crate,
27 /// Absolute path (::foo)
28 Abs,
29 /// `$crate` from macro expansion
30 DollarCrate(CrateId),
31}
32
21impl ModPath { 33impl ModPath {
22 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> { 34 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> {
23 lower::lower_path(path, hygiene).map(|it| it.mod_path) 35 lower::lower_path(path, hygiene).map(|it| it.mod_path)
@@ -70,6 +82,9 @@ impl ModPath {
70 82
71#[derive(Debug, Clone, PartialEq, Eq, Hash)] 83#[derive(Debug, Clone, PartialEq, Eq, Hash)]
72pub struct Path { 84pub struct Path {
85 /// Type based path like `<T>::foo`.
86 /// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`.
87 type_anchor: Option<Box<TypeRef>>,
73 mod_path: ModPath, 88 mod_path: ModPath,
74 /// Invariant: the same len as self.path.segments 89 /// Invariant: the same len as self.path.segments
75 generic_args: Vec<Option<Arc<GenericArgs>>>, 90 generic_args: Vec<Option<Arc<GenericArgs>>>,
@@ -97,19 +112,6 @@ pub enum GenericArg {
97 // or lifetime... 112 // or lifetime...
98} 113}
99 114
100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
101pub enum PathKind {
102 Plain,
103 Super(u8),
104 Crate,
105 // Absolute path
106 Abs,
107 // Type based path like `<T>::foo`
108 Type(Box<TypeRef>),
109 // `$crate` from macro expansion
110 DollarCrate(CrateId),
111}
112
113impl Path { 115impl Path {
114 /// Converts an `ast::Path` to `Path`. Works with use trees. 116 /// Converts an `ast::Path` to `Path`. Works with use trees.
115 /// DEPRECATED: It does not handle `$crate` from macro call. 117 /// DEPRECATED: It does not handle `$crate` from macro call.
@@ -125,18 +127,17 @@ impl Path {
125 127
126 /// Converts an `ast::NameRef` into a single-identifier `Path`. 128 /// Converts an `ast::NameRef` into a single-identifier `Path`.
127 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path { 129 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path {
128 Path { mod_path: name_ref.as_name().into(), generic_args: vec![None] } 130 Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] }
129 }
130
131 /// `true` if this path is just a standalone `self`
132 pub fn is_self(&self) -> bool {
133 self.mod_path.is_self()
134 } 131 }
135 132
136 pub fn kind(&self) -> &PathKind { 133 pub fn kind(&self) -> &PathKind {
137 &self.mod_path.kind 134 &self.mod_path.kind
138 } 135 }
139 136
137 pub fn type_anchor(&self) -> Option<&TypeRef> {
138 self.type_anchor.as_ref().map(|it| &**it)
139 }
140
140 pub fn segments(&self) -> PathSegments<'_> { 141 pub fn segments(&self) -> PathSegments<'_> {
141 PathSegments { 142 PathSegments {
142 segments: self.mod_path.segments.as_slice(), 143 segments: self.mod_path.segments.as_slice(),
@@ -153,6 +154,7 @@ impl Path {
153 return None; 154 return None;
154 } 155 }
155 let res = Path { 156 let res = Path {
157 type_anchor: self.type_anchor.clone(),
156 mod_path: ModPath { 158 mod_path: ModPath {
157 kind: self.mod_path.kind.clone(), 159 kind: self.mod_path.kind.clone(),
158 segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(), 160 segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(),
@@ -225,6 +227,7 @@ impl GenericArgs {
225impl From<Name> for Path { 227impl From<Name> for Path {
226 fn from(name: Name) -> Path { 228 fn from(name: Name) -> Path {
227 Path { 229 Path {
230 type_anchor: None,
228 mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)), 231 mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)),
229 generic_args: vec![None], 232 generic_args: vec![None],
230 } 233 }
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index c71b52d89..62aafd508 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -22,6 +22,7 @@ pub(super) use lower_use::lower_use_tree;
22/// It correctly handles `$crate` based path from macro call. 22/// It correctly handles `$crate` based path from macro call.
23pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { 23pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
24 let mut kind = PathKind::Plain; 24 let mut kind = PathKind::Plain;
25 let mut type_anchor = None;
25 let mut segments = Vec::new(); 26 let mut segments = Vec::new();
26 let mut generic_args = Vec::new(); 27 let mut generic_args = Vec::new();
27 loop { 28 loop {
@@ -63,7 +64,8 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
63 match trait_ref { 64 match trait_ref {
64 // <T>::foo 65 // <T>::foo
65 None => { 66 None => {
66 kind = PathKind::Type(Box::new(self_type)); 67 type_anchor = Some(Box::new(self_type));
68 kind = PathKind::Plain;
67 } 69 }
68 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo 70 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
69 Some(trait_ref) => { 71 Some(trait_ref) => {
@@ -111,7 +113,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
111 segments.reverse(); 113 segments.reverse();
112 generic_args.reverse(); 114 generic_args.reverse();
113 let mod_path = ModPath { kind, segments }; 115 let mod_path = ModPath { kind, segments };
114 return Some(Path { mod_path, generic_args }); 116 return Some(Path { type_anchor, mod_path, generic_args });
115 117
116 fn qualifier(path: &ast::Path) -> Option<ast::Path> { 118 fn qualifier(path: &ast::Path) -> Option<ast::Path> {
117 if let Some(q) = path.qualifier() { 119 if let Some(q) = path.qualifier() {
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs
index 062c02063..3218eaf0a 100644
--- a/crates/ra_hir_def/src/path/lower/lower_use.rs
+++ b/crates/ra_hir_def/src/path/lower/lower_use.rs
@@ -9,6 +9,7 @@ use hir_expand::{
9 name::{AsName, Name}, 9 name::{AsName, Name},
10}; 10};
11use ra_syntax::ast::{self, NameOwner}; 11use ra_syntax::ast::{self, NameOwner};
12use test_utils::tested_by;
12 13
13use crate::path::{ModPath, PathKind}; 14use crate::path::{ModPath, PathKind};
14 15
@@ -34,6 +35,7 @@ pub(crate) fn lower_use_tree(
34 } 35 }
35 } else { 36 } else {
36 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); 37 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name());
38 let is_glob = tree.has_star();
37 if let Some(ast_path) = tree.path() { 39 if let Some(ast_path) = tree.path() {
38 // Handle self in a path. 40 // Handle self in a path.
39 // E.g. `use something::{self, <...>}` 41 // E.g. `use something::{self, <...>}`
@@ -48,11 +50,15 @@ pub(crate) fn lower_use_tree(
48 } 50 }
49 } 51 }
50 if let Some(path) = convert_path(prefix, ast_path, hygiene) { 52 if let Some(path) = convert_path(prefix, ast_path, hygiene) {
51 let is_glob = tree.has_star();
52 cb(path, &tree, is_glob, alias) 53 cb(path, &tree, is_glob, alias)
53 } 54 }
54 // FIXME: report errors somewhere 55 // FIXME: report errors somewhere
55 // We get here if we do 56 // We get here if we do
57 } else if is_glob {
58 tested_by!(glob_enum_group);
59 if let Some(prefix) = prefix {
60 cb(prefix, &tree, is_glob, None)
61 }
56 } 62 }
57 } 63 }
58} 64}
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 2694c0438..af9d194f8 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -17,9 +17,9 @@ use crate::{
17 nameres::{BuiltinShadowMode, CrateDefMap}, 17 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::{ModPath, PathKind}, 18 path::{ModPath, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, 20 AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
21 HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, 21 FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
22 TypeAliasId, TypeParamId, VariantId, 22 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
23}; 23};
24 24
25#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -583,9 +583,18 @@ impl HasResolver for DefWithBodyId {
583impl HasResolver for ContainerId { 583impl HasResolver for ContainerId {
584 fn resolver(self, db: &impl DefDatabase) -> Resolver { 584 fn resolver(self, db: &impl DefDatabase) -> Resolver {
585 match self { 585 match self {
586 ContainerId::TraitId(it) => it.resolver(db),
587 ContainerId::ImplId(it) => it.resolver(db),
588 ContainerId::ModuleId(it) => it.resolver(db), 586 ContainerId::ModuleId(it) => it.resolver(db),
587 ContainerId::DefWithBodyId(it) => it.resolver(db),
588 }
589 }
590}
591
592impl HasResolver for AssocContainerId {
593 fn resolver(self, db: &impl DefDatabase) -> Resolver {
594 match self {
595 AssocContainerId::ContainerId(it) => it.resolver(db),
596 AssocContainerId::TraitId(it) => it.resolver(db),
597 AssocContainerId::ImplId(it) => it.resolver(db),
589 } 598 }
590 } 599 }
591} 600}
diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs
index 20200d1db..499375b80 100644
--- a/crates/ra_hir_def/src/src.rs
+++ b/crates/ra_hir_def/src/src.rs
@@ -2,94 +2,28 @@
2 2
3use hir_expand::InFile; 3use hir_expand::InFile;
4use ra_arena::map::ArenaMap; 4use ra_arena::map::ArenaMap;
5use ra_syntax::ast; 5use ra_syntax::AstNode;
6 6
7use crate::{ 7use crate::{db::DefDatabase, AssocItemLoc, ItemLoc};
8 db::DefDatabase, ConstLoc, EnumLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc,
9 TypeAliasLoc, UnionLoc,
10};
11 8
12pub trait HasSource { 9pub trait HasSource {
13 type Value; 10 type Value;
14 fn source(&self, db: &impl DefDatabase) -> InFile<Self::Value>; 11 fn source(&self, db: &impl DefDatabase) -> InFile<Self::Value>;
15} 12}
16 13
17impl HasSource for FunctionLoc { 14impl<N: AstNode> HasSource for AssocItemLoc<N> {
18 type Value = ast::FnDef; 15 type Value = N;
19 16
20 fn source(&self, db: &impl DefDatabase) -> InFile<ast::FnDef> { 17 fn source(&self, db: &impl DefDatabase) -> InFile<N> {
21 let node = self.ast_id.to_node(db); 18 let node = self.ast_id.to_node(db);
22 InFile::new(self.ast_id.file_id, node) 19 InFile::new(self.ast_id.file_id, node)
23 } 20 }
24} 21}
25 22
26impl HasSource for TypeAliasLoc { 23impl<N: AstNode> HasSource for ItemLoc<N> {
27 type Value = ast::TypeAliasDef; 24 type Value = N;
28 25
29 fn source(&self, db: &impl DefDatabase) -> InFile<ast::TypeAliasDef> { 26 fn source(&self, db: &impl DefDatabase) -> InFile<N> {
30 let node = self.ast_id.to_node(db);
31 InFile::new(self.ast_id.file_id, node)
32 }
33}
34
35impl HasSource for ConstLoc {
36 type Value = ast::ConstDef;
37
38 fn source(&self, db: &impl DefDatabase) -> InFile<ast::ConstDef> {
39 let node = self.ast_id.to_node(db);
40 InFile::new(self.ast_id.file_id, node)
41 }
42}
43
44impl HasSource for StaticLoc {
45 type Value = ast::StaticDef;
46
47 fn source(&self, db: &impl DefDatabase) -> InFile<ast::StaticDef> {
48 let node = self.ast_id.to_node(db);
49 InFile::new(self.ast_id.file_id, node)
50 }
51}
52
53impl HasSource for ImplLoc {
54 type Value = ast::ImplBlock;
55
56 fn source(&self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> {
57 let node = self.ast_id.to_node(db);
58 InFile::new(self.ast_id.file_id, node)
59 }
60}
61
62impl HasSource for TraitLoc {
63 type Value = ast::TraitDef;
64
65 fn source(&self, db: &impl DefDatabase) -> InFile<ast::TraitDef> {
66 let node = self.ast_id.to_node(db);
67 InFile::new(self.ast_id.file_id, node)
68 }
69}
70
71impl HasSource for StructLoc {
72 type Value = ast::StructDef;
73
74 fn source(&self, db: &impl DefDatabase) -> InFile<ast::StructDef> {
75 let node = self.ast_id.to_node(db);
76 InFile::new(self.ast_id.file_id, node)
77 }
78}
79
80impl HasSource for UnionLoc {
81 type Value = ast::UnionDef;
82
83 fn source(&self, db: &impl DefDatabase) -> InFile<ast::UnionDef> {
84 let node = self.ast_id.to_node(db);
85 InFile::new(self.ast_id.file_id, node)
86 }
87}
88
89impl HasSource for EnumLoc {
90 type Value = ast::EnumDef;
91
92 fn source(&self, db: &impl DefDatabase) -> InFile<ast::EnumDef> {
93 let node = self.ast_id.to_node(db); 27 let node = self.ast_id.to_node(db);
94 InFile::new(self.ast_id.file_id, node) 28 InFile::new(self.ast_id.file_id, node)
95 } 29 }
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs
index 9bb3ece6c..dcca1bace 100644
--- a/crates/ra_hir_ty/src/display.rs
+++ b/crates/ra_hir_ty/src/display.rs
@@ -10,6 +10,7 @@ pub struct HirFormatter<'a, 'b, DB> {
10 buf: String, 10 buf: String,
11 curr_size: usize, 11 curr_size: usize,
12 max_size: Option<usize>, 12 max_size: Option<usize>,
13 should_display_default_types: bool,
13} 14}
14 15
15pub trait HirDisplay { 16pub trait HirDisplay {
@@ -19,7 +20,7 @@ pub trait HirDisplay {
19 where 20 where
20 Self: Sized, 21 Self: Sized,
21 { 22 {
22 HirDisplayWrapper(db, self, None) 23 HirDisplayWrapper(db, self, None, true)
23 } 24 }
24 25
25 fn display_truncated<'a, DB>( 26 fn display_truncated<'a, DB>(
@@ -30,7 +31,7 @@ pub trait HirDisplay {
30 where 31 where
31 Self: Sized, 32 Self: Sized,
32 { 33 {
33 HirDisplayWrapper(db, self, max_size) 34 HirDisplayWrapper(db, self, max_size, false)
34 } 35 }
35} 36}
36 37
@@ -72,9 +73,13 @@ where
72 false 73 false
73 } 74 }
74 } 75 }
76
77 pub fn should_display_default_types(&self) -> bool {
78 self.should_display_default_types
79 }
75} 80}
76 81
77pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>); 82pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>, bool);
78 83
79impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> 84impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T>
80where 85where
@@ -88,6 +93,7 @@ where
88 buf: String::with_capacity(20), 93 buf: String::with_capacity(20),
89 curr_size: 0, 94 curr_size: 0,
90 max_size: self.2, 95 max_size: self.2,
96 should_display_default_types: self.3,
91 }) 97 })
92 } 98 }
93} 99}
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 011c6c5c6..8be567917 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -8,7 +8,7 @@ use hir_def::{
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
11 AdtId, ContainerId, Lookup, StructFieldId, 11 AdtId, AssocContainerId, Lookup, StructFieldId,
12}; 12};
13use hir_expand::name::{name, Name}; 13use hir_expand::name::{name, Name};
14use ra_syntax::ast::RangeOp; 14use ra_syntax::ast::RangeOp;
@@ -676,7 +676,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
676 // add obligation for trait implementation, if this is a trait method 676 // add obligation for trait implementation, if this is a trait method
677 match def { 677 match def {
678 CallableDef::FunctionId(f) => { 678 CallableDef::FunctionId(f) => {
679 if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { 679 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db).container {
680 // construct a TraitDef 680 // construct a TraitDef
681 let substs = 681 let substs =
682 a_ty.parameters.prefix(generics(self.db, trait_.into()).len()); 682 a_ty.parameters.prefix(generics(self.db, trait_.into()).len());
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 3bae0ca6c..ffd358367 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -3,9 +3,9 @@
3use std::iter; 3use std::iter;
4 4
5use hir_def::{ 5use hir_def::{
6 path::{Path, PathKind, PathSegment}, 6 path::{Path, PathSegment},
7 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, 7 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
8 AssocItemId, ContainerId, Lookup, 8 AssocContainerId, AssocItemId, Lookup,
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
@@ -32,7 +32,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
32 path: &Path, 32 path: &Path,
33 id: ExprOrPatId, 33 id: ExprOrPatId,
34 ) -> Option<Ty> { 34 ) -> Option<Ty> {
35 let (value, self_subst) = if let PathKind::Type(type_ref) = path.kind() { 35 let (value, self_subst) = if let Some(type_ref) = path.type_anchor() {
36 if path.segments().is_empty() { 36 if path.segments().is_empty() {
37 // This can't actually happen syntax-wise 37 // This can't actually happen syntax-wise
38 return None; 38 return None;
@@ -209,7 +209,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
209 AssocItemId::TypeAliasId(_) => unreachable!(), 209 AssocItemId::TypeAliasId(_) => unreachable!(),
210 }; 210 };
211 let substs = match container { 211 let substs = match container {
212 ContainerId::ImplId(impl_id) => { 212 AssocContainerId::ImplId(impl_id) => {
213 let impl_substs = Substs::build_for_def(self.db, impl_id) 213 let impl_substs = Substs::build_for_def(self.db, impl_id)
214 .fill(iter::repeat_with(|| self.table.new_type_var())) 214 .fill(iter::repeat_with(|| self.table.new_type_var()))
215 .build(); 215 .build();
@@ -221,7 +221,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
221 self.unify(&impl_self_ty, &ty); 221 self.unify(&impl_self_ty, &ty);
222 Some(substs) 222 Some(substs)
223 } 223 }
224 ContainerId::TraitId(trait_) => { 224 AssocContainerId::TraitId(trait_) => {
225 // we're picking this method 225 // we're picking this method
226 let trait_substs = Substs::build_for_def(self.db, trait_) 226 let trait_substs = Substs::build_for_def(self.db, trait_)
227 .push(ty.clone()) 227 .push(ty.clone())
@@ -237,7 +237,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
237 })); 237 }));
238 Some(substs) 238 Some(substs)
239 } 239 }
240 ContainerId::ModuleId(_) => None, 240 AssocContainerId::ContainerId(_) => None,
241 }; 241 };
242 242
243 self.write_assoc_resolution(id, item.into()); 243 self.write_assoc_resolution(id, item.into());
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 3ad913e55..7310ef10d 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -44,8 +44,8 @@ use std::sync::Arc;
44use std::{fmt, iter, mem}; 44use std::{fmt, iter, mem};
45 45
46use hir_def::{ 46use hir_def::{
47 expr::ExprId, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, 47 expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId,
48 Lookup, TraitId, TypeAliasId, 48 HasModule, Lookup, TraitId, TypeAliasId,
49}; 49};
50use hir_expand::name::Name; 50use hir_expand::name::Name;
51use ra_db::{impl_intern_key, salsa, CrateId}; 51use ra_db::{impl_intern_key, salsa, CrateId};
@@ -251,7 +251,7 @@ impl ProjectionTy {
251 251
252 fn trait_(&self, db: &impl HirDatabase) -> TraitId { 252 fn trait_(&self, db: &impl HirDatabase) -> TraitId {
253 match self.associated_ty.lookup(db).container { 253 match self.associated_ty.lookup(db).container {
254 ContainerId::TraitId(it) => it, 254 AssocContainerId::TraitId(it) => it,
255 _ => panic!("projection ty without parent trait"), 255 _ => panic!("projection ty without parent trait"),
256 } 256 }
257 } 257 }
@@ -906,13 +906,44 @@ impl HirDisplay for ApplicationTy {
906 write!(f, "{}", name)?; 906 write!(f, "{}", name)?;
907 if self.parameters.len() > 0 { 907 if self.parameters.len() > 0 {
908 write!(f, "<")?; 908 write!(f, "<")?;
909 f.write_joined(&*self.parameters.0, ", ")?; 909
910 let mut non_default_parameters = Vec::with_capacity(self.parameters.len());
911 let parameters_to_write = if f.should_display_default_types() {
912 self.parameters.0.as_ref()
913 } else {
914 match self
915 .ctor
916 .as_generic_def()
917 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
918 .filter(|defaults| !defaults.is_empty())
919 {
920 Option::None => self.parameters.0.as_ref(),
921 Option::Some(default_parameters) => {
922 for (i, parameter) in self.parameters.into_iter().enumerate() {
923 match (parameter, default_parameters.get(i)) {
924 (&Ty::Unknown, _) | (_, None) => {
925 non_default_parameters.push(parameter.clone())
926 }
927 (_, Some(default_parameter))
928 if parameter != default_parameter =>
929 {
930 non_default_parameters.push(parameter.clone())
931 }
932 _ => (),
933 }
934 }
935 &non_default_parameters
936 }
937 }
938 };
939
940 f.write_joined(parameters_to_write, ", ")?;
910 write!(f, ">")?; 941 write!(f, ">")?;
911 } 942 }
912 } 943 }
913 TypeCtor::AssociatedType(type_alias) => { 944 TypeCtor::AssociatedType(type_alias) => {
914 let trait_ = match type_alias.lookup(f.db).container { 945 let trait_ = match type_alias.lookup(f.db).container {
915 ContainerId::TraitId(it) => it, 946 AssocContainerId::TraitId(it) => it,
916 _ => panic!("not an associated type"), 947 _ => panic!("not an associated type"),
917 }; 948 };
918 let trait_name = f.db.trait_data(trait_).name.clone(); 949 let trait_name = f.db.trait_data(trait_).name.clone();
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index a4ddfc8ef..af3db2e1d 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -11,7 +11,7 @@ use std::sync::Arc;
11use hir_def::{ 11use hir_def::{
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 generics::WherePredicate, 13 generics::WherePredicate,
14 path::{GenericArg, Path, PathKind, PathSegment, PathSegments}, 14 path::{GenericArg, Path, PathSegment, PathSegments},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, 17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
@@ -101,7 +101,7 @@ impl Ty {
101 TypeRef::Path(path) => path, 101 TypeRef::Path(path) => path,
102 _ => return None, 102 _ => return None,
103 }; 103 };
104 if let PathKind::Type(_) = path.kind() { 104 if path.type_anchor().is_some() {
105 return None; 105 return None;
106 } 106 }
107 if path.segments().len() > 1 { 107 if path.segments().len() > 1 {
@@ -202,7 +202,7 @@ impl Ty {
202 202
203 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { 203 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty {
204 // Resolve the path (in type namespace) 204 // Resolve the path (in type namespace)
205 if let PathKind::Type(type_ref) = path.kind() { 205 if let Some(type_ref) = path.type_anchor() {
206 let ty = Ty::from_hir(db, resolver, &type_ref); 206 let ty = Ty::from_hir(db, resolver, &type_ref);
207 return Ty::from_type_relative_path(db, resolver, ty, path.segments()); 207 return Ty::from_type_relative_path(db, resolver, ty, path.segments());
208 } 208 }
@@ -697,8 +697,8 @@ impl CallableDef {
697 pub fn krate(self, db: &impl HirDatabase) -> CrateId { 697 pub fn krate(self, db: &impl HirDatabase) -> CrateId {
698 match self { 698 match self {
699 CallableDef::FunctionId(f) => f.lookup(db).module(db), 699 CallableDef::FunctionId(f) => f.lookup(db).module(db),
700 CallableDef::StructId(s) => s.lookup(db).container, 700 CallableDef::StructId(s) => s.lookup(db).container.module(db),
701 CallableDef::EnumVariantId(e) => e.parent.lookup(db).container, 701 CallableDef::EnumVariantId(e) => e.parent.lookup(db).container.module(db),
702 } 702 }
703 .krate 703 .krate
704 } 704 }
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 848e306e9..92fb4c081 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -6,8 +6,8 @@ use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{ 8use hir_def::{
9 lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocItemId, FunctionId, 9 lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocContainerId,
10 HasModule, ImplId, Lookup, TraitId, 10 AssocItemId, FunctionId, HasModule, ImplId, Lookup, TraitId,
11}; 11};
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use ra_db::CrateId; 13use ra_db::CrateId;
@@ -134,7 +134,7 @@ impl Ty {
134 LangItemTarget::ImplBlockId(it) => Some(it), 134 LangItemTarget::ImplBlockId(it) => Some(it),
135 _ => None, 135 _ => None,
136 }) 136 })
137 .map(|it| it.lookup(db).container.krate) 137 .map(|it| it.lookup(db).container.module(db).krate)
138 .collect(); 138 .collect();
139 Some(res) 139 Some(res)
140 } 140 }
@@ -451,12 +451,12 @@ fn transform_receiver_ty(
451 self_ty: &Canonical<Ty>, 451 self_ty: &Canonical<Ty>,
452) -> Option<Ty> { 452) -> Option<Ty> {
453 let substs = match function_id.lookup(db).container { 453 let substs = match function_id.lookup(db).container {
454 hir_def::ContainerId::TraitId(_) => Substs::build_for_def(db, function_id) 454 AssocContainerId::TraitId(_) => Substs::build_for_def(db, function_id)
455 .push(self_ty.value.clone()) 455 .push(self_ty.value.clone())
456 .fill_with_unknown() 456 .fill_with_unknown()
457 .build(), 457 .build(),
458 hir_def::ContainerId::ImplId(impl_id) => inherent_impl_substs(db, impl_id, &self_ty)?, 458 AssocContainerId::ImplId(impl_id) => inherent_impl_substs(db, impl_id, &self_ty)?,
459 hir_def::ContainerId::ModuleId(_) => unreachable!(), 459 AssocContainerId::ContainerId(_) => unreachable!(),
460 }; 460 };
461 let sig = db.callable_item_signature(function_id.into()); 461 let sig = db.callable_item_signature(function_id.into());
462 Some(sig.params()[0].clone().subst(&substs)) 462 Some(sig.params()[0].clone().subst(&substs))
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index fc21872b2..5eb032d86 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -9,7 +9,9 @@ use chalk_ir::{
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11 11
12use hir_def::{AssocItemId, ContainerId, GenericDefId, ImplId, Lookup, TraitId, TypeAliasId}; 12use hir_def::{
13 AssocContainerId, AssocItemId, GenericDefId, HasModule, ImplId, Lookup, TraitId, TypeAliasId,
14};
13use ra_db::{ 15use ra_db::{
14 salsa::{InternId, InternKey}, 16 salsa::{InternId, InternKey},
15 CrateId, 17 CrateId,
@@ -542,7 +544,7 @@ pub(crate) fn associated_ty_data_query(
542 debug!("associated_ty_data {:?}", id); 544 debug!("associated_ty_data {:?}", id);
543 let type_alias: TypeAliasId = from_chalk(db, id); 545 let type_alias: TypeAliasId = from_chalk(db, id);
544 let trait_ = match type_alias.lookup(db).container { 546 let trait_ = match type_alias.lookup(db).container {
545 ContainerId::TraitId(t) => t, 547 AssocContainerId::TraitId(t) => t,
546 _ => panic!("associated type not in trait"), 548 _ => panic!("associated type not in trait"),
547 }; 549 };
548 let generic_params = generics(db, type_alias.into()); 550 let generic_params = generics(db, type_alias.into());
@@ -591,7 +593,7 @@ pub(crate) fn trait_datum_query(
591 let bound_vars = Substs::bound_vars(&generic_params); 593 let bound_vars = Substs::bound_vars(&generic_params);
592 let flags = chalk_rust_ir::TraitFlags { 594 let flags = chalk_rust_ir::TraitFlags {
593 auto: trait_data.auto, 595 auto: trait_data.auto,
594 upstream: trait_.lookup(db).container.krate != krate, 596 upstream: trait_.lookup(db).container.module(db).krate != krate,
595 non_enumerable: true, 597 non_enumerable: true,
596 coinductive: false, // only relevant for Chalk testing 598 coinductive: false, // only relevant for Chalk testing
597 // FIXME set these flags correctly 599 // FIXME set these flags correctly
@@ -671,7 +673,7 @@ fn impl_block_datum(
671 let bound_vars = Substs::bound_vars(&generic_params); 673 let bound_vars = Substs::bound_vars(&generic_params);
672 let trait_ref = trait_ref.subst(&bound_vars); 674 let trait_ref = trait_ref.subst(&bound_vars);
673 let trait_ = trait_ref.trait_; 675 let trait_ = trait_ref.trait_;
674 let impl_type = if impl_id.lookup(db).container.krate == krate { 676 let impl_type = if impl_id.lookup(db).container.module(db).krate == krate {
675 chalk_rust_ir::ImplType::Local 677 chalk_rust_ir::ImplType::Local
676 } else { 678 } else {
677 chalk_rust_ir::ImplType::External 679 chalk_rust_ir::ImplType::External
@@ -755,7 +757,7 @@ fn type_alias_associated_ty_value(
755) -> Arc<AssociatedTyValue<ChalkIr>> { 757) -> Arc<AssociatedTyValue<ChalkIr>> {
756 let type_alias_data = db.type_alias_data(type_alias); 758 let type_alias_data = db.type_alias_data(type_alias);
757 let impl_id = match type_alias.lookup(db).container { 759 let impl_id = match type_alias.lookup(db).container {
758 ContainerId::ImplId(it) => it, 760 AssocContainerId::ImplId(it) => it,
759 _ => panic!("assoc ty value should be in impl"), 761 _ => panic!("assoc ty value should be in impl"),
760 }; 762 };
761 763
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
index 29799a8cb..0b1806a84 100644
--- a/crates/ra_hir_ty/src/utils.rs
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -9,7 +9,7 @@ use hir_def::{
9 path::Path, 9 path::Path,
10 resolver::{HasResolver, TypeNs}, 10 resolver::{HasResolver, TypeNs},
11 type_ref::TypeRef, 11 type_ref::TypeRef,
12 ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId, 12 AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId,
13}; 13};
14use hir_expand::name::{name, Name}; 14use hir_expand::name::{name, Name};
15 15
@@ -155,8 +155,8 @@ fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option<Generi
155 }; 155 };
156 156
157 match container { 157 match container {
158 ContainerId::ImplId(it) => Some(it.into()), 158 AssocContainerId::ImplId(it) => Some(it.into()),
159 ContainerId::TraitId(it) => Some(it.into()), 159 AssocContainerId::TraitId(it) => Some(it.into()),
160 ContainerId::ModuleId(_) => None, 160 AssocContainerId::ContainerId(_) => None,
161 } 161 }
162} 162}
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index b3c323d38..2c2b6fa48 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -1,24 +1,26 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use ra_db::SourceDatabase; 3use hir::db::AstDatabase;
4use ra_syntax::{ 4use ra_syntax::{
5 algo::ancestors_at_offset,
6 ast::{self, ArgListOwner}, 5 ast::{self, ArgListOwner},
7 match_ast, AstNode, SyntaxNode, TextUnit, 6 match_ast, AstNode, SyntaxNode,
8}; 7};
9use test_utils::tested_by; 8use test_utils::tested_by;
10 9
11use crate::{db::RootDatabase, CallInfo, FilePosition, FunctionSignature}; 10use crate::{
11 db::RootDatabase, expand::descend_into_macros, CallInfo, FilePosition, FunctionSignature,
12};
12 13
13/// Computes parameter information for the given call expression. 14/// Computes parameter information for the given call expression.
14pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { 15pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> {
15 let parse = db.parse(position.file_id); 16 let file = db.parse_or_expand(position.file_id.into())?;
16 let syntax = parse.tree().syntax().clone(); 17 let token = file.token_at_offset(position.offset).next()?;
18 let token = descend_into_macros(db, position.file_id, token);
17 19
18 // Find the calling expression and it's NameRef 20 // Find the calling expression and it's NameRef
19 let calling_node = FnCallNode::with_node(&syntax, position.offset)?; 21 let calling_node = FnCallNode::with_node(&token.value.parent())?;
20 let name_ref = calling_node.name_ref()?; 22 let name_ref = calling_node.name_ref()?;
21 let name_ref = hir::InFile::new(position.file_id.into(), name_ref.syntax()); 23 let name_ref = token.with_value(name_ref.syntax());
22 24
23 let analyzer = hir::SourceAnalyzer::new(db, name_ref, None); 25 let analyzer = hir::SourceAnalyzer::new(db, name_ref, None);
24 let (mut call_info, has_self) = match &calling_node { 26 let (mut call_info, has_self) = match &calling_node {
@@ -93,8 +95,8 @@ enum FnCallNode {
93} 95}
94 96
95impl FnCallNode { 97impl FnCallNode {
96 fn with_node(syntax: &SyntaxNode, offset: TextUnit) -> Option<FnCallNode> { 98 fn with_node(syntax: &SyntaxNode) -> Option<FnCallNode> {
97 ancestors_at_offset(syntax, offset).find_map(|node| { 99 syntax.ancestors().find_map(|node| {
98 match_ast! { 100 match_ast! {
99 match node { 101 match node {
100 ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, 102 ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) },
@@ -589,4 +591,25 @@ fn f() {
589 assert_eq!(info.label(), "foo!()"); 591 assert_eq!(info.label(), "foo!()");
590 assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string())); 592 assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string()));
591 } 593 }
594
595 #[test]
596 fn fn_signature_for_call_in_macro() {
597 let info = call_info(
598 r#"
599 macro_rules! id {
600 ($($tt:tt)*) => { $($tt)* }
601 }
602 fn foo() {
603
604 }
605 id! {
606 fn bar() {
607 foo(<|>);
608 }
609 }
610 "#,
611 );
612
613 assert_eq!(info.label(), "fn foo()");
614 }
592} 615}
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index 6a6b49afd..b9ae67828 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -328,22 +328,23 @@ impl ToNav for hir::AssocItem {
328impl ToNav for hir::Local { 328impl ToNav for hir::Local {
329 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 329 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
330 let src = self.source(db); 330 let src = self.source(db);
331 let (full_range, focus_range) = match src.value { 331 let node = match &src.value {
332 Either::Left(it) => { 332 Either::Left(bind_pat) => {
333 (it.syntax().text_range(), it.name().map(|it| it.syntax().text_range())) 333 bind_pat.name().map_or_else(|| bind_pat.syntax().clone(), |it| it.syntax().clone())
334 } 334 }
335 Either::Right(it) => (it.syntax().text_range(), Some(it.self_kw_token().text_range())), 335 Either::Right(it) => it.syntax().clone(),
336 }; 336 };
337 let full_range = original_range(db, src.with_value(&node));
337 let name = match self.name(db) { 338 let name = match self.name(db) {
338 Some(it) => it.to_string().into(), 339 Some(it) => it.to_string().into(),
339 None => "".into(), 340 None => "".into(),
340 }; 341 };
341 NavigationTarget { 342 NavigationTarget {
342 file_id: src.file_id.original_file(db), 343 file_id: full_range.file_id,
343 name, 344 name,
344 kind: BIND_PAT, 345 kind: BIND_PAT,
345 full_range, 346 full_range: full_range.range,
346 focus_range, 347 focus_range: None,
347 container_name: None, 348 container_name: None,
348 description: None, 349 description: None,
349 docs: None, 350 docs: None,
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index bee8e9df2..9b5744789 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -225,35 +225,40 @@ mod tests {
225 225
226 use crate::mock_analysis::analysis_and_position; 226 use crate::mock_analysis::analysis_and_position;
227 227
228 fn check_goto(fixture: &str, expected: &str) { 228 fn check_goto(fixture: &str, expected: &str, expected_range: &str) {
229 let (analysis, pos) = analysis_and_position(fixture); 229 let (analysis, pos) = analysis_and_position(fixture);
230 230
231 let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info; 231 let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info;
232 assert_eq!(navs.len(), 1); 232 assert_eq!(navs.len(), 1);
233 let nav = navs.pop().unwrap();
234 nav.assert_match(expected);
235 }
236
237 fn check_goto_with_range_content(fixture: &str, expected: &str, expected_range: &str) {
238 let (analysis, pos) = analysis_and_position(fixture);
239 233
240 let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info;
241 assert_eq!(navs.len(), 1);
242 let nav = navs.pop().unwrap(); 234 let nav = navs.pop().unwrap();
243 let file_text = analysis.file_text(pos.file_id).unwrap(); 235 let file_text = analysis.file_text(nav.file_id()).unwrap();
236
237 let mut actual = file_text[nav.full_range()].to_string();
238 if let Some(focus) = nav.focus_range() {
239 actual += "|";
240 actual += &file_text[focus];
241 }
244 242
245 let actual_full_range = &file_text[nav.full_range()]; 243 if !expected_range.contains("...") {
246 let actual_range = &file_text[nav.range()]; 244 test_utils::assert_eq_text!(&actual, expected_range);
245 } else {
246 let mut parts = expected_range.split("...");
247 let prefix = parts.next().unwrap();
248 let suffix = parts.next().unwrap();
249 assert!(
250 actual.starts_with(prefix) && actual.ends_with(suffix),
251 "\nExpected: {}\n Actual: {}\n",
252 expected_range,
253 actual
254 );
255 }
247 256
248 test_utils::assert_eq_text!(
249 &format!("{}|{}", actual_full_range, actual_range),
250 expected_range
251 );
252 nav.assert_match(expected); 257 nav.assert_match(expected);
253 } 258 }
254 259
255 #[test] 260 #[test]
256 fn goto_definition_works_in_items() { 261 fn goto_def_in_items() {
257 check_goto( 262 check_goto(
258 " 263 "
259 //- /lib.rs 264 //- /lib.rs
@@ -261,11 +266,12 @@ mod tests {
261 enum E { X(Foo<|>) } 266 enum E { X(Foo<|>) }
262 ", 267 ",
263 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", 268 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
269 "struct Foo;|Foo",
264 ); 270 );
265 } 271 }
266 272
267 #[test] 273 #[test]
268 fn goto_definition_works_at_start_of_item() { 274 fn goto_def_at_start_of_item() {
269 check_goto( 275 check_goto(
270 " 276 "
271 //- /lib.rs 277 //- /lib.rs
@@ -273,6 +279,7 @@ mod tests {
273 enum E { X(<|>Foo) } 279 enum E { X(<|>Foo) }
274 ", 280 ",
275 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", 281 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
282 "struct Foo;|Foo",
276 ); 283 );
277 } 284 }
278 285
@@ -285,61 +292,65 @@ mod tests {
285 mod a; 292 mod a;
286 mod b; 293 mod b;
287 enum E { X(Foo<|>) } 294 enum E { X(Foo<|>) }
295
288 //- /a.rs 296 //- /a.rs
289 struct Foo; 297 struct Foo;
298
290 //- /b.rs 299 //- /b.rs
291 struct Foo; 300 struct Foo;
292 ", 301 ",
293 "Foo STRUCT_DEF FileId(2) [0; 11) [7; 10)", 302 "Foo STRUCT_DEF FileId(2) [0; 11) [7; 10)",
303 "struct Foo;|Foo",
294 ); 304 );
295 } 305 }
296 306
297 #[test] 307 #[test]
298 fn goto_definition_works_for_module_declaration() { 308 fn goto_def_for_module_declaration() {
299 check_goto( 309 check_goto(
300 " 310 "
301 //- /lib.rs 311 //- /lib.rs
302 mod <|>foo; 312 mod <|>foo;
313
303 //- /foo.rs 314 //- /foo.rs
304 // empty 315 // empty
305 ", 316 ",
306 "foo SOURCE_FILE FileId(2) [0; 10)", 317 "foo SOURCE_FILE FileId(2) [0; 10)",
318 "// empty\n\n",
307 ); 319 );
308 320
309 check_goto( 321 check_goto(
310 " 322 "
311 //- /lib.rs 323 //- /lib.rs
312 mod <|>foo; 324 mod <|>foo;
325
313 //- /foo/mod.rs 326 //- /foo/mod.rs
314 // empty 327 // empty
315 ", 328 ",
316 "foo SOURCE_FILE FileId(2) [0; 10)", 329 "foo SOURCE_FILE FileId(2) [0; 10)",
330 "// empty\n\n",
317 ); 331 );
318 } 332 }
319 333
320 #[test] 334 #[test]
321 fn goto_definition_works_for_macros() { 335 fn goto_def_for_macros() {
322 covers!(goto_definition_works_for_macros); 336 covers!(goto_def_for_macros);
323 check_goto( 337 check_goto(
324 " 338 "
325 //- /lib.rs 339 //- /lib.rs
326 macro_rules! foo { 340 macro_rules! foo { () => { () } }
327 () => {
328 {}
329 };
330 }
331 341
332 fn bar() { 342 fn bar() {
333 <|>foo!(); 343 <|>foo!();
334 } 344 }
335 ", 345 ",
336 "foo MACRO_CALL FileId(1) [0; 50) [13; 16)", 346 "foo MACRO_CALL FileId(1) [0; 33) [13; 16)",
347 "macro_rules! foo { () => { () } }|foo",
337 ); 348 );
338 } 349 }
339 350
340 #[test] 351 #[test]
341 fn goto_definition_works_for_macros_from_other_crates() { 352 fn goto_def_for_macros_from_other_crates() {
342 covers!(goto_definition_works_for_macros); 353 covers!(goto_def_for_macros);
343 check_goto( 354 check_goto(
344 " 355 "
345 //- /lib.rs 356 //- /lib.rs
@@ -350,18 +361,15 @@ mod tests {
350 361
351 //- /foo/lib.rs 362 //- /foo/lib.rs
352 #[macro_export] 363 #[macro_export]
353 macro_rules! foo { 364 macro_rules! foo { () => { () } }
354 () => {
355 {}
356 };
357 }
358 ", 365 ",
359 "foo MACRO_CALL FileId(2) [0; 66) [29; 32)", 366 "foo MACRO_CALL FileId(2) [0; 49) [29; 32)",
367 "#[macro_export]\nmacro_rules! foo { () => { () } }|foo",
360 ); 368 );
361 } 369 }
362 370
363 #[test] 371 #[test]
364 fn goto_definition_works_for_macros_in_use_tree() { 372 fn goto_def_for_macros_in_use_tree() {
365 check_goto( 373 check_goto(
366 " 374 "
367 //- /lib.rs 375 //- /lib.rs
@@ -369,19 +377,16 @@ mod tests {
369 377
370 //- /foo/lib.rs 378 //- /foo/lib.rs
371 #[macro_export] 379 #[macro_export]
372 macro_rules! foo { 380 macro_rules! foo { () => { () } }
373 () => {
374 {}
375 };
376 }
377 ", 381 ",
378 "foo MACRO_CALL FileId(2) [0; 66) [29; 32)", 382 "foo MACRO_CALL FileId(2) [0; 49) [29; 32)",
383 "#[macro_export]\nmacro_rules! foo { () => { () } }|foo",
379 ); 384 );
380 } 385 }
381 386
382 #[test] 387 #[test]
383 fn goto_definition_works_for_macro_defined_fn_with_arg() { 388 fn goto_def_for_macro_defined_fn_with_arg() {
384 check_goto_with_range_content( 389 check_goto(
385 " 390 "
386 //- /lib.rs 391 //- /lib.rs
387 macro_rules! define_fn { 392 macro_rules! define_fn {
@@ -400,8 +405,8 @@ mod tests {
400 } 405 }
401 406
402 #[test] 407 #[test]
403 fn goto_definition_works_for_macro_defined_fn_no_arg() { 408 fn goto_def_for_macro_defined_fn_no_arg() {
404 check_goto_with_range_content( 409 check_goto(
405 " 410 "
406 //- /lib.rs 411 //- /lib.rs
407 macro_rules! define_fn { 412 macro_rules! define_fn {
@@ -420,27 +425,28 @@ mod tests {
420 } 425 }
421 426
422 #[test] 427 #[test]
423 fn goto_definition_works_for_methods() { 428 fn goto_def_for_methods() {
424 covers!(goto_definition_works_for_methods); 429 covers!(goto_def_for_methods);
425 check_goto( 430 check_goto(
426 " 431 "
427 //- /lib.rs 432 //- /lib.rs
428 struct Foo; 433 struct Foo;
429 impl Foo { 434 impl Foo {
430 fn frobnicate(&self) { } 435 fn frobnicate(&self) { }
431 } 436 }
432 437
433 fn bar(foo: &Foo) { 438 fn bar(foo: &Foo) {
434 foo.frobnicate<|>(); 439 foo.frobnicate<|>();
435 } 440 }
436 ", 441 ",
437 "frobnicate FN_DEF FileId(1) [27; 52) [30; 40)", 442 "frobnicate FN_DEF FileId(1) [27; 51) [30; 40)",
443 "fn frobnicate(&self) { }|frobnicate",
438 ); 444 );
439 } 445 }
440 446
441 #[test] 447 #[test]
442 fn goto_definition_works_for_fields() { 448 fn goto_def_for_fields() {
443 covers!(goto_definition_works_for_fields); 449 covers!(goto_def_for_fields);
444 check_goto( 450 check_goto(
445 " 451 "
446 //- /lib.rs 452 //- /lib.rs
@@ -453,12 +459,13 @@ mod tests {
453 } 459 }
454 ", 460 ",
455 "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", 461 "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)",
462 "spam: u32|spam",
456 ); 463 );
457 } 464 }
458 465
459 #[test] 466 #[test]
460 fn goto_definition_works_for_record_fields() { 467 fn goto_def_for_record_fields() {
461 covers!(goto_definition_works_for_record_fields); 468 covers!(goto_def_for_record_fields);
462 check_goto( 469 check_goto(
463 " 470 "
464 //- /lib.rs 471 //- /lib.rs
@@ -473,6 +480,7 @@ mod tests {
473 } 480 }
474 ", 481 ",
475 "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", 482 "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)",
483 "spam: u32|spam",
476 ); 484 );
477 } 485 }
478 486
@@ -489,29 +497,31 @@ mod tests {
489 } 497 }
490 ", 498 ",
491 "TUPLE_FIELD_DEF FileId(1) [11; 14)", 499 "TUPLE_FIELD_DEF FileId(1) [11; 14)",
500 "u32",
492 ); 501 );
493 } 502 }
494 503
495 #[test] 504 #[test]
496 fn goto_definition_works_for_ufcs_inherent_methods() { 505 fn goto_def_for_ufcs_inherent_methods() {
497 check_goto( 506 check_goto(
498 " 507 "
499 //- /lib.rs 508 //- /lib.rs
500 struct Foo; 509 struct Foo;
501 impl Foo { 510 impl Foo {
502 fn frobnicate() { } 511 fn frobnicate() { }
503 } 512 }
504 513
505 fn bar(foo: &Foo) { 514 fn bar(foo: &Foo) {
506 Foo::frobnicate<|>(); 515 Foo::frobnicate<|>();
507 } 516 }
508 ", 517 ",
509 "frobnicate FN_DEF FileId(1) [27; 47) [30; 40)", 518 "frobnicate FN_DEF FileId(1) [27; 46) [30; 40)",
519 "fn frobnicate() { }|frobnicate",
510 ); 520 );
511 } 521 }
512 522
513 #[test] 523 #[test]
514 fn goto_definition_works_for_ufcs_trait_methods_through_traits() { 524 fn goto_def_for_ufcs_trait_methods_through_traits() {
515 check_goto( 525 check_goto(
516 " 526 "
517 //- /lib.rs 527 //- /lib.rs
@@ -524,11 +534,12 @@ mod tests {
524 } 534 }
525 ", 535 ",
526 "frobnicate FN_DEF FileId(1) [16; 32) [19; 29)", 536 "frobnicate FN_DEF FileId(1) [16; 32) [19; 29)",
537 "fn frobnicate();|frobnicate",
527 ); 538 );
528 } 539 }
529 540
530 #[test] 541 #[test]
531 fn goto_definition_works_for_ufcs_trait_methods_through_self() { 542 fn goto_def_for_ufcs_trait_methods_through_self() {
532 check_goto( 543 check_goto(
533 " 544 "
534 //- /lib.rs 545 //- /lib.rs
@@ -543,6 +554,7 @@ mod tests {
543 } 554 }
544 ", 555 ",
545 "frobnicate FN_DEF FileId(1) [30; 46) [33; 43)", 556 "frobnicate FN_DEF FileId(1) [30; 46) [33; 43)",
557 "fn frobnicate();|frobnicate",
546 ); 558 );
547 } 559 }
548 560
@@ -559,6 +571,7 @@ mod tests {
559 } 571 }
560 ", 572 ",
561 "impl IMPL_BLOCK FileId(1) [12; 73)", 573 "impl IMPL_BLOCK FileId(1) [12; 73)",
574 "impl Foo {...}",
562 ); 575 );
563 576
564 check_goto( 577 check_goto(
@@ -572,6 +585,7 @@ mod tests {
572 } 585 }
573 ", 586 ",
574 "impl IMPL_BLOCK FileId(1) [12; 73)", 587 "impl IMPL_BLOCK FileId(1) [12; 73)",
588 "impl Foo {...}",
575 ); 589 );
576 590
577 check_goto( 591 check_goto(
@@ -585,6 +599,7 @@ mod tests {
585 } 599 }
586 ", 600 ",
587 "impl IMPL_BLOCK FileId(1) [15; 75)", 601 "impl IMPL_BLOCK FileId(1) [15; 75)",
602 "impl Foo {...}",
588 ); 603 );
589 604
590 check_goto( 605 check_goto(
@@ -597,6 +612,7 @@ mod tests {
597 } 612 }
598 ", 613 ",
599 "impl IMPL_BLOCK FileId(1) [15; 62)", 614 "impl IMPL_BLOCK FileId(1) [15; 62)",
615 "impl Foo {...}",
600 ); 616 );
601 } 617 }
602 618
@@ -616,6 +632,7 @@ mod tests {
616 } 632 }
617 ", 633 ",
618 "impl IMPL_BLOCK FileId(1) [49; 115)", 634 "impl IMPL_BLOCK FileId(1) [49; 115)",
635 "impl Make for Foo {...}",
619 ); 636 );
620 637
621 check_goto( 638 check_goto(
@@ -632,17 +649,19 @@ mod tests {
632 } 649 }
633 ", 650 ",
634 "impl IMPL_BLOCK FileId(1) [49; 115)", 651 "impl IMPL_BLOCK FileId(1) [49; 115)",
652 "impl Make for Foo {...}",
635 ); 653 );
636 } 654 }
637 655
638 #[test] 656 #[test]
639 fn goto_definition_works_when_used_on_definition_name_itself() { 657 fn goto_def_when_used_on_definition_name_itself() {
640 check_goto( 658 check_goto(
641 " 659 "
642 //- /lib.rs 660 //- /lib.rs
643 struct Foo<|> { value: u32 } 661 struct Foo<|> { value: u32 }
644 ", 662 ",
645 "Foo STRUCT_DEF FileId(1) [0; 25) [7; 10)", 663 "Foo STRUCT_DEF FileId(1) [0; 25) [7; 10)",
664 "struct Foo { value: u32 }|Foo",
646 ); 665 );
647 666
648 check_goto( 667 check_goto(
@@ -653,15 +672,16 @@ mod tests {
653 } 672 }
654 "#, 673 "#,
655 "field RECORD_FIELD_DEF FileId(1) [17; 30) [17; 22)", 674 "field RECORD_FIELD_DEF FileId(1) [17; 30) [17; 22)",
675 "field: string|field",
656 ); 676 );
657 677
658 check_goto( 678 check_goto(
659 " 679 "
660 //- /lib.rs 680 //- /lib.rs
661 fn foo_test<|>() { 681 fn foo_test<|>() { }
662 }
663 ", 682 ",
664 "foo_test FN_DEF FileId(1) [0; 17) [3; 11)", 683 "foo_test FN_DEF FileId(1) [0; 17) [3; 11)",
684 "fn foo_test() { }|foo_test",
665 ); 685 );
666 686
667 check_goto( 687 check_goto(
@@ -672,6 +692,7 @@ mod tests {
672 } 692 }
673 ", 693 ",
674 "Foo ENUM_DEF FileId(1) [0; 25) [5; 8)", 694 "Foo ENUM_DEF FileId(1) [0; 25) [5; 8)",
695 "enum Foo {...}|Foo",
675 ); 696 );
676 697
677 check_goto( 698 check_goto(
@@ -684,22 +705,25 @@ mod tests {
684 } 705 }
685 ", 706 ",
686 "Variant2 ENUM_VARIANT FileId(1) [29; 37) [29; 37)", 707 "Variant2 ENUM_VARIANT FileId(1) [29; 37) [29; 37)",
708 "Variant2|Variant2",
687 ); 709 );
688 710
689 check_goto( 711 check_goto(
690 r#" 712 r#"
691 //- /lib.rs 713 //- /lib.rs
692 static inner<|>: &str = ""; 714 static INNER<|>: &str = "";
693 "#, 715 "#,
694 "inner STATIC_DEF FileId(1) [0; 24) [7; 12)", 716 "INNER STATIC_DEF FileId(1) [0; 24) [7; 12)",
717 "static INNER: &str = \"\";|INNER",
695 ); 718 );
696 719
697 check_goto( 720 check_goto(
698 r#" 721 r#"
699 //- /lib.rs 722 //- /lib.rs
700 const inner<|>: &str = ""; 723 const INNER<|>: &str = "";
701 "#, 724 "#,
702 "inner CONST_DEF FileId(1) [0; 23) [6; 11)", 725 "INNER CONST_DEF FileId(1) [0; 23) [6; 11)",
726 "const INNER: &str = \"\";|INNER",
703 ); 727 );
704 728
705 check_goto( 729 check_goto(
@@ -708,24 +732,25 @@ mod tests {
708 type Thing<|> = Option<()>; 732 type Thing<|> = Option<()>;
709 "#, 733 "#,
710 "Thing TYPE_ALIAS_DEF FileId(1) [0; 24) [5; 10)", 734 "Thing TYPE_ALIAS_DEF FileId(1) [0; 24) [5; 10)",
735 "type Thing = Option<()>;|Thing",
711 ); 736 );
712 737
713 check_goto( 738 check_goto(
714 r#" 739 r#"
715 //- /lib.rs 740 //- /lib.rs
716 trait Foo<|> { 741 trait Foo<|> { }
717 }
718 "#, 742 "#,
719 "Foo TRAIT_DEF FileId(1) [0; 13) [6; 9)", 743 "Foo TRAIT_DEF FileId(1) [0; 13) [6; 9)",
744 "trait Foo { }|Foo",
720 ); 745 );
721 746
722 check_goto( 747 check_goto(
723 r#" 748 r#"
724 //- /lib.rs 749 //- /lib.rs
725 mod bar<|> { 750 mod bar<|> { }
726 }
727 "#, 751 "#,
728 "bar MODULE FileId(1) [0; 11) [4; 7)", 752 "bar MODULE FileId(1) [0; 11) [4; 7)",
753 "mod bar { }|bar",
729 ); 754 );
730 } 755 }
731 756
@@ -746,6 +771,7 @@ mod tests {
746 mod confuse_index { fn foo(); } 771 mod confuse_index { fn foo(); }
747 ", 772 ",
748 "foo FN_DEF FileId(1) [52; 63) [55; 58)", 773 "foo FN_DEF FileId(1) [52; 63) [55; 58)",
774 "fn foo() {}|foo",
749 ); 775 );
750 } 776 }
751 777
@@ -774,6 +800,7 @@ mod tests {
774 } 800 }
775 ", 801 ",
776 "foo FN_DEF FileId(1) [398; 415) [401; 404)", 802 "foo FN_DEF FileId(1) [398; 415) [401; 404)",
803 "fn foo() -> i8 {}|foo",
777 ); 804 );
778 } 805 }
779 806
@@ -787,6 +814,82 @@ mod tests {
787 } 814 }
788 ", 815 ",
789 "T TYPE_PARAM FileId(1) [11; 12)", 816 "T TYPE_PARAM FileId(1) [11; 12)",
817 "T",
790 ); 818 );
791 } 819 }
820
821 #[test]
822 fn goto_within_macro() {
823 check_goto(
824 "
825 //- /lib.rs
826 macro_rules! id {
827 ($($tt:tt)*) => ($($tt)*)
828 }
829
830 fn foo() {
831 let x = 1;
832 id!({
833 let y = <|>x;
834 let z = y;
835 });
836 }
837 ",
838 "x BIND_PAT FileId(1) [69; 70)",
839 "x",
840 );
841
842 check_goto(
843 "
844 //- /lib.rs
845 macro_rules! id {
846 ($($tt:tt)*) => ($($tt)*)
847 }
848
849 fn foo() {
850 let x = 1;
851 id!({
852 let y = x;
853 let z = <|>y;
854 });
855 }
856 ",
857 "y BIND_PAT FileId(1) [98; 99)",
858 "y",
859 );
860 }
861
862 #[test]
863 fn goto_def_in_local_fn() {
864 check_goto(
865 "
866 //- /lib.rs
867 fn main() {
868 fn foo() {
869 let x = 92;
870 <|>x;
871 }
872 }
873 ",
874 "x BIND_PAT FileId(1) [39; 40)",
875 "x",
876 );
877 }
878
879 #[test]
880 fn goto_def_for_field_init_shorthand() {
881 covers!(goto_def_for_field_init_shorthand);
882 check_goto(
883 "
884 //- /lib.rs
885 struct Foo { x: i32 }
886 fn main() {
887 let x = 92;
888 Foo { x<|> };
889 }
890 ",
891 "x RECORD_FIELD_DEF FileId(1) [13; 19) [13; 14)",
892 "x: i32|x",
893 )
894 }
792} 895}
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 51e320128..a227bf546 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -250,7 +250,7 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
250 } else { 250 } else {
251 return None; 251 return None;
252 }; 252 };
253 Some(ty.display(db).to_string()) 253 Some(ty.display_truncated(db, None).to_string())
254} 254}
255 255
256#[cfg(test)] 256#[cfg(test)]
@@ -425,6 +425,23 @@ mod tests {
425 } 425 }
426 426
427 #[test] 427 #[test]
428 fn hover_omits_default_generic_types() {
429 check_hover_result(
430 r#"
431//- /main.rs
432struct Test<K, T = u8> {
433 k: K,
434 t: T,
435}
436
437fn main() {
438 let zz<|> = Test { t: 23, k: 33 };
439}"#,
440 &["Test<i32>"],
441 );
442 }
443
444 #[test]
428 fn hover_some() { 445 fn hover_some() {
429 let (analysis, position) = single_file_with_position( 446 let (analysis, position) = single_file_with_position(
430 " 447 "
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index 3730121af..3154df457 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -160,6 +160,32 @@ mod tests {
160 use crate::mock_analysis::single_file; 160 use crate::mock_analysis::single_file;
161 161
162 #[test] 162 #[test]
163 fn default_generic_types_should_not_be_displayed() {
164 let (analysis, file_id) = single_file(
165 r#"
166struct Test<K, T = u8> {
167 k: K,
168 t: T,
169}
170
171fn main() {
172 let zz = Test { t: 23, k: 33 };
173}"#,
174 );
175
176 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###"
177 [
178 InlayHint {
179 range: [69; 71),
180 kind: TypeHint,