diff options
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" | |||
110 | source = "registry+https://github.com/rust-lang/crates.io-index" | 110 | source = "registry+https://github.com/rust-lang/crates.io-index" |
111 | dependencies = [ | 111 | dependencies = [ |
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]] |
435 | name = "hermit-abi" | 435 | name = "hermit-abi" |
436 | version = "0.1.3" | 436 | version = "0.1.5" |
437 | source = "registry+https://github.com/rust-lang/crates.io-index" | 437 | source = "registry+https://github.com/rust-lang/crates.io-index" |
438 | dependencies = [ | 438 | dependencies = [ |
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" | |||
614 | dependencies = [ | 614 | dependencies = [ |
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" | |||
624 | source = "registry+https://github.com/rust-lang/crates.io-index" | 624 | source = "registry+https://github.com/rust-lang/crates.io-index" |
625 | dependencies = [ | 625 | dependencies = [ |
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" | |||
729 | version = "1.11.1" | 729 | version = "1.11.1" |
730 | source = "registry+https://github.com/rust-lang/crates.io-index" | 730 | source = "registry+https://github.com/rust-lang/crates.io-index" |
731 | dependencies = [ | 731 | dependencies = [ |
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" | |||
957 | version = "0.1.0" | 957 | version = "0.1.0" |
958 | dependencies = [ | 958 | dependencies = [ |
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" | |||
1381 | dependencies = [ | 1382 | dependencies = [ |
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" | |||
1474 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1475 | dependencies = [ | 1476 | dependencies = [ |
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]] |
1486 | name = "serde" | 1487 | name = "serde" |
1487 | version = "1.0.103" | 1488 | version = "1.0.104" |
1488 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1489 | dependencies = [ | 1490 | dependencies = [ |
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]] |
1494 | name = "serde_derive" | 1495 | name = "serde_derive" |
1495 | version = "1.0.103" | 1496 | version = "1.0.104" |
1496 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1497 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1497 | dependencies = [ | 1498 | dependencies = [ |
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" | |||
1507 | dependencies = [ | 1508 | dependencies = [ |
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" | |||
1527 | dependencies = [ | 1528 | dependencies = [ |
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" | |||
1546 | version = "0.1.15" | 1547 | version = "0.1.15" |
1547 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1548 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1548 | dependencies = [ | 1549 | dependencies = [ |
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" | |||
1671 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1672 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1672 | dependencies = [ | 1673 | dependencies = [ |
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 | }; |
18 | use hir_expand::{ | 18 | use hir_expand::{ |
19 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
@@ -269,7 +269,7 @@ pub struct Struct { | |||
269 | 269 | ||
270 | impl Struct { | 270 | impl 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 | ||
338 | impl Enum { | 338 | impl 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 | ||
578 | impl Trait { | 554 | impl 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 | ||
657 | impl MacroDef {} | ||
658 | |||
659 | pub enum Container { | ||
660 | Trait(Trait), | ||
661 | ImplBlock(ImplBlock), | ||
662 | } | ||
663 | impl_froms!(Container: Trait, ImplBlock); | ||
664 | |||
665 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 609 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
666 | pub enum AssocItem { | 610 | pub 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 | |||
2 | use hir_def::{ | 4 | use 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 | }; |
7 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 9 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
8 | use ra_syntax::{ | 10 | use ra_syntax::{ |
@@ -11,14 +13,14 @@ use ra_syntax::{ | |||
11 | }; | 13 | }; |
12 | 14 | ||
13 | use crate::{ | 15 | use 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 | ||
19 | pub trait FromSource: Sized { | 21 | pub 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 | ||
24 | pub trait FromSourceByContainer: Sized { | 26 | pub 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 | ||
65 | impl FromSource for MacroDef { | 67 | impl 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 | ||
81 | impl FromSource for EnumVariant { | 83 | impl 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 | ||
94 | impl FromSource for StructField { | 96 | impl 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 | ||
214 | fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { | 216 | fn 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 | ||
218 | fn _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 | ||
40 | pub use crate::{ | 40 | pub 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" | |||
13 | rustc-hash = "1.0" | 13 | rustc-hash = "1.0" |
14 | either = "1.5" | 14 | either = "1.5" |
15 | anymap = "0.12" | 15 | anymap = "0.12" |
16 | drop_bomb = "0.1.4" | ||
16 | 17 | ||
17 | ra_arena = { path = "../ra_arena" } | 18 | ra_arena = { path = "../ra_arena" } |
18 | ra_db = { path = "../ra_db" } | 19 | ra_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 @@ | |||
3 | mod lower; | 3 | mod lower; |
4 | pub mod scope; | 4 | pub mod scope; |
5 | 5 | ||
6 | use std::{ops::Index, sync::Arc}; | 6 | use std::{mem, ops::Index, sync::Arc}; |
7 | 7 | ||
8 | use drop_bomb::DropBomb; | ||
8 | use either::Either; | 9 | use either::Either; |
9 | use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId}; | 10 | use hir_expand::{ |
11 | ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId, | ||
12 | }; | ||
10 | use ra_arena::{map::ArenaMap, Arena}; | 13 | use ra_arena::{map::ArenaMap, Arena}; |
11 | use ra_syntax::{ast, AstNode, AstPtr}; | 14 | use ra_syntax::{ast, AstNode, AstPtr}; |
12 | use rustc_hash::FxHashMap; | 15 | use 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 | ||
23 | struct Expander { | 26 | struct 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(¯o_call), | 49 | db.ast_id_map(self.current_file_id).ast_id(¯o_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 | ||
92 | struct Mark { | 112 | struct Mark { |
93 | file_id: HirFileId, | 113 | file_id: HirFileId, |
94 | } | 114 | ast_id_map: Arc<AstIdMap>, |
95 | 115 | bomb: DropBomb, | |
96 | impl 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 | ||
120 | pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; | 135 | pub 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 | ||
4 | use either::Either; | 4 | use either::Either; |
5 | |||
5 | use hir_expand::name::{name, AsName, Name}; | 6 | use hir_expand::name::{name, AsName, Name}; |
6 | use ra_arena::Arena; | 7 | use ra_arena::Arena; |
7 | use ra_syntax::{ | 8 | use 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 | ||
29 | pub(super) fn lower( | 32 | pub(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 | ||
49 | struct ExprCollector<DB> { | 55 | struct 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 | ||
18 | pub trait ChildBySource { | 18 | pub 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 | ||
92 | fn 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 | |||
128 | impl ChildBySource for VariantId { | 132 | impl 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 | |||
168 | impl 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; | |||
45 | use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; | 45 | use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; |
46 | use ra_arena::{impl_arena_id, RawId}; | 46 | use ra_arena::{impl_arena_id, RawId}; |
47 | use ra_db::{impl_intern_key, salsa, CrateId}; | 47 | use ra_db::{impl_intern_key, salsa, CrateId}; |
48 | use ra_syntax::ast; | 48 | use ra_syntax::{ast, AstNode}; |
49 | 49 | ||
50 | use crate::builtin_type::BuiltinType; | 50 | use crate::builtin_type::BuiltinType; |
51 | 51 | ||
@@ -65,101 +65,57 @@ pub struct ModuleId { | |||
65 | pub struct LocalModuleId(RawId); | 65 | pub struct LocalModuleId(RawId); |
66 | impl_arena_id!(LocalModuleId); | 66 | impl_arena_id!(LocalModuleId); |
67 | 67 | ||
68 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
69 | pub struct FunctionId(salsa::InternId); | ||
70 | impl_intern_key!(FunctionId); | ||
71 | |||
72 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 68 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
73 | pub struct FunctionLoc { | 69 | pub 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 | ||
78 | impl Intern for FunctionLoc { | 74 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
79 | type ID = FunctionId; | 75 | pub 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 | ||
85 | impl Lookup for FunctionId { | 80 | macro_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 { |
93 | pub struct StructId(salsa::InternId); | 85 | type ID = $id; |
94 | impl_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 { |
97 | pub 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 | ||
102 | impl Intern for StructLoc { | 100 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
103 | type ID = StructId; | 101 | pub struct FunctionId(salsa::InternId); |
104 | fn intern(self, db: &impl db::DefDatabase) -> StructId { | 102 | type FunctionLoc = AssocItemLoc<ast::FnDef>; |
105 | db.intern_struct(self) | 103 | impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); |
106 | } | ||
107 | } | ||
108 | 104 | ||
109 | impl Lookup for StructId { | 105 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
110 | type Data = StructLoc; | 106 | pub struct StructId(salsa::InternId); |
111 | fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { | 107 | type StructLoc = ItemLoc<ast::StructDef>; |
112 | db.lookup_intern_struct(*self) | 108 | impl_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)] |
117 | pub struct UnionId(salsa::InternId); | 111 | pub struct UnionId(salsa::InternId); |
118 | impl_intern_key!(UnionId); | 112 | pub type UnionLoc = ItemLoc<ast::UnionDef>; |
119 | 113 | impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); | |
120 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
121 | pub struct UnionLoc { | ||
122 | pub container: ModuleId, | ||
123 | pub ast_id: AstId<ast::UnionDef>, | ||
124 | } | ||
125 | |||
126 | impl Intern for UnionLoc { | ||
127 | type ID = UnionId; | ||
128 | fn intern(self, db: &impl db::DefDatabase) -> UnionId { | ||
129 | db.intern_union(self) | ||
130 | } | ||
131 | } | ||
132 | |||
133 | impl 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)] |
141 | pub struct EnumId(salsa::InternId); | 116 | pub struct EnumId(salsa::InternId); |
142 | impl_intern_key!(EnumId); | 117 | pub type EnumLoc = ItemLoc<ast::EnumDef>; |
143 | 118 | impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); | |
144 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
145 | pub struct EnumLoc { | ||
146 | pub container: ModuleId, | ||
147 | pub ast_id: AstId<ast::EnumDef>, | ||
148 | } | ||
149 | |||
150 | impl Intern for EnumLoc { | ||
151 | type ID = EnumId; | ||
152 | fn intern(self, db: &impl db::DefDatabase) -> EnumId { | ||
153 | db.intern_enum(self) | ||
154 | } | ||
155 | } | ||
156 | |||
157 | impl 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)] |
186 | pub struct ConstId(salsa::InternId); | 142 | pub struct ConstId(salsa::InternId); |
187 | impl_intern_key!(ConstId); | 143 | type ConstLoc = AssocItemLoc<ast::ConstDef>; |
188 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 144 | impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); |
189 | pub struct ConstLoc { | ||
190 | pub container: ContainerId, | ||
191 | pub ast_id: AstId<ast::ConstDef>, | ||
192 | } | ||
193 | |||
194 | impl Intern for ConstLoc { | ||
195 | type ID = ConstId; | ||
196 | fn intern(self, db: &impl db::DefDatabase) -> ConstId { | ||
197 | db.intern_const(self) | ||
198 | } | ||
199 | } | ||
200 | |||
201 | impl 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)] |
209 | pub struct StaticId(salsa::InternId); | 147 | pub struct StaticId(salsa::InternId); |
210 | impl_intern_key!(StaticId); | 148 | pub type StaticLoc = ItemLoc<ast::StaticDef>; |
211 | 149 | impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); | |
212 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
213 | pub struct StaticLoc { | ||
214 | pub container: ModuleId, | ||
215 | pub ast_id: AstId<ast::StaticDef>, | ||
216 | } | ||
217 | |||
218 | impl Intern for StaticLoc { | ||
219 | type ID = StaticId; | ||
220 | fn intern(self, db: &impl db::DefDatabase) -> StaticId { | ||
221 | db.intern_static(self) | ||
222 | } | ||
223 | } | ||
224 | |||
225 | impl 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)] |
233 | pub struct TraitId(salsa::InternId); | 152 | pub struct TraitId(salsa::InternId); |
234 | impl_intern_key!(TraitId); | 153 | pub type TraitLoc = ItemLoc<ast::TraitDef>; |
235 | 154 | impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); | |
236 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
237 | pub struct TraitLoc { | ||
238 | pub container: ModuleId, | ||
239 | pub ast_id: AstId<ast::TraitDef>, | ||
240 | } | ||
241 | |||
242 | impl Intern for TraitLoc { | ||
243 | type ID = TraitId; | ||
244 | fn intern(self, db: &impl db::DefDatabase) -> TraitId { | ||
245 | db.intern_trait(self) | ||
246 | } | ||
247 | } | ||
248 | |||
249 | impl 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)] |
257 | pub struct TypeAliasId(salsa::InternId); | 157 | pub struct TypeAliasId(salsa::InternId); |
258 | impl_intern_key!(TypeAliasId); | 158 | type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>; |
259 | 159 | impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); | |
260 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
261 | pub struct TypeAliasLoc { | ||
262 | pub container: ContainerId, | ||
263 | pub ast_id: AstId<ast::TypeAliasDef>, | ||
264 | } | ||
265 | |||
266 | impl 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 | |||
273 | impl 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)] |
281 | pub struct ImplId(salsa::InternId); | 162 | pub struct ImplId(salsa::InternId); |
282 | impl_intern_key!(ImplId); | 163 | type ImplLoc = ItemLoc<ast::ImplBlock>; |
283 | 164 | impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); | |
284 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
285 | pub struct ImplLoc { | ||
286 | pub container: ModuleId, | ||
287 | pub ast_id: AstId<ast::ImplBlock>, | ||
288 | } | ||
289 | 165 | ||
290 | impl Intern for ImplLoc { | 166 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
291 | type ID = ImplId; | 167 | pub 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 | ||
297 | impl Lookup for ImplId { | 172 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
298 | type Data = ImplLoc; | 173 | pub struct LocalTypeParamId(RawId); |
299 | fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { | 174 | impl_arena_id!(LocalTypeParamId); |
300 | db.lookup_intern_impl(*self) | ||
301 | } | ||
302 | } | ||
303 | 175 | ||
304 | macro_rules! impl_froms { | 176 | macro_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)] |
324 | pub struct TypeParamId { | 196 | pub 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)] |
330 | pub struct LocalTypeParamId(RawId); | 202 | pub enum AssocContainerId { |
331 | impl_arena_id!(LocalTypeParamId); | 203 | ContainerId(ContainerId), |
332 | |||
333 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
334 | pub enum ContainerId { | ||
335 | ModuleId(ModuleId), | ||
336 | ImplId(ImplId), | 204 | ImplId(ImplId), |
337 | TraitId(TraitId), | 205 | TraitId(TraitId), |
338 | } | 206 | } |
207 | impl_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 | ||
481 | impl HasModule for FunctionLoc { | 350 | impl 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 | ||
491 | impl HasModule for TypeAliasLoc { | 359 | impl 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 | ||
501 | impl HasModule for ConstLoc { | 369 | impl<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 | ||
545 | impl HasModule for StaticLoc { | 410 | impl 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 | ||
58 | use std::sync::Arc; | 58 | use std::sync::Arc; |
59 | 59 | ||
60 | use hir_expand::{ | 60 | use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId}; |
61 | ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId, | ||
62 | }; | ||
63 | use once_cell::sync::Lazy; | 61 | use once_cell::sync::Lazy; |
64 | use ra_arena::Arena; | 62 | use ra_arena::Arena; |
65 | use ra_db::{CrateId, Edition, FileId, FilePosition}; | 63 | use 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)] | ||
180 | pub(crate) struct Declarations { | ||
181 | fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>, | ||
182 | } | ||
183 | |||
184 | #[derive(Debug, Default, PartialEq, Eq)] | 177 | #[derive(Debug, Default, PartialEq, Eq)] |
185 | pub struct ModuleScope { | 178 | pub 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] | ||
117 | fn 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)] | ||
22 | pub 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 | |||
21 | impl ModPath { | 33 | impl 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)] |
72 | pub struct Path { | 84 | pub 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)] | ||
101 | pub 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 | |||
113 | impl Path { | 115 | impl 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 { | |||
225 | impl From<Name> for Path { | 227 | impl 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. |
23 | pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { | 23 | pub(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 | }; |
11 | use ra_syntax::ast::{self, NameOwner}; | 11 | use ra_syntax::ast::{self, NameOwner}; |
12 | use test_utils::tested_by; | ||
12 | 13 | ||
13 | use crate::path::{ModPath, PathKind}; | 14 | use 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 { | |||
583 | impl HasResolver for ContainerId { | 583 | impl 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 | |||
592 | impl 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 | ||
3 | use hir_expand::InFile; | 3 | use hir_expand::InFile; |
4 | use ra_arena::map::ArenaMap; | 4 | use ra_arena::map::ArenaMap; |
5 | use ra_syntax::ast; | 5 | use ra_syntax::AstNode; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{db::DefDatabase, AssocItemLoc, ItemLoc}; |
8 | db::DefDatabase, ConstLoc, EnumLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc, | ||
9 | TypeAliasLoc, UnionLoc, | ||
10 | }; | ||
11 | 8 | ||
12 | pub trait HasSource { | 9 | pub 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 | ||
17 | impl HasSource for FunctionLoc { | 14 | impl<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 | ||
26 | impl HasSource for TypeAliasLoc { | 23 | impl<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 | |||
35 | impl 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 | |||
44 | impl 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 | |||
53 | impl 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 | |||
62 | impl 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 | |||
71 | impl 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 | |||
80 | impl 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 | |||
89 | impl 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 | ||
15 | pub trait HirDisplay { | 16 | pub 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 | ||
77 | pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>); | 82 | pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>, bool); |
78 | 83 | ||
79 | impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> | 84 | impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> |
80 | where | 85 | where |
@@ -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 | }; |
13 | use hir_expand::name::{name, Name}; | 13 | use hir_expand::name::{name, Name}; |
14 | use ra_syntax::ast::RangeOp; | 14 | use 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 @@ | |||
3 | use std::iter; | 3 | use std::iter; |
4 | 4 | ||
5 | use hir_def::{ | 5 | use 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 | }; |
10 | use hir_expand::name::Name; | 10 | use 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; | |||
44 | use std::{fmt, iter, mem}; | 44 | use std::{fmt, iter, mem}; |
45 | 45 | ||
46 | use hir_def::{ | 46 | use 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 | }; |
50 | use hir_expand::name::Name; | 50 | use hir_expand::name::Name; |
51 | use ra_db::{impl_intern_key, salsa, CrateId}; | 51 | use 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; | |||
11 | use hir_def::{ | 11 | use 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 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::{ | 8 | use 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 | }; |
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | use ra_db::CrateId; | 13 | use 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 | }; |
10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; | 10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; |
11 | 11 | ||
12 | use hir_def::{AssocItemId, ContainerId, GenericDefId, ImplId, Lookup, TraitId, TypeAliasId}; | 12 | use hir_def::{ |
13 | AssocContainerId, AssocItemId, GenericDefId, HasModule, ImplId, Lookup, TraitId, TypeAliasId, | ||
14 | }; | ||
13 | use ra_db::{ | 15 | use 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 | }; |
14 | use hir_expand::name::{name, Name}; | 14 | use 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 | ||
3 | use ra_db::SourceDatabase; | 3 | use hir::db::AstDatabase; |
4 | use ra_syntax::{ | 4 | use 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 | }; |
9 | use test_utils::tested_by; | 8 | use test_utils::tested_by; |
10 | 9 | ||
11 | use crate::{db::RootDatabase, CallInfo, FilePosition, FunctionSignature}; | 10 | use 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. |
14 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { | 15 | pub(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 | ||
95 | impl FnCallNode { | 97 | impl 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 { | |||
328 | impl ToNav for hir::Local { | 328 | impl 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 | ||
432 | struct Test<K, T = u8> { | ||
433 | k: K, | ||
434 | t: T, | ||
435 | } | ||
436 | |||
437 | fn 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#" | ||
166 | struct Test<K, T = u8> { | ||
167 | k: K, | ||
168 | t: T, | ||
169 | } | ||
170 | |||
171 | fn 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, | ||
181 | label: "Test<i32>", | ||
182 | }, | ||
183 | ] | ||
184 | "### | ||
185 | ); | ||
186 | } | ||
187 | |||
188 | #[test] | ||
163 | fn let_statement() { | 189 | fn let_statement() { |
164 | let (analysis, file_id) = single_file( | 190 | let (analysis, file_id) = single_file( |
165 | r#" | 191 | r#" |
diff --git a/crates/ra_ide/src/marks.rs b/crates/ra_ide/src/marks.rs index 848ae4dc7..077a44473 100644 --- a/crates/ra_ide/src/marks.rs +++ b/crates/ra_ide/src/marks.rs | |||
@@ -3,10 +3,11 @@ | |||
3 | test_utils::marks!( | 3 | test_utils::marks!( |
4 | inserts_angle_brackets_for_generics | 4 | inserts_angle_brackets_for_generics |
5 | inserts_parens_for_function_calls | 5 | inserts_parens_for_function_calls |
6 | goto_definition_works_for_macros | 6 | goto_def_for_macros |
7 | goto_definition_works_for_methods | 7 | goto_def_for_methods |
8 | goto_definition_works_for_fields | 8 | goto_def_for_fields |
9 | goto_definition_works_for_record_fields | 9 | goto_def_for_record_fields |
10 | goto_def_for_field_init_shorthand | ||
10 | call_info_bad_offset | 11 | call_info_bad_offset |
11 | dont_complete_current_use | 12 | dont_complete_current_use |
12 | dont_complete_primitive_in_use | 13 | dont_complete_primitive_in_use |
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index c1f091ec0..3483a7176 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs | |||
@@ -134,21 +134,22 @@ pub(crate) fn classify_name_ref( | |||
134 | let analyzer = SourceAnalyzer::new(db, name_ref.map(|it| it.syntax()), None); | 134 | let analyzer = SourceAnalyzer::new(db, name_ref.map(|it| it.syntax()), None); |
135 | 135 | ||
136 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { | 136 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { |
137 | tested_by!(goto_definition_works_for_methods); | 137 | tested_by!(goto_def_for_methods); |
138 | if let Some(func) = analyzer.resolve_method_call(&method_call) { | 138 | if let Some(func) = analyzer.resolve_method_call(&method_call) { |
139 | return Some(from_assoc_item(db, func.into())); | 139 | return Some(from_assoc_item(db, func.into())); |
140 | } | 140 | } |
141 | } | 141 | } |
142 | 142 | ||
143 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { | 143 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { |
144 | tested_by!(goto_definition_works_for_fields); | 144 | tested_by!(goto_def_for_fields); |
145 | if let Some(field) = analyzer.resolve_field(&field_expr) { | 145 | if let Some(field) = analyzer.resolve_field(&field_expr) { |
146 | return Some(from_struct_field(db, field)); | 146 | return Some(from_struct_field(db, field)); |
147 | } | 147 | } |
148 | } | 148 | } |
149 | 149 | ||
150 | if let Some(record_field) = ast::RecordField::cast(parent.clone()) { | 150 | if let Some(record_field) = ast::RecordField::cast(parent.clone()) { |
151 | tested_by!(goto_definition_works_for_record_fields); | 151 | tested_by!(goto_def_for_record_fields); |
152 | tested_by!(goto_def_for_field_init_shorthand); | ||
152 | if let Some(field_def) = analyzer.resolve_record_field(&record_field) { | 153 | if let Some(field_def) = analyzer.resolve_record_field(&record_field) { |
153 | return Some(from_struct_field(db, field_def)); | 154 | return Some(from_struct_field(db, field_def)); |
154 | } | 155 | } |
@@ -160,7 +161,7 @@ pub(crate) fn classify_name_ref( | |||
160 | let visibility = None; | 161 | let visibility = None; |
161 | 162 | ||
162 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { | 163 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { |
163 | tested_by!(goto_definition_works_for_macros); | 164 | tested_by!(goto_def_for_macros); |
164 | if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(¯o_call)) { | 165 | if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(¯o_call)) { |
165 | let kind = NameKind::Macro(macro_def); | 166 | let kind = NameKind::Macro(macro_def); |
166 | return Some(NameDefinition { kind, container, visibility }); | 167 | return Some(NameDefinition { kind, container, visibility }); |
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html index 2157139f6..a097cf8e8 100644 --- a/crates/ra_ide/src/snapshots/highlighting.html +++ b/crates/ra_ide/src/snapshots/highlighting.html | |||
@@ -5,6 +5,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
5 | 5 | ||
6 | .comment { color: #7F9F7F; } | 6 | .comment { color: #7F9F7F; } |
7 | .string { color: #CC9393; } | 7 | .string { color: #CC9393; } |
8 | .field { color: #94BFF3; } | ||
8 | .function { color: #93E0E3; } | 9 | .function { color: #93E0E3; } |
9 | .parameter { color: #94BFF3; } | 10 | .parameter { color: #94BFF3; } |
10 | .text { color: #DCDCCC; } | 11 | .text { color: #DCDCCC; } |
@@ -39,7 +40,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
39 | 40 | ||
40 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>(); | 41 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>(); |
41 | <span class="keyword.control">if</span> <span class="keyword">true</span> { | 42 | <span class="keyword.control">if</span> <span class="keyword">true</span> { |
42 | <span class="variable.mut">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>: <span class="literal.numeric">0</span>, <span class="field">y</span>: <span class="literal.numeric">1</span> }); | 43 | <span class="keyword">let</span> <span class="variable">x</span> = <span class="literal.numeric">92</span>; |
44 | <span class="variable.mut">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="literal.numeric">1</span> }); | ||
43 | } | 45 | } |
44 | <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal.numeric">0</span>); } | 46 | <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal.numeric">0</span>); } |
45 | 47 | ||
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html index 871a52cf6..110556c09 100644 --- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html +++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html | |||
@@ -5,6 +5,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
5 | 5 | ||
6 | .comment { color: #7F9F7F; } | 6 | .comment { color: #7F9F7F; } |
7 | .string { color: #CC9393; } | 7 | .string { color: #CC9393; } |
8 | .field { color: #94BFF3; } | ||
8 | .function { color: #93E0E3; } | 9 | .function { color: #93E0E3; } |
9 | .parameter { color: #94BFF3; } | 10 | .parameter { color: #94BFF3; } |
10 | .text { color: #DCDCCC; } | 11 | .text { color: #DCDCCC; } |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 15e75709c..657c7b21a 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -102,11 +102,10 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
102 | COMMENT => tags::LITERAL_COMMENT, | 102 | COMMENT => tags::LITERAL_COMMENT, |
103 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => tags::LITERAL_STRING, | 103 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => tags::LITERAL_STRING, |
104 | ATTR => tags::LITERAL_ATTRIBUTE, | 104 | ATTR => tags::LITERAL_ATTRIBUTE, |
105 | // Special-case field init shorthand | ||
106 | NAME_REF if node.parent().and_then(ast::RecordField::cast).is_some() => tags::FIELD, | ||
107 | NAME_REF if node.ancestors().any(|it| it.kind() == ATTR) => continue, | ||
105 | NAME_REF => { | 108 | NAME_REF => { |
106 | if node.ancestors().any(|it| it.kind() == ATTR) { | ||
107 | continue; | ||
108 | } | ||
109 | |||
110 | let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); | 109 | let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); |
111 | let name_kind = | 110 | let name_kind = |
112 | classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind); | 111 | classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind); |
@@ -282,6 +281,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
282 | 281 | ||
283 | .comment { color: #7F9F7F; } | 282 | .comment { color: #7F9F7F; } |
284 | .string { color: #CC9393; } | 283 | .string { color: #CC9393; } |
284 | .field { color: #94BFF3; } | ||
285 | .function { color: #93E0E3; } | 285 | .function { color: #93E0E3; } |
286 | .parameter { color: #94BFF3; } | 286 | .parameter { color: #94BFF3; } |
287 | .text { color: #DCDCCC; } | 287 | .text { color: #DCDCCC; } |
@@ -327,7 +327,8 @@ fn main() { | |||
327 | 327 | ||
328 | let mut vec = Vec::new(); | 328 | let mut vec = Vec::new(); |
329 | if true { | 329 | if true { |
330 | vec.push(Foo { x: 0, y: 1 }); | 330 | let x = 92; |
331 | vec.push(Foo { x, y: 1 }); | ||
331 | } | 332 | } |
332 | unsafe { vec.set_len(0); } | 333 | unsafe { vec.set_len(0); } |
333 | 334 | ||
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 2c60430d1..ea2cac069 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -476,7 +476,7 @@ impl<'a> TreeSink for TtTreeSink<'a> { | |||
476 | #[cfg(test)] | 476 | #[cfg(test)] |
477 | mod tests { | 477 | mod tests { |
478 | use super::*; | 478 | use super::*; |
479 | use crate::tests::{create_rules, expand}; | 479 | use crate::tests::parse_macro; |
480 | use ra_parser::TokenSource; | 480 | use ra_parser::TokenSource; |
481 | use ra_syntax::{ | 481 | use ra_syntax::{ |
482 | algo::{insert_children, InsertPosition}, | 482 | algo::{insert_children, InsertPosition}, |
@@ -485,7 +485,7 @@ mod tests { | |||
485 | 485 | ||
486 | #[test] | 486 | #[test] |
487 | fn convert_tt_token_source() { | 487 | fn convert_tt_token_source() { |
488 | let rules = create_rules( | 488 | let expansion = parse_macro( |
489 | r#" | 489 | r#" |
490 | macro_rules! literals { | 490 | macro_rules! literals { |
491 | ($i:ident) => { | 491 | ($i:ident) => { |
@@ -498,8 +498,8 @@ mod tests { | |||
498 | } | 498 | } |
499 | } | 499 | } |
500 | "#, | 500 | "#, |
501 | ); | 501 | ) |
502 | let expansion = expand(&rules, "literals!(foo);"); | 502 | .expand_tt("literals!(foo);"); |
503 | let tts = &[expansion.into()]; | 503 | let tts = &[expansion.into()]; |
504 | let buffer = tt::buffer::TokenBuffer::new(tts); | 504 | let buffer = tt::buffer::TokenBuffer::new(tts); |
505 | let mut tt_src = SubtreeTokenSource::new(&buffer); | 505 | let mut tt_src = SubtreeTokenSource::new(&buffer); |
@@ -527,7 +527,7 @@ mod tests { | |||
527 | 527 | ||
528 | #[test] | 528 | #[test] |
529 | fn stmts_token_trees_to_expr_is_err() { | 529 | fn stmts_token_trees_to_expr_is_err() { |
530 | let rules = create_rules( | 530 | let expansion = parse_macro( |
531 | r#" | 531 | r#" |
532 | macro_rules! stmts { | 532 | macro_rules! stmts { |
533 | () => { | 533 | () => { |
@@ -538,8 +538,8 @@ mod tests { | |||
538 | } | 538 | } |
539 | } | 539 | } |
540 | "#, | 540 | "#, |
541 | ); | 541 | ) |
542 | let expansion = expand(&rules, "stmts!();"); | 542 | .expand_tt("stmts!();"); |
543 | assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err()); | 543 | assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err()); |
544 | } | 544 | } |
545 | 545 | ||
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs index ff225f0db..e640d115b 100644 --- a/crates/ra_mbe/src/tests.rs +++ b/crates/ra_mbe/src/tests.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | use std::fmt::Write; | ||
2 | |||
1 | use ra_parser::FragmentKind; | 3 | use ra_parser::FragmentKind; |
2 | use ra_syntax::{ast, AstNode, NodeOrToken, WalkEvent}; | 4 | use ra_syntax::{ast, AstNode, NodeOrToken, SyntaxKind::IDENT, SyntaxNode, WalkEvent, T}; |
3 | use test_utils::assert_eq_text; | 5 | use test_utils::assert_eq_text; |
4 | 6 | ||
5 | use super::*; | 7 | use super::*; |
@@ -61,13 +63,14 @@ mod rule_parsing { | |||
61 | 63 | ||
62 | #[test] | 64 | #[test] |
63 | fn test_token_id_shift() { | 65 | fn test_token_id_shift() { |
64 | let macro_definition = r#" | 66 | let expansion = parse_macro( |
67 | r#" | ||
65 | macro_rules! foobar { | 68 | macro_rules! foobar { |
66 | ($e:ident) => { foo bar $e } | 69 | ($e:ident) => { foo bar $e } |
67 | } | 70 | } |
68 | "#; | 71 | "#, |
69 | let rules = create_rules(macro_definition); | 72 | ) |
70 | let expansion = expand(&rules, "foobar!(baz);"); | 73 | .expand_tt("foobar!(baz);"); |
71 | 74 | ||
72 | fn get_id(t: &tt::TokenTree) -> Option<u32> { | 75 | fn get_id(t: &tt::TokenTree) -> Option<u32> { |
73 | if let tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = t { | 76 | if let tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = t { |
@@ -90,22 +93,23 @@ macro_rules! foobar { | |||
90 | 93 | ||
91 | #[test] | 94 | #[test] |
92 | fn test_token_map() { | 95 | fn test_token_map() { |
93 | use ra_parser::SyntaxKind::*; | 96 | let expanded = parse_macro( |
94 | use ra_syntax::T; | 97 | r#" |
95 | |||
96 | let macro_definition = r#" | ||
97 | macro_rules! foobar { | 98 | macro_rules! foobar { |
98 | ($e:ident) => { fn $e() {} } | 99 | ($e:ident) => { fn $e() {} } |
99 | } | 100 | } |
100 | "#; | 101 | "#, |
101 | let rules = create_rules(macro_definition); | 102 | ) |
102 | let (expansion, (token_map, content)) = expand_and_map(&rules, "foobar!(baz);"); | 103 | .expand_tt("foobar!(baz);"); |
104 | |||
105 | let (node, token_map) = token_tree_to_syntax_node(&expanded, FragmentKind::Items).unwrap(); | ||
106 | let content = node.syntax_node().to_string(); | ||
103 | 107 | ||
104 | let get_text = |id, kind| -> String { | 108 | let get_text = |id, kind| -> String { |
105 | content[token_map.range_by_token(id).unwrap().by_kind(kind).unwrap()].to_string() | 109 | content[token_map.range_by_token(id).unwrap().by_kind(kind).unwrap()].to_string() |
106 | }; | 110 | }; |
107 | 111 | ||
108 | assert_eq!(expansion.token_trees.len(), 4); | 112 | assert_eq!(expanded.token_trees.len(), 4); |
109 | // {($e:ident) => { fn $e() {} }} | 113 | // {($e:ident) => { fn $e() {} }} |
110 | // 012345 67 8 9 T12 3 | 114 | // 012345 67 8 9 T12 3 |
111 | 115 | ||
@@ -116,7 +120,7 @@ macro_rules! foobar { | |||
116 | 120 | ||
117 | #[test] | 121 | #[test] |
118 | fn test_convert_tt() { | 122 | fn test_convert_tt() { |
119 | let macro_definition = r#" | 123 | parse_macro(r#" |
120 | macro_rules! impl_froms { | 124 | macro_rules! impl_froms { |
121 | ($e:ident: $($v:ident),*) => { | 125 | ($e:ident: $($v:ident),*) => { |
122 | $( | 126 | $( |
@@ -128,24 +132,17 @@ macro_rules! impl_froms { | |||
128 | )* | 132 | )* |
129 | } | 133 | } |
130 | } | 134 | } |
131 | "#; | 135 | "#) |
132 | 136 | .assert_expand_tt( | |
133 | let macro_invocation = r#" | 137 | "impl_froms!(TokenTree: Leaf, Subtree);", |
134 | impl_froms!(TokenTree: Leaf, Subtree); | 138 | "impl From <Leaf > for TokenTree {fn from (it : Leaf) -> TokenTree {TokenTree ::Leaf (it)}} \ |
135 | "#; | 139 | impl From <Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree ::Subtree (it)}}" |
136 | 140 | ); | |
137 | let rules = create_rules(macro_definition); | ||
138 | let expansion = expand(&rules, macro_invocation); | ||
139 | assert_eq!( | ||
140 | expansion.to_string(), | ||
141 | "impl From <Leaf > for TokenTree {fn from (it : Leaf) -> TokenTree {TokenTree ::Leaf (it)}} \ | ||
142 | impl From <Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree ::Subtree (it)}}" | ||
143 | ) | ||
144 | } | 141 | } |
145 | 142 | ||
146 | #[test] | 143 | #[test] |
147 | fn test_expr_order() { | 144 | fn test_expr_order() { |
148 | let rules = create_rules( | 145 | let expanded = parse_macro( |
149 | r#" | 146 | r#" |
150 | macro_rules! foo { | 147 | macro_rules! foo { |
151 | ($ i:expr) => { | 148 | ($ i:expr) => { |
@@ -153,11 +150,10 @@ fn test_expr_order() { | |||
153 | } | 150 | } |
154 | } | 151 | } |
155 | "#, | 152 | "#, |
156 | ); | 153 | ) |
157 | let expanded = expand(&rules, "foo! { 1 + 1}"); | 154 | .expand_items("foo! { 1 + 1}"); |
158 | let tree = token_tree_to_syntax_node(&expanded, FragmentKind::Items).unwrap().0.syntax_node(); | ||
159 | 155 | ||
160 | let dump = format!("{:#?}", tree); | 156 | let dump = format!("{:#?}", expanded); |
161 | assert_eq_text!( | 157 | assert_eq_text!( |
162 | dump.trim(), | 158 | dump.trim(), |
163 | r#"MACRO_ITEMS@[0; 15) | 159 | r#"MACRO_ITEMS@[0; 15) |
@@ -189,7 +185,7 @@ fn test_expr_order() { | |||
189 | 185 | ||
190 | #[test] | 186 | #[test] |
191 | fn test_fail_match_pattern_by_first_token() { | 187 | fn test_fail_match_pattern_by_first_token() { |
192 | let rules = create_rules( | 188 | parse_macro( |
193 | r#" | 189 | r#" |
194 | macro_rules! foo { | 190 | macro_rules! foo { |
195 | ($ i:ident) => ( | 191 | ($ i:ident) => ( |
@@ -203,16 +199,15 @@ fn test_fail_match_pattern_by_first_token() { | |||
203 | ) | 199 | ) |
204 | } | 200 | } |
205 | "#, | 201 | "#, |
206 | ); | 202 | ) |
207 | 203 | .assert_expand_items("foo! { foo }", "mod foo {}") | |
208 | assert_expansion(MacroKind::Items, &rules, "foo! { foo }", "mod foo {}"); | 204 | .assert_expand_items("foo! { = bar }", "fn bar () {}") |
209 | assert_expansion(MacroKind::Items, &rules, "foo! { = bar }", "fn bar () {}"); | 205 | .assert_expand_items("foo! { + Baz }", "struct Baz ;"); |
210 | assert_expansion(MacroKind::Items, &rules, "foo! { + Baz }", "struct Baz ;"); | ||
211 | } | 206 | } |
212 | 207 | ||
213 | #[test] | 208 | #[test] |
214 | fn test_fail_match_pattern_by_last_token() { | 209 | fn test_fail_match_pattern_by_last_token() { |
215 | let rules = create_rules( | 210 | parse_macro( |
216 | r#" | 211 | r#" |
217 | macro_rules! foo { | 212 | macro_rules! foo { |
218 | ($ i:ident) => ( | 213 | ($ i:ident) => ( |
@@ -226,16 +221,15 @@ fn test_fail_match_pattern_by_last_token() { | |||
226 | ) | 221 | ) |
227 | } | 222 | } |
228 | "#, | 223 | "#, |
229 | ); | 224 | ) |
230 | 225 | .assert_expand_items("foo! { foo }", "mod foo {}") | |
231 | assert_expansion(MacroKind::Items, &rules, "foo! { foo }", "mod foo {}"); | 226 | .assert_expand_items("foo! { bar = }", "fn bar () {}") |
232 | assert_expansion(MacroKind::Items, &rules, "foo! { bar = }", "fn bar () {}"); | 227 | .assert_expand_items("foo! { Baz + }", "struct Baz ;"); |
233 | assert_expansion(MacroKind::Items, &rules, "foo! { Baz + }", "struct Baz ;"); | ||
234 | } | 228 | } |
235 | 229 | ||
236 | #[test] | 230 | #[test] |
237 | fn test_fail_match_pattern_by_word_token() { | 231 | fn test_fail_match_pattern_by_word_token() { |
238 | let rules = create_rules( | 232 | parse_macro( |
239 | r#" | 233 | r#" |
240 | macro_rules! foo { | 234 | macro_rules! foo { |
241 | ($ i:ident) => ( | 235 | ($ i:ident) => ( |
@@ -249,16 +243,15 @@ fn test_fail_match_pattern_by_word_token() { | |||
249 | ) | 243 | ) |
250 | } | 244 | } |
251 | "#, | 245 | "#, |
252 | ); | 246 | ) |
253 | 247 | .assert_expand_items("foo! { foo }", "mod foo {}") | |
254 | assert_expansion(MacroKind::Items, &rules, "foo! { foo }", "mod foo {}"); | 248 | .assert_expand_items("foo! { spam bar }", "fn bar () {}") |
255 | assert_expansion(MacroKind::Items, &rules, "foo! { spam bar }", "fn bar () {}"); | 249 | .assert_expand_items("foo! { eggs Baz }", "struct Baz ;"); |
256 | assert_expansion(MacroKind::Items, &rules, "foo! { eggs Baz }", "struct Baz ;"); | ||
257 | } | 250 | } |
258 | 251 | ||
259 | #[test] | 252 | #[test] |
260 | fn test_match_group_pattern_by_separator_token() { | 253 | fn test_match_group_pattern_by_separator_token() { |
261 | let rules = create_rules( | 254 | parse_macro( |
262 | r#" | 255 | r#" |
263 | macro_rules! foo { | 256 | macro_rules! foo { |
264 | ($ ($ i:ident),*) => ($ ( | 257 | ($ ($ i:ident),*) => ($ ( |
@@ -273,16 +266,15 @@ fn test_match_group_pattern_by_separator_token() { | |||
273 | ) | 266 | ) |
274 | } | 267 | } |
275 | "#, | 268 | "#, |
276 | ); | 269 | ) |
277 | 270 | .assert_expand_items("foo! { foo, bar }", "mod foo {} mod bar {}") | |
278 | assert_expansion(MacroKind::Items, &rules, "foo! { foo, bar }", "mod foo {} mod bar {}"); | 271 | .assert_expand_items("foo! { foo# bar }", "fn foo () {} fn bar () {}") |
279 | assert_expansion(MacroKind::Items, &rules, "foo! { foo# bar }", "fn foo () {} fn bar () {}"); | 272 | .assert_expand_items("foo! { Foo,# Bar }", "struct Foo ; struct Bar ;"); |
280 | assert_expansion(MacroKind::Items, &rules, "foo! { Foo,# Bar }", "struct Foo ; struct Bar ;"); | ||
281 | } | 273 | } |
282 | 274 | ||
283 | #[test] | 275 | #[test] |
284 | fn test_match_group_pattern_with_multiple_defs() { | 276 | fn test_match_group_pattern_with_multiple_defs() { |
285 | let rules = create_rules( | 277 | parse_macro( |
286 | r#" | 278 | r#" |
287 | macro_rules! foo { | 279 | macro_rules! foo { |
288 | ($ ($ i:ident),*) => ( struct Bar { $ ( | 280 | ($ ($ i:ident),*) => ( struct Bar { $ ( |
@@ -290,19 +282,13 @@ fn test_match_group_pattern_with_multiple_defs() { | |||
290 | )*} ); | 282 | )*} ); |
291 | } | 283 | } |
292 | "#, | 284 | "#, |
293 | ); | 285 | ) |
294 | 286 | .assert_expand_items("foo! { foo, bar }", "struct Bar {fn foo {} fn bar {}}"); | |
295 | assert_expansion( | ||
296 | MacroKind::Items, | ||
297 | &rules, | ||
298 | "foo! { foo, bar }", | ||
299 | "struct Bar {fn foo {} fn bar {}}", | ||
300 | ); | ||
301 | } | 287 | } |
302 | 288 | ||
303 | #[test] | 289 | #[test] |
304 | fn test_match_group_pattern_with_multiple_statement() { | 290 | fn test_match_group_pattern_with_multiple_statement() { |
305 | let rules = create_rules( | 291 | parse_macro( |
306 | r#" | 292 | r#" |
307 | macro_rules! foo { | 293 | macro_rules! foo { |
308 | ($ ($ i:ident),*) => ( fn baz { $ ( | 294 | ($ ($ i:ident),*) => ( fn baz { $ ( |
@@ -310,14 +296,13 @@ fn test_match_group_pattern_with_multiple_statement() { | |||
310 | )*} ); | 296 | )*} ); |
311 | } | 297 | } |
312 | "#, | 298 | "#, |
313 | ); | 299 | ) |
314 | 300 | .assert_expand_items("foo! { foo, bar }", "fn baz {foo () ; bar () ;}"); | |
315 | assert_expansion(MacroKind::Items, &rules, "foo! { foo, bar }", "fn baz {foo () ; bar () ;}"); | ||
316 | } | 301 | } |
317 | 302 | ||
318 | #[test] | 303 | #[test] |
319 | fn test_match_group_pattern_with_multiple_statement_without_semi() { | 304 | fn test_match_group_pattern_with_multiple_statement_without_semi() { |
320 | let rules = create_rules( | 305 | parse_macro( |
321 | r#" | 306 | r#" |
322 | macro_rules! foo { | 307 | macro_rules! foo { |
323 | ($ ($ i:ident),*) => ( fn baz { $ ( | 308 | ($ ($ i:ident),*) => ( fn baz { $ ( |
@@ -325,14 +310,13 @@ fn test_match_group_pattern_with_multiple_statement_without_semi() { | |||
325 | );*} ); | 310 | );*} ); |
326 | } | 311 | } |
327 | "#, | 312 | "#, |
328 | ); | 313 | ) |
329 | 314 | .assert_expand_items("foo! { foo, bar }", "fn baz {foo () ;bar ()}"); | |
330 | assert_expansion(MacroKind::Items, &rules, "foo! { foo, bar }", "fn baz {foo () ;bar ()}"); | ||
331 | } | 315 | } |
332 | 316 | ||
333 | #[test] | 317 | #[test] |
334 | fn test_match_group_empty_fixed_token() { | 318 | fn test_match_group_empty_fixed_token() { |
335 | let rules = create_rules( | 319 | parse_macro( |
336 | r#" | 320 | r#" |
337 | macro_rules! foo { | 321 | macro_rules! foo { |
338 | ($ ($ i:ident)* #abc) => ( fn baz { $ ( | 322 | ($ ($ i:ident)* #abc) => ( fn baz { $ ( |
@@ -340,69 +324,59 @@ fn test_match_group_empty_fixed_token() { | |||
340 | )*} ); | 324 | )*} ); |
341 | } | 325 | } |
342 | "#, | 326 | "#, |
343 | ); | 327 | ) |
344 | 328 | .assert_expand_items("foo! {#abc}", "fn baz {}"); | |
345 | assert_expansion(MacroKind::Items, &rules, "foo! {#abc}", "fn baz {}"); | ||
346 | } | 329 | } |
347 | 330 | ||
348 | #[test] | 331 | #[test] |
349 | fn test_match_group_in_subtree() { | 332 | fn test_match_group_in_subtree() { |
350 | let rules = create_rules( | 333 | parse_macro( |
351 | r#" | 334 | r#" |
352 | macro_rules! foo { | 335 | macro_rules! foo { |
353 | (fn $name:ident {$($i:ident)*} ) => ( fn $name() { $ ( | 336 | (fn $name:ident {$($i:ident)*} ) => ( fn $name() { $ ( |
354 | $ i (); | 337 | $ i (); |
355 | )*} ); | 338 | )*} ); |
356 | }"#, | 339 | }"#, |
357 | ); | 340 | ) |
358 | 341 | .assert_expand_items("foo! {fn baz {a b} }", "fn baz () {a () ; b () ;}"); | |
359 | assert_expansion(MacroKind::Items, &rules, "foo! {fn baz {a b} }", "fn baz () {a () ; b () ;}"); | ||
360 | } | 342 | } |
361 | 343 | ||
362 | #[test] | 344 | #[test] |
363 | fn test_match_group_with_multichar_sep() { | 345 | fn test_match_group_with_multichar_sep() { |
364 | let rules = create_rules( | 346 | parse_macro( |
365 | r#" | 347 | r#" |
366 | macro_rules! foo { | 348 | macro_rules! foo { |
367 | (fn $name:ident {$($i:literal)*} ) => ( fn $name() -> bool { $($i)&&*} ); | 349 | (fn $name:ident {$($i:literal)*} ) => ( fn $name() -> bool { $($i)&&*} ); |
368 | }"#, | 350 | }"#, |
369 | ); | 351 | ) |
370 | 352 | .assert_expand_items("foo! (fn baz {true true} );", "fn baz () -> bool {true &&true}"); | |
371 | assert_expansion( | ||
372 | MacroKind::Items, | ||
373 | &rules, | ||
374 | "foo! (fn baz {true true} );", | ||
375 | "fn baz () -> bool {true &&true}", | ||
376 | ); | ||
377 | } | 353 | } |
378 | 354 | ||
379 | #[test] | 355 | #[test] |
380 | fn test_match_group_zero_match() { | 356 | fn test_match_group_zero_match() { |
381 | let rules = create_rules( | 357 | parse_macro( |
382 | r#" | 358 | r#" |
383 | macro_rules! foo { | 359 | macro_rules! foo { |
384 | ( $($i:ident)* ) => (); | 360 | ( $($i:ident)* ) => (); |
385 | }"#, | 361 | }"#, |
386 | ); | 362 | ) |
387 | 363 | .assert_expand_items("foo! ();", ""); | |
388 | assert_expansion(MacroKind::Items, &rules, "foo! ();", ""); | ||
389 | } | 364 | } |
390 | 365 | ||
391 | #[test] | 366 | #[test] |
392 | fn test_match_group_in_group() { | 367 | fn test_match_group_in_group() { |
393 | let rules = create_rules( | 368 | parse_macro( |
394 | r#" | 369 | r#" |
395 | macro_rules! foo { | 370 | macro_rules! foo { |
396 | { $( ( $($i:ident)* ) )* } => ( $( ( $($i)* ) )* ); | 371 | { $( ( $($i:ident)* ) )* } => ( $( ( $($i)* ) )* ); |
397 | }"#, | 372 | }"#, |
398 | ); | 373 | ) |
399 | 374 | .assert_expand_items("foo! ( (a b) );", "(a b)"); | |
400 | assert_expansion(MacroKind::Items, &rules, "foo! ( (a b) );", "(a b)"); | ||
401 | } | 375 | } |
402 | 376 | ||
403 | #[test] | 377 | #[test] |
404 | fn test_expand_to_item_list() { | 378 | fn test_expand_to_item_list() { |
405 | let rules = create_rules( | 379 | let tree = parse_macro( |
406 | " | 380 | " |
407 | macro_rules! structs { | 381 | macro_rules! structs { |
408 | ($($i:ident),*) => { | 382 | ($($i:ident),*) => { |
@@ -410,9 +384,8 @@ fn test_expand_to_item_list() { | |||
410 | } | 384 | } |
411 | } | 385 | } |
412 | ", | 386 | ", |
413 | ); | 387 | ) |
414 | let expansion = expand(&rules, "structs!(Foo, Bar);"); | 388 | .expand_items("structs!(Foo, Bar);"); |
415 | let tree = token_tree_to_syntax_node(&expansion, FragmentKind::Items).unwrap().0.syntax_node(); | ||
416 | assert_eq!( | 389 | assert_eq!( |
417 | format!("{:#?}", tree).trim(), | 390 | format!("{:#?}", tree).trim(), |
418 | r#" | 391 | r#" |
@@ -469,7 +442,7 @@ fn test_expand_literals_to_token_tree() { | |||
469 | unreachable!("It is not a literal"); | 442 | unreachable!("It is not a literal"); |
470 | } | 443 | } |
471 | 444 | ||
472 | let rules = create_rules( | 445 | let expansion = parse_macro( |
473 | r#" | 446 | r#" |
474 | macro_rules! literals { | 447 | macro_rules! literals { |
475 | ($i:ident) => { | 448 | ($i:ident) => { |
@@ -482,8 +455,8 @@ fn test_expand_literals_to_token_tree() { | |||
482 | } | 455 | } |
483 | } | 456 | } |
484 | "#, | 457 | "#, |
485 | ); | 458 | ) |
486 | let expansion = expand(&rules, "literals!(foo);"); | 459 | .expand_tt("literals!(foo);"); |
487 | let stm_tokens = &to_subtree(&expansion.token_trees[0]).token_trees; | 460 | let stm_tokens = &to_subtree(&expansion.token_trees[0]).token_trees; |
488 | 461 | ||
489 | // [let] [a] [=] ['c'] [;] | 462 | // [let] [a] [=] ['c'] [;] |
@@ -498,7 +471,7 @@ fn test_expand_literals_to_token_tree() { | |||
498 | 471 | ||
499 | #[test] | 472 | #[test] |
500 | fn test_two_idents() { | 473 | fn test_two_idents() { |
501 | let rules = create_rules( | 474 | parse_macro( |
502 | r#" | 475 | r#" |
503 | macro_rules! foo { | 476 | macro_rules! foo { |
504 | ($ i:ident, $ j:ident) => { | 477 | ($ i:ident, $ j:ident) => { |
@@ -506,18 +479,13 @@ fn test_two_idents() { | |||
506 | } | 479 | } |
507 | } | 480 | } |
508 | "#, | 481 | "#, |
509 | ); | 482 | ) |
510 | assert_expansion( | 483 | .assert_expand_items("foo! { foo, bar }", "fn foo () {let a = foo ; let b = bar ;}"); |
511 | MacroKind::Items, | ||
512 | &rules, | ||
513 | "foo! { foo, bar }", | ||
514 | "fn foo () {let a = foo ; let b = bar ;}", | ||
515 | ); | ||
516 | } | 484 | } |
517 | 485 | ||
518 | #[test] | 486 | #[test] |
519 | fn test_tt_to_stmts() { | 487 | fn test_tt_to_stmts() { |
520 | let rules = create_rules( | 488 | let stmts = parse_macro( |
521 | r#" | 489 | r#" |
522 | macro_rules! foo { | 490 | macro_rules! foo { |
523 | () => { | 491 | () => { |
@@ -527,11 +495,8 @@ fn test_tt_to_stmts() { | |||
527 | } | 495 | } |
528 | } | 496 | } |
529 | "#, | 497 | "#, |
530 | ); | 498 | ) |
531 | 499 | .expand_statements("foo!{}"); | |
532 | let expanded = expand(&rules, "foo!{}"); | ||
533 | let stmts = | ||
534 | token_tree_to_syntax_node(&expanded, FragmentKind::Statements).unwrap().0.syntax_node(); | ||
535 | 500 | ||
536 | assert_eq!( | 501 | assert_eq!( |
537 | format!("{:#?}", stmts).trim(), | 502 | format!("{:#?}", stmts).trim(), |
@@ -571,7 +536,7 @@ fn test_tt_to_stmts() { | |||
571 | 536 | ||
572 | #[test] | 537 | #[test] |
573 | fn test_match_literal() { | 538 | fn test_match_literal() { |
574 | let rules = create_rules( | 539 | parse_macro( |
575 | r#" | 540 | r#" |
576 | macro_rules! foo { | 541 | macro_rules! foo { |
577 | ('(') => { | 542 | ('(') => { |
@@ -579,8 +544,8 @@ fn test_match_literal() { | |||
579 | } | 544 | } |
580 | } | 545 | } |
581 | "#, | 546 | "#, |
582 | ); | 547 | ) |
583 | assert_expansion(MacroKind::Items, &rules, "foo! ['('];", "fn foo () {}"); | 548 | .assert_expand_items("foo! ['('];", "fn foo () {}"); |
584 | } | 549 | } |
585 | 550 | ||
586 | // The following tests are port from intellij-rust directly | 551 | // The following tests are port from intellij-rust directly |
@@ -588,7 +553,7 @@ fn test_match_literal() { | |||
588 | 553 | ||
589 | #[test] | 554 | #[test] |
590 | fn test_path() { | 555 | fn test_path() { |
591 | let rules = create_rules( | 556 | parse_macro( |
592 | r#" | 557 | r#" |
593 | macro_rules! foo { | 558 | macro_rules! foo { |
594 | ($ i:path) => { | 559 | ($ i:path) => { |
@@ -596,11 +561,9 @@ fn test_path() { | |||
596 | } | 561 | } |
597 | } | 562 | } |
598 | "#, | 563 | "#, |
599 | ); | 564 | ) |
600 | assert_expansion(MacroKind::Items, &rules, "foo! { foo }", "fn foo () {let a = foo ;}"); | 565 | .assert_expand_items("foo! { foo }", "fn foo () {let a = foo ;}") |
601 | assert_expansion( | 566 | .assert_expand_items( |
602 | MacroKind::Items, | ||
603 | &rules, | ||
604 | "foo! { bar::<u8>::baz::<u8> }", | 567 | "foo! { bar::<u8>::baz::<u8> }", |
605 | "fn foo () {let a = bar ::< u8 >:: baz ::< u8 > ;}", | 568 | "fn foo () {let a = bar ::< u8 >:: baz ::< u8 > ;}", |
606 | ); | 569 | ); |
@@ -608,7 +571,7 @@ fn test_path() { | |||
608 | 571 | ||
609 | #[test] | 572 | #[test] |
610 | fn test_two_paths() { | 573 | fn test_two_paths() { |
611 | let rules = create_rules( | 574 | parse_macro( |
612 | r#" | 575 | r#" |
613 | macro_rules! foo { | 576 | macro_rules! foo { |
614 | ($ i:path, $ j:path) => { | 577 | ($ i:path, $ j:path) => { |
@@ -616,18 +579,13 @@ fn test_two_paths() { | |||
616 | } | 579 | } |
617 | } | 580 | } |
618 | "#, | 581 | "#, |
619 | ); | 582 | ) |
620 | assert_expansion( | 583 | .assert_expand_items("foo! { foo, bar }", "fn foo () {let a = foo ; let b = bar ;}"); |
621 | MacroKind::Items, | ||
622 | &rules, | ||
623 | "foo! { foo, bar }", | ||
624 | "fn foo () {let a = foo ; let b = bar ;}", | ||
625 | ); | ||
626 | } | 584 | } |
627 | 585 | ||
628 | #[test] | 586 | #[test] |
629 | fn test_path_with_path() { | 587 | fn test_path_with_path() { |
630 | let rules = create_rules( | 588 | parse_macro( |
631 | r#" | 589 | r#" |
632 | macro_rules! foo { | 590 | macro_rules! foo { |
633 | ($ i:path) => { | 591 | ($ i:path) => { |
@@ -635,13 +593,13 @@ fn test_path_with_path() { | |||
635 | } | 593 | } |
636 | } | 594 | } |
637 | "#, | 595 | "#, |
638 | ); | 596 | ) |
639 | assert_expansion(MacroKind::Items, &rules, "foo! { foo }", "fn foo () {let a = foo :: bar ;}"); | 597 | .assert_expand_items("foo! { foo }", "fn foo () {let a = foo :: bar ;}"); |
640 | } | 598 | } |
641 | 599 | ||
642 | #[test] | 600 | #[test] |
643 | fn test_expr() { | 601 | fn test_expr() { |
644 | let rules = create_rules( | 602 | parse_macro( |
645 | r#" | 603 | r#" |
646 | macro_rules! foo { | 604 | macro_rules! foo { |
647 | ($ i:expr) => { | 605 | ($ i:expr) => { |
@@ -649,11 +607,8 @@ fn test_expr() { | |||
649 | } | 607 | } |
650 | } | 608 | } |
651 | "#, | 609 | "#, |
652 | ); | 610 | ) |
653 | 611 | .assert_expand_items( | |
654 | assert_expansion( | ||
655 | MacroKind::Items, | ||
656 | &rules, | ||
657 | "foo! { 2 + 2 * baz(3).quux() }", | 612 | "foo! { 2 + 2 * baz(3).quux() }", |
658 | "fn bar () {2 + 2 * baz (3) . quux () ;}", | 613 | "fn bar () {2 + 2 * baz (3) . quux () ;}", |
659 | ); | 614 | ); |
@@ -661,7 +616,7 @@ fn test_expr() { | |||
661 | 616 | ||
662 | #[test] | 617 | #[test] |
663 | fn test_last_expr() { | 618 | fn test_last_expr() { |
664 | let rules = create_rules( | 619 | parse_macro( |
665 | r#" | 620 | r#" |
666 | macro_rules! vec { | 621 | macro_rules! vec { |
667 | ($($item:expr),*) => { | 622 | ($($item:expr),*) => { |
@@ -675,10 +630,8 @@ fn test_last_expr() { | |||
675 | }; | 630 | }; |
676 | } | 631 | } |
677 | "#, | 632 | "#, |
678 | ); | 633 | ) |
679 | assert_expansion( | 634 | .assert_expand_items( |
680 | MacroKind::Items, | ||
681 | &rules, | ||
682 | "vec!(1,2,3);", | 635 | "vec!(1,2,3);", |
683 | "{let mut v = Vec :: new () ; v . push (1) ; v . push (2) ; v . push (3) ; v}", | 636 | "{let mut v = Vec :: new () ; v . push (1) ; v . push (2) ; v . push (3) ; v}", |
684 | ); | 637 | ); |
@@ -686,7 +639,7 @@ fn test_last_expr() { | |||
686 | 639 | ||
687 | #[test] | 640 | #[test] |
688 | fn test_ty() { | 641 | fn test_ty() { |
689 | let rules = create_rules( | 642 | parse_macro( |
690 | r#" | 643 | r#" |
691 | macro_rules! foo { | 644 | macro_rules! foo { |
692 | ($ i:ty) => ( | 645 | ($ i:ty) => ( |
@@ -694,18 +647,13 @@ fn test_ty() { | |||
694 | ) | 647 | ) |
695 | } | 648 | } |
696 | "#, | 649 | "#, |
697 | ); | 650 | ) |
698 | assert_expansion( | 651 | .assert_expand_items("foo! { Baz<u8> }", "fn bar () -> Baz < u8 > {unimplemented ! ()}"); |
699 | MacroKind::Items, | ||
700 | &rules, | ||
701 | "foo! { Baz<u8> }", | ||
702 | "fn bar () -> Baz < u8 > {unimplemented ! ()}", | ||
703 | ); | ||
704 | } | 652 | } |
705 | 653 | ||
706 | #[test] | 654 | #[test] |
707 | fn test_ty_with_complex_type() { | 655 | fn test_ty_with_complex_type() { |
708 | let rules = create_rules( | 656 | parse_macro( |
709 | r#" | 657 | r#" |
710 | macro_rules! foo { | 658 | macro_rules! foo { |
711 | ($ i:ty) => ( | 659 | ($ i:ty) => ( |
@@ -713,20 +661,14 @@ fn test_ty_with_complex_type() { | |||
713 | ) | 661 | ) |
714 | } | 662 | } |
715 | "#, | 663 | "#, |
716 | ); | 664 | ) |
717 | |||
718 | // Reference lifetime struct with generic type | 665 | // Reference lifetime struct with generic type |
719 | assert_expansion( | 666 | .assert_expand_items( |
720 | MacroKind::Items, | ||
721 | &rules, | ||
722 | "foo! { &'a Baz<u8> }", | 667 | "foo! { &'a Baz<u8> }", |
723 | "fn bar () -> & 'a Baz < u8 > {unimplemented ! ()}", | 668 | "fn bar () -> & 'a Baz < u8 > {unimplemented ! ()}", |
724 | ); | 669 | ) |
725 | |||
726 | // extern "Rust" func type | 670 | // extern "Rust" func type |
727 | assert_expansion( | 671 | .assert_expand_items( |
728 | MacroKind::Items, | ||
729 | &rules, | ||
730 | r#"foo! { extern "Rust" fn() -> Ret }"#, | 672 | r#"foo! { extern "Rust" fn() -> Ret }"#, |
731 | r#"fn bar () -> extern "Rust" fn () -> Ret {unimplemented ! ()}"#, | 673 | r#"fn bar () -> extern "Rust" fn () -> Ret {unimplemented ! ()}"#, |
732 | ); | 674 | ); |
@@ -734,19 +676,19 @@ fn test_ty_with_complex_type() { | |||
734 | 676 | ||
735 | #[test] | 677 | #[test] |
736 | fn test_pat_() { | 678 | fn test_pat_() { |
737 | let rules = create_rules( | 679 | parse_macro( |
738 | r#" | 680 | r#" |
739 | macro_rules! foo { | 681 | macro_rules! foo { |
740 | ($ i:pat) => { fn foo() { let $ i; } } | 682 | ($ i:pat) => { fn foo() { let $ i; } } |
741 | } | 683 | } |
742 | "#, | 684 | "#, |
743 | ); | 685 | ) |
744 | assert_expansion(MacroKind::Items, &rules, "foo! { (a, b) }", "fn foo () {let (a , b) ;}"); | 686 | .assert_expand_items("foo! { (a, b) }", "fn foo () {let (a , b) ;}"); |
745 | } | 687 | } |
746 | 688 | ||
747 | #[test] | 689 | #[test] |
748 | fn test_stmt() { | 690 | fn test_stmt() { |
749 | let rules = create_rules( | 691 | parse_macro( |
750 | r#" | 692 | r#" |
751 | macro_rules! foo { | 693 | macro_rules! foo { |
752 | ($ i:stmt) => ( | 694 | ($ i:stmt) => ( |
@@ -754,14 +696,14 @@ fn test_stmt() { | |||
754 | ) | 696 | ) |
755 | } | 697 | } |
756 | "#, | 698 | "#, |
757 | ); | 699 | ) |
758 | assert_expansion(MacroKind::Items, &rules, "foo! { 2 }", "fn bar () {2 ;}"); | 700 | .assert_expand_items("foo! { 2 }", "fn bar () {2 ;}") |
759 | assert_expansion(MacroKind::Items, &rules, "foo! { let a = 0 }", "fn bar () {let a = 0 ;}"); | 701 | .assert_expand_items("foo! { let a = 0 }", "fn bar () {let a = 0 ;}"); |
760 | } | 702 | } |
761 | 703 | ||
762 | #[test] | 704 | #[test] |
763 | fn test_single_item() { | 705 | fn test_single_item() { |
764 | let rules = create_rules( | 706 | parse_macro( |
765 | r#" | 707 | r#" |
766 | macro_rules! foo { | 708 | macro_rules! foo { |
767 | ($ i:item) => ( | 709 | ($ i:item) => ( |
@@ -769,13 +711,13 @@ fn test_single_item() { | |||
769 | ) | 711 | ) |
770 | } | 712 | } |
771 | "#, | 713 | "#, |
772 | ); | 714 | ) |
773 | assert_expansion(MacroKind::Items, &rules, "foo! {mod c {}}", "mod c {}"); | 715 | .assert_expand_items("foo! {mod c {}}", "mod c {}"); |
774 | } | 716 | } |
775 | 717 | ||
776 | #[test] | 718 | #[test] |
777 | fn test_all_items() { | 719 | fn test_all_items() { |
778 | let rules = create_rules( | 720 | parse_macro( |
779 | r#" | 721 | r#" |
780 | macro_rules! foo { | 722 | macro_rules! foo { |
781 | ($ ($ i:item)*) => ($ ( | 723 | ($ ($ i:item)*) => ($ ( |
@@ -783,10 +725,8 @@ fn test_all_items() { | |||
783 | )*) | 725 | )*) |
784 | } | 726 | } |
785 | "#, | 727 | "#, |
786 | ); | 728 | ). |
787 | assert_expansion( | 729 | assert_expand_items( |
788 | MacroKind::Items, | ||
789 | &rules, | ||
790 | r#" | 730 | r#" |
791 | foo! { | 731 | foo! { |
792 | extern crate a; | 732 | extern crate a; |
@@ -810,19 +750,19 @@ fn test_all_items() { | |||
810 | 750 | ||
811 | #[test] | 751 | #[test] |
812 | fn test_block() { | 752 | fn test_block() { |
813 | let rules = create_rules( | 753 | parse_macro( |
814 | r#" | 754 | r#" |
815 | macro_rules! foo { | 755 | macro_rules! foo { |
816 | ($ i:block) => { fn foo() $ i } | 756 | ($ i:block) => { fn foo() $ i } |
817 | } | 757 | } |
818 | "#, | 758 | "#, |
819 | ); | 759 | ) |
820 | assert_expansion(MacroKind::Stmts, &rules, "foo! { { 1; } }", "fn foo () {1 ;}"); | 760 | .assert_expand_statements("foo! { { 1; } }", "fn foo () {1 ;}"); |
821 | } | 761 | } |
822 | 762 | ||
823 | #[test] | 763 | #[test] |
824 | fn test_meta() { | 764 | fn test_meta() { |
825 | let rules = create_rules( | 765 | parse_macro( |
826 | r#" | 766 | r#" |
827 | macro_rules! foo { | 767 | macro_rules! foo { |
828 | ($ i:meta) => ( | 768 | ($ i:meta) => ( |
@@ -831,10 +771,8 @@ fn test_meta() { | |||
831 | ) | 771 | ) |
832 | } | 772 | } |
833 | "#, | 773 | "#, |
834 | ); | 774 | ) |
835 | assert_expansion( | 775 | .assert_expand_items( |
836 | MacroKind::Items, | ||
837 | &rules, | ||
838 | r#"foo! { cfg(target_os = "windows") }"#, | 776 | r#"foo! { cfg(target_os = "windows") }"#, |
839 | r#"# [cfg (target_os = "windows")] fn bar () {}"#, | 777 | r#"# [cfg (target_os = "windows")] fn bar () {}"#, |
840 | ); | 778 | ); |
@@ -842,7 +780,7 @@ fn test_meta() { | |||
842 | 780 | ||
843 | #[test] | 781 | #[test] |
844 | fn test_meta_doc_comments() { | 782 | fn test_meta_doc_comments() { |
845 | let rules = create_rules( | 783 | parse_macro( |
846 | r#" | 784 | r#" |
847 | macro_rules! foo { | 785 | macro_rules! foo { |
848 | ($(#[$ i:meta])+) => ( | 786 | ($(#[$ i:meta])+) => ( |
@@ -851,10 +789,8 @@ fn test_meta_doc_comments() { | |||
851 | ) | 789 | ) |
852 | } | 790 | } |
853 | "#, | 791 | "#, |
854 | ); | 792 | ). |
855 | assert_expansion( | 793 | assert_expand_items( |
856 | MacroKind::Items, | ||
857 | &rules, | ||
858 | r#"foo! { | 794 | r#"foo! { |
859 | /// Single Line Doc 1 | 795 | /// Single Line Doc 1 |
860 | /** | 796 | /** |
@@ -867,69 +803,68 @@ fn test_meta_doc_comments() { | |||
867 | 803 | ||
868 | #[test] | 804 | #[test] |
869 | fn test_tt_block() { | 805 | fn test_tt_block() { |
870 | let rules = create_rules( | 806 | parse_macro( |
871 | r#" | 807 | r#" |
872 | macro_rules! foo { | 808 | macro_rules! foo { |
873 | ($ i:tt) => { fn foo() $ i } | 809 | ($ i:tt) => { fn foo() $ i } |
874 | } | 810 | } |
875 | "#, | 811 | "#, |
876 | ); | 812 | ) |
877 | assert_expansion(MacroKind::Items, &rules, r#"foo! { { 1; } }"#, r#"fn foo () {1 ;}"#); | 813 | .assert_expand_items(r#"foo! { { 1; } }"#, r#"fn foo () {1 ;}"#); |
878 | } | 814 | } |
879 | 815 | ||
880 | #[test] | 816 | #[test] |
881 | fn test_tt_group() { | 817 | fn test_tt_group() { |
882 | let rules = create_rules( | 818 | parse_macro( |
883 | r#" | 819 | r#" |
884 | macro_rules! foo { | 820 | macro_rules! foo { |
885 | ($($ i:tt)*) => { $($ i)* } | 821 | ($($ i:tt)*) => { $($ i)* } |
886 | } | 822 | } |
887 | "#, | 823 | "#, |
888 | ); | 824 | ) |
889 | assert_expansion(MacroKind::Items, &rules, r#"foo! { fn foo() {} }"#, r#"fn foo () {}"#); | 825 | .assert_expand_items(r#"foo! { fn foo() {} }"#, r#"fn foo () {}"#); |
890 | } | 826 | } |
891 | #[test] | 827 | #[test] |
892 | fn test_lifetime() { | 828 | fn test_lifetime() { |
893 | let rules = create_rules( | 829 | parse_macro( |
894 | r#" | 830 | r#" |
895 | macro_rules! foo { | 831 | macro_rules! foo { |
896 | ($ lt:lifetime) => { struct Ref<$ lt>{ s: &$ lt str } } | 832 | ($ lt:lifetime) => { struct Ref<$ lt>{ s: &$ lt str } } |
897 | } | 833 | } |
898 | "#, | 834 | "#, |
899 | ); | 835 | ) |
900 | assert_expansion(MacroKind::Items, &rules, r#"foo!{'a}"#, r#"struct Ref <'a > {s : &'a str}"#); | 836 | .assert_expand_items(r#"foo!{'a}"#, r#"struct Ref <'a > {s : &'a str}"#); |
901 | } | 837 | } |
902 | 838 | ||
903 | #[test] | 839 | #[test] |
904 | fn test_literal() { | 840 | fn test_literal() { |
905 | let rules = create_rules( | 841 | parse_macro( |
906 | r#" | 842 | r#" |
907 | macro_rules! foo { | 843 | macro_rules! foo { |
908 | ($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;}; | 844 | ($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;}; |
909 | } | 845 | } |
910 | "#, | 846 | "#, |
911 | ); | 847 | ) |
912 | assert_expansion(MacroKind::Items, &rules, r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#); | 848 | .assert_expand_items(r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#); |
913 | } | 849 | } |
914 | 850 | ||
915 | #[test] | 851 | #[test] |
916 | fn test_vis() { | 852 | fn test_vis() { |
917 | let rules = create_rules( | 853 | parse_macro( |
918 | r#" | 854 | r#" |
919 | macro_rules! foo { | 855 | macro_rules! foo { |
920 | ($ vis:vis $ name:ident) => { $ vis fn $ name() {}}; | 856 | ($ vis:vis $ name:ident) => { $ vis fn $ name() {}}; |
921 | } | 857 | } |
922 | "#, | 858 | "#, |
923 | ); | 859 | ) |
924 | assert_expansion(MacroKind::Items, &rules, r#"foo!(pub foo);"#, r#"pub fn foo () {}"#); | 860 | .assert_expand_items(r#"foo!(pub foo);"#, r#"pub fn foo () {}"#) |
925 | 861 | // test optional cases | |
926 | // test optional casse | 862 | .assert_expand_items(r#"foo!(foo);"#, r#"fn foo () {}"#); |
927 | assert_expansion(MacroKind::Items, &rules, r#"foo!(foo);"#, r#"fn foo () {}"#); | ||
928 | } | 863 | } |
929 | 864 | ||
930 | #[test] | 865 | #[test] |
931 | fn test_inner_macro_rules() { | 866 | fn test_inner_macro_rules() { |
932 | let rules = create_rules( | 867 | parse_macro( |
933 | r#" | 868 | r#" |
934 | macro_rules! foo { | 869 | macro_rules! foo { |
935 | ($a:ident, $b:ident, $c:tt) => { | 870 | ($a:ident, $b:ident, $c:tt) => { |
@@ -945,10 +880,8 @@ macro_rules! foo { | |||
945 | } | 880 | } |
946 | } | 881 | } |
947 | "#, | 882 | "#, |
948 | ); | 883 | ). |
949 | assert_expansion( | 884 | assert_expand_items( |
950 | MacroKind::Items, | ||
951 | &rules, | ||
952 | r#"foo!(x,y, 1);"#, | 885 | r#"foo!(x,y, 1);"#, |
953 | r#"macro_rules ! bar {($ bi : ident) => {fn $ bi () -> u8 {1}}} bar ! (x) ; fn y () -> u8 {1}"#, | 886 | r#"macro_rules ! bar {($ bi : ident) => {fn $ bi () -> u8 {1}}} bar ! (x) ; fn y () -> u8 {1}"#, |
954 | ); | 887 | ); |
@@ -957,7 +890,7 @@ macro_rules! foo { | |||
957 | // The following tests are based on real world situations | 890 | // The following tests are based on real world situations |
958 | #[test] | 891 | #[test] |
959 | fn test_vec() { | 892 | fn test_vec() { |
960 | let rules = create_rules( | 893 | let fixture = parse_macro( |
961 | r#" | 894 | r#" |
962 | macro_rules! vec { | 895 | macro_rules! vec { |
963 | ($($item:expr),*) => { | 896 | ($($item:expr),*) => { |
@@ -972,16 +905,14 @@ fn test_vec() { | |||
972 | } | 905 | } |
973 | "#, | 906 | "#, |
974 | ); | 907 | ); |
975 | assert_expansion(MacroKind::Items, &rules, r#"vec!();"#, r#"{let mut v = Vec :: new () ; v}"#); | 908 | fixture |
976 | assert_expansion( | 909 | .assert_expand_items(r#"vec!();"#, r#"{let mut v = Vec :: new () ; v}"#) |
977 | MacroKind::Items, | 910 | .assert_expand_items( |
978 | &rules, | 911 | r#"vec![1u32,2];"#, |
979 | r#"vec![1u32,2];"#, | 912 | r#"{let mut v = Vec :: new () ; v . push (1u32) ; v . push (2) ; v}"#, |
980 | r#"{let mut v = Vec :: new () ; v . push (1u32) ; v . push (2) ; v}"#, | 913 | ); |
981 | ); | ||
982 | 914 | ||
983 | let expansion = expand(&rules, r#"vec![1u32,2];"#); | 915 | let tree = fixture.expand_expr(r#"vec![1u32,2];"#); |
984 | let tree = token_tree_to_syntax_node(&expansion, FragmentKind::Expr).unwrap().0.syntax_node(); | ||
985 | 916 | ||
986 | assert_eq!( | 917 | assert_eq!( |
987 | format!("{:#?}", tree).trim(), | 918 | format!("{:#?}", tree).trim(), |
@@ -1055,7 +986,7 @@ fn test_vec() { | |||
1055 | fn test_winapi_struct() { | 986 | fn test_winapi_struct() { |
1056 | // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/macros.rs#L366 | 987 | // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/macros.rs#L366 |
1057 | 988 | ||
1058 | let rules = create_rules( | 989 | parse_macro( |
1059 | r#" | 990 | r#" |
1060 | macro_rules! STRUCT { | 991 | macro_rules! STRUCT { |
1061 | ($(#[$attrs:meta])* struct $name:ident { | 992 | ($(#[$attrs:meta])* struct $name:ident { |
@@ -1077,17 +1008,19 @@ macro_rules! STRUCT { | |||
1077 | ); | 1008 | ); |
1078 | } | 1009 | } |
1079 | "#, | 1010 | "#, |
1080 | ); | 1011 | ). |
1081 | // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/shared/d3d9caps.rs | 1012 | // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/shared/d3d9caps.rs |
1082 | assert_expansion(MacroKind::Items, &rules, r#"STRUCT!{struct D3DVSHADERCAPS2_0 {Caps: u8,}}"#, | 1013 | assert_expand_items(r#"STRUCT!{struct D3DVSHADERCAPS2_0 {Caps: u8,}}"#, |
1083 | "# [repr (C)] # [derive (Copy)] pub struct D3DVSHADERCAPS2_0 {pub Caps : u8 ,} impl Clone for D3DVSHADERCAPS2_0 {# [inline] fn clone (& self) -> D3DVSHADERCAPS2_0 {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DVSHADERCAPS2_0 {# [inline] fn default () -> D3DVSHADERCAPS2_0 {unsafe {$crate :: _core :: mem :: zeroed ()}}}"); | 1014 | "# [repr (C)] # [derive (Copy)] pub struct D3DVSHADERCAPS2_0 {pub Caps : u8 ,} impl Clone for D3DVSHADERCAPS2_0 {# [inline] fn clone (& self) -> D3DVSHADERCAPS2_0 {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DVSHADERCAPS2_0 {# [inline] fn default () -> D3DVSHADERCAPS2_0 {unsafe {$crate :: _core :: mem :: zeroed ()}}}" |
1084 | assert_expansion(MacroKind::Items, &rules, r#"STRUCT!{#[cfg_attr(target_arch = "x86", repr(packed))] struct D3DCONTENTPROTECTIONCAPS {Caps : u8 ,}}"#, | 1015 | ) |
1085 | "# [repr (C)] # [derive (Copy)] # [cfg_attr (target_arch = \"x86\" , repr (packed))] pub struct D3DCONTENTPROTECTIONCAPS {pub Caps : u8 ,} impl Clone for D3DCONTENTPROTECTIONCAPS {# [inline] fn clone (& self) -> D3DCONTENTPROTECTIONCAPS {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DCONTENTPROTECTIONCAPS {# [inline] fn default () -> D3DCONTENTPROTECTIONCAPS {unsafe {$crate :: _core :: mem :: zeroed ()}}}"); | 1016 | .assert_expand_items(r#"STRUCT!{#[cfg_attr(target_arch = "x86", repr(packed))] struct D3DCONTENTPROTECTIONCAPS {Caps : u8 ,}}"#, |
1017 | "# [repr (C)] # [derive (Copy)] # [cfg_attr (target_arch = \"x86\" , repr (packed))] pub struct D3DCONTENTPROTECTIONCAPS {pub Caps : u8 ,} impl Clone for D3DCONTENTPROTECTIONCAPS {# [inline] fn clone (& self) -> D3DCONTENTPROTECTIONCAPS {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DCONTENTPROTECTIONCAPS {# [inline] fn default () -> D3DCONTENTPROTECTIONCAPS {unsafe {$crate :: _core :: mem :: zeroed ()}}}" | ||
1018 | ); | ||
1086 | } | 1019 | } |
1087 | 1020 | ||
1088 | #[test] | 1021 | #[test] |
1089 | fn test_int_base() { | 1022 | fn test_int_base() { |
1090 | let rules = create_rules( | 1023 | parse_macro( |
1091 | r#" | 1024 | r#" |
1092 | macro_rules! int_base { | 1025 | macro_rules! int_base { |
1093 | ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { | 1026 | ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { |
@@ -1100,17 +1033,15 @@ macro_rules! int_base { | |||
1100 | } | 1033 | } |
1101 | } | 1034 | } |
1102 | "#, | 1035 | "#, |
1103 | ); | 1036 | ).assert_expand_items(r#" int_base!{Binary for isize as usize -> Binary}"#, |
1104 | |||
1105 | assert_expansion(MacroKind::Items, &rules, r#" int_base!{Binary for isize as usize -> Binary}"#, | ||
1106 | "# [stable (feature = \"rust1\" , since = \"1.0.0\")] impl fmt ::Binary for isize {fn fmt (& self , f : & mut fmt :: Formatter < \'_ >) -> fmt :: Result {Binary . fmt_int (* self as usize , f)}}" | 1037 | "# [stable (feature = \"rust1\" , since = \"1.0.0\")] impl fmt ::Binary for isize {fn fmt (& self , f : & mut fmt :: Formatter < \'_ >) -> fmt :: Result {Binary . fmt_int (* self as usize , f)}}" |
1107 | ); | 1038 | ); |
1108 | } | 1039 | } |
1109 | 1040 | ||
1110 | #[test] | 1041 | #[test] |
1111 | fn test_generate_pattern_iterators() { | 1042 | fn test_generate_pattern_iterators() { |
1112 | // from https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/str/mod.rs | 1043 | // from https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/str/mod.rs |
1113 | let rules = create_rules( | 1044 | parse_macro( |
1114 | r#" | 1045 | r#" |
1115 | macro_rules! generate_pattern_iterators { | 1046 | macro_rules! generate_pattern_iterators { |
1116 | { double ended; with $(#[$common_stability_attribute:meta])*, | 1047 | { double ended; with $(#[$common_stability_attribute:meta])*, |
@@ -1121,11 +1052,7 @@ macro_rules! generate_pattern_iterators { | |||
1121 | } | 1052 | } |
1122 | } | 1053 | } |
1123 | "#, | 1054 | "#, |
1124 | ); | 1055 | ).assert_expand_items( |
1125 | |||
1126 | assert_expansion( | ||
1127 | MacroKind::Items, | ||
1128 | &rules, | ||
1129 | r#"generate_pattern_iterators ! ( double ended ; with # [ stable ( feature = "rust1" , since = "1.0.0" ) ] , Split , RSplit , & 'a str );"#, | 1056 | r#"generate_pattern_iterators ! ( double ended ; with # [ stable ( feature = "rust1" , since = "1.0.0" ) ] , Split , RSplit , & 'a str );"#, |
1130 | "fn foo () {}", | 1057 | "fn foo () {}", |
1131 | ); | 1058 | ); |
@@ -1134,7 +1061,7 @@ macro_rules! generate_pattern_iterators { | |||
1134 | #[test] | 1061 | #[test] |
1135 | fn test_impl_fn_for_zst() { | 1062 | fn test_impl_fn_for_zst() { |
1136 | // from https://github.com/rust-lang/rust/blob/5d20ff4d2718c820632b38c1e49d4de648a9810b/src/libcore/internal_macros.rs | 1063 | // from https://github.com/rust-lang/rust/blob/5d20ff4d2718c820632b38c1e49d4de648a9810b/src/libcore/internal_macros.rs |
1137 | let rules = create_rules( | 1064 | parse_macro( |
1138 | r#" | 1065 | r#" |
1139 | macro_rules! impl_fn_for_zst { | 1066 | macro_rules! impl_fn_for_zst { |
1140 | { $( $( #[$attr: meta] )* | 1067 | { $( $( #[$attr: meta] )* |
@@ -1175,9 +1102,7 @@ $body: block; )+ | |||
1175 | } | 1102 | } |
1176 | } | 1103 | } |
1177 | "#, | 1104 | "#, |
1178 | ); | 1105 | ).assert_expand_items(r#" |
1179 | |||
1180 | assert_expansion(MacroKind::Items, &rules, r#" | ||
1181 | impl_fn_for_zst ! { | 1106 | impl_fn_for_zst ! { |
1182 | # [ derive ( Clone ) ] | 1107 | # [ derive ( Clone ) ] |
1183 | struct CharEscapeDebugContinue impl Fn = | c : char | -> char :: EscapeDebug { | 1108 | struct CharEscapeDebugContinue impl Fn = | c : char | -> char :: EscapeDebug { |
@@ -1194,13 +1119,14 @@ impl_fn_for_zst ! { | |||
1194 | } ; | 1119 | } ; |
1195 | } | 1120 | } |
1196 | "#, | 1121 | "#, |
1197 | "# [derive (Clone)] struct CharEscapeDebugContinue ; impl Fn < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDebug {{c . escape_debug_ext (false)}}} impl FnMut < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDebugContinue {type Output = char :: EscapeDebug ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeUnicode ; impl Fn < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeUnicode {{c . escape_unicode ()}}} impl FnMut < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeUnicode {type Output = char :: EscapeUnicode ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeDefault ; impl Fn < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDefault {{c . escape_default ()}}} impl FnMut < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDefault {type Output = char :: EscapeDefault ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (& self , (c ,))}}"); | 1122 | "# [derive (Clone)] struct CharEscapeDebugContinue ; impl Fn < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDebug {{c . escape_debug_ext (false)}}} impl FnMut < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDebugContinue {type Output = char :: EscapeDebug ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeUnicode ; impl Fn < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeUnicode {{c . escape_unicode ()}}} impl FnMut < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeUnicode {type Output = char :: EscapeUnicode ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeDefault ; impl Fn < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDefault {{c . escape_default ()}}} impl FnMut < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDefault {type Output = char :: EscapeDefault ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (& self , (c ,))}}" |
1123 | ); | ||
1198 | } | 1124 | } |
1199 | 1125 | ||
1200 | #[test] | 1126 | #[test] |
1201 | fn test_impl_nonzero_fmt() { | 1127 | fn test_impl_nonzero_fmt() { |
1202 | // from https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/num/mod.rs#L12 | 1128 | // from https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/num/mod.rs#L12 |
1203 | let rules = create_rules( | 1129 | parse_macro( |
1204 | r#" | 1130 | r#" |
1205 | macro_rules! impl_nonzero_fmt { | 1131 | macro_rules! impl_nonzero_fmt { |
1206 | ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { | 1132 | ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { |
@@ -1208,11 +1134,7 @@ fn test_impl_nonzero_fmt() { | |||
1208 | } | 1134 | } |
1209 | } | 1135 | } |
1210 | "#, | 1136 | "#, |
1211 | ); | 1137 | ).assert_expand_items( |
1212 | |||
1213 | assert_expansion( | ||
1214 | MacroKind::Items, | ||
1215 | &rules, | ||
1216 | r#"impl_nonzero_fmt! { # [stable(feature= "nonzero",since="1.28.0")] (Debug,Display,Binary,Octal,LowerHex,UpperHex) for NonZeroU8}"#, | 1138 | r#"impl_nonzero_fmt! { # [stable(feature= "nonzero",since="1.28.0")] (Debug,Display,Binary,Octal,LowerHex,UpperHex) for NonZeroU8}"#, |
1217 | "fn foo () {}", | 1139 | "fn foo () {}", |
1218 | ); | 1140 | ); |
@@ -1221,7 +1143,7 @@ fn test_impl_nonzero_fmt() { | |||
1221 | #[test] | 1143 | #[test] |
1222 | fn test_cfg_if_items() { | 1144 | fn test_cfg_if_items() { |
1223 | // from https://github.com/rust-lang/rust/blob/33fe1131cadba69d317156847be9a402b89f11bb/src/libstd/macros.rs#L986 | 1145 | // from https://github.com/rust-lang/rust/blob/33fe1131cadba69d317156847be9a402b89f11bb/src/libstd/macros.rs#L986 |
1224 | let rules = create_rules( | 1146 | parse_macro( |
1225 | r#" | 1147 | r#" |
1226 | macro_rules! __cfg_if_items { | 1148 | macro_rules! __cfg_if_items { |
1227 | (($($not:meta,)*) ; ) => {}; | 1149 | (($($not:meta,)*) ; ) => {}; |
@@ -1230,11 +1152,7 @@ fn test_cfg_if_items() { | |||
1230 | } | 1152 | } |
1231 | } | 1153 | } |
1232 | "#, | 1154 | "#, |
1233 | ); | 1155 | ).assert_expand_items( |
1234 | |||
1235 | assert_expansion( | ||
1236 | MacroKind::Items, | ||
1237 | &rules, | ||
1238 | r#"__cfg_if_items ! { ( rustdoc , ) ; ( ( ) ( # [ cfg ( any ( target_os = "redox" , unix ) ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as unix ; # [ cfg ( windows ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as windows ; # [ cfg ( any ( target_os = "linux" , target_os = "l4re" ) ) ] pub mod linux ; ) ) , }"#, | 1156 | r#"__cfg_if_items ! { ( rustdoc , ) ; ( ( ) ( # [ cfg ( any ( target_os = "redox" , unix ) ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as unix ; # [ cfg ( windows ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as windows ; # [ cfg ( any ( target_os = "linux" , target_os = "l4re" ) ) ] pub mod linux ; ) ) , }"#, |
1239 | "__cfg_if_items ! {(rustdoc ,) ;}", | 1157 | "__cfg_if_items ! {(rustdoc ,) ;}", |
1240 | ); | 1158 | ); |
@@ -1243,7 +1161,7 @@ fn test_cfg_if_items() { | |||
1243 | #[test] | 1161 | #[test] |
1244 | fn test_cfg_if_main() { | 1162 | fn test_cfg_if_main() { |
1245 | // from https://github.com/rust-lang/rust/blob/3d211248393686e0f73851fc7548f6605220fbe1/src/libpanic_unwind/macros.rs#L9 | 1163 | // from https://github.com/rust-lang/rust/blob/3d211248393686e0f73851fc7548f6605220fbe1/src/libpanic_unwind/macros.rs#L9 |
1246 | let rules = create_rules( | 1164 | parse_macro( |
1247 | r#" | 1165 | r#" |
1248 | macro_rules! cfg_if { | 1166 | macro_rules! cfg_if { |
1249 | ($( | 1167 | ($( |
@@ -1264,9 +1182,7 @@ fn test_cfg_if_main() { | |||
1264 | }; | 1182 | }; |
1265 | } | 1183 | } |
1266 | "#, | 1184 | "#, |
1267 | ); | 1185 | ).assert_expand_items(r#" |
1268 | |||
1269 | assert_expansion(MacroKind::Items, &rules, r#" | ||
1270 | cfg_if ! { | 1186 | cfg_if ! { |
1271 | if # [ cfg ( target_env = "msvc" ) ] { | 1187 | if # [ cfg ( target_env = "msvc" ) ] { |
1272 | // no extra unwinder support needed | 1188 | // no extra unwinder support needed |
@@ -1278,11 +1194,8 @@ cfg_if ! { | |||
1278 | } | 1194 | } |
1279 | } | 1195 | } |
1280 | "#, | 1196 | "#, |
1281 | "__cfg_if_items ! {() ; ((target_env = \"msvc\") ()) , ((all (target_arch = \"wasm32\" , not (target_os = \"emscripten\"))) ()) , (() (mod libunwind ; pub use libunwind :: * ;)) ,}"); | 1197 | "__cfg_if_items ! {() ; ((target_env = \"msvc\") ()) , ((all (target_arch = \"wasm32\" , not (target_os = \"emscripten\"))) ()) , (() (mod libunwind ; pub use libunwind :: * ;)) ,}" |
1282 | 1198 | ).assert_expand_items( | |
1283 | assert_expansion( | ||
1284 | MacroKind::Items, | ||
1285 | &rules, | ||
1286 | r#" | 1199 | r#" |
1287 | cfg_if ! { @ __apply cfg ( all ( not ( any ( not ( any ( target_os = "solaris" , target_os = "illumos" ) ) ) ) ) ) , } | 1200 | cfg_if ! { @ __apply cfg ( all ( not ( any ( not ( any ( target_os = "solaris" , target_os = "illumos" ) ) ) ) ) ) , } |
1288 | "#, | 1201 | "#, |
@@ -1293,7 +1206,7 @@ cfg_if ! { @ __apply cfg ( all ( not ( any ( not ( any ( target_os = "solaris" , | |||
1293 | #[test] | 1206 | #[test] |
1294 | fn test_proptest_arbitrary() { | 1207 | fn test_proptest_arbitrary() { |
1295 | // from https://github.com/AltSysrq/proptest/blob/d1c4b049337d2f75dd6f49a095115f7c532e5129/proptest/src/arbitrary/macros.rs#L16 | 1208 | // from https://github.com/AltSysrq/proptest/blob/d1c4b049337d2f75dd6f49a095115f7c532e5129/proptest/src/arbitrary/macros.rs#L16 |
1296 | let rules = create_rules( | 1209 | parse_macro( |
1297 | r#" | 1210 | r#" |
1298 | macro_rules! arbitrary { | 1211 | macro_rules! arbitrary { |
1299 | ([$($bounds : tt)*] $typ: ty, $strat: ty, $params: ty; | 1212 | ([$($bounds : tt)*] $typ: ty, $strat: ty, $params: ty; |
@@ -1308,22 +1221,21 @@ macro_rules! arbitrary { | |||
1308 | }; | 1221 | }; |
1309 | 1222 | ||
1310 | }"#, | 1223 | }"#, |
1311 | ); | 1224 | ).assert_expand_items(r#"arbitrary ! ( [ A : Arbitrary ] |
1312 | |||
1313 | assert_expansion(MacroKind::Items, &rules, r#"arbitrary ! ( [ A : Arbitrary ] | ||
1314 | Vec < A > , | 1225 | Vec < A > , |
1315 | VecStrategy < A :: Strategy > , | 1226 | VecStrategy < A :: Strategy > , |
1316 | RangedParams1 < A :: Parameters > ; | 1227 | RangedParams1 < A :: Parameters > ; |
1317 | args => { let product_unpack ! [ range , a ] = args ; vec ( any_with :: < A > ( a ) , range ) } | 1228 | args => { let product_unpack ! [ range , a ] = args ; vec ( any_with :: < A > ( a ) , range ) } |
1318 | ) ;"#, | 1229 | ) ;"#, |
1319 | "impl <A : Arbitrary > $crate :: arbitrary :: Arbitrary for Vec < A > {type Parameters = RangedParams1 < A :: Parameters > ; type Strategy = VecStrategy < A :: Strategy > ; fn arbitrary_with (args : Self :: Parameters) -> Self :: Strategy {{let product_unpack ! [range , a] = args ; vec (any_with :: < A > (a) , range)}}}"); | 1230 | "impl <A : Arbitrary > $crate :: arbitrary :: Arbitrary for Vec < A > {type Parameters = RangedParams1 < A :: Parameters > ; type Strategy = VecStrategy < A :: Strategy > ; fn arbitrary_with (args : Self :: Parameters) -> Self :: Strategy {{let product_unpack ! [range , a] = args ; vec (any_with :: < A > (a) , range)}}}" |
1231 | ); | ||
1320 | } | 1232 | } |
1321 | 1233 | ||
1322 | #[test] | 1234 | #[test] |
1323 | fn test_old_ridl() { | 1235 | fn test_old_ridl() { |
1324 | // This is from winapi 2.8, which do not have a link from github | 1236 | // This is from winapi 2.8, which do not have a link from github |
1325 | // | 1237 | // |
1326 | let rules = create_rules( | 1238 | let expanded = parse_macro( |
1327 | r#" | 1239 | r#" |
1328 | #[macro_export] | 1240 | #[macro_export] |
1329 | macro_rules! RIDL { | 1241 | macro_rules! RIDL { |
@@ -1339,21 +1251,17 @@ macro_rules! RIDL { | |||
1339 | } | 1251 | } |
1340 | }; | 1252 | }; |
1341 | }"#, | 1253 | }"#, |
1342 | ); | 1254 | ).expand_tt(r#" |
1255 | RIDL!{interface ID3D11Asynchronous(ID3D11AsynchronousVtbl): ID3D11DeviceChild(ID3D11DeviceChildVtbl) { | ||
1256 | fn GetDataSize(&mut self) -> UINT | ||
1257 | }}"#); | ||
1343 | 1258 | ||
1344 | let expanded = expand( | ||
1345 | &rules, | ||
1346 | r#" | ||
1347 | RIDL!{interface ID3D11Asynchronous(ID3D11AsynchronousVtbl): ID3D11DeviceChild(ID3D11DeviceChildVtbl) { | ||
1348 | fn GetDataSize(&mut self) -> UINT | ||
1349 | }}"#, | ||
1350 | ); | ||
1351 | assert_eq!(expanded.to_string(), "impl ID3D11Asynchronous {pub unsafe fn GetDataSize (& mut self) -> UINT {((* self . lpVtbl) .GetDataSize) (self)}}"); | 1259 | assert_eq!(expanded.to_string(), "impl ID3D11Asynchronous {pub unsafe fn GetDataSize (& mut self) -> UINT {((* self . lpVtbl) .GetDataSize) (self)}}"); |
1352 | } | 1260 | } |
1353 | 1261 | ||
1354 | #[test] | 1262 | #[test] |
1355 | fn test_quick_error() { | 1263 | fn test_quick_error() { |
1356 | let rules = create_rules( | 1264 | let expanded = parse_macro( |
1357 | r#" | 1265 | r#" |
1358 | macro_rules! quick_error { | 1266 | macro_rules! quick_error { |
1359 | 1267 | ||
@@ -1376,10 +1284,8 @@ macro_rules! quick_error { | |||
1376 | 1284 | ||
1377 | } | 1285 | } |
1378 | "#, | 1286 | "#, |
1379 | ); | 1287 | ) |
1380 | 1288 | .expand_tt( | |
1381 | let expanded = expand( | ||
1382 | &rules, | ||
1383 | r#" | 1289 | r#" |
1384 | quick_error ! (SORT [enum Wrapped # [derive (Debug)]] items [ | 1290 | quick_error ! (SORT [enum Wrapped # [derive (Debug)]] items [ |
1385 | => One : UNIT [] {} | 1291 | => One : UNIT [] {} |
@@ -1393,7 +1299,7 @@ quick_error ! (SORT [enum Wrapped # [derive (Debug)]] items [ | |||
1393 | 1299 | ||
1394 | #[test] | 1300 | #[test] |
1395 | fn test_empty_repeat_vars_in_empty_repeat_vars() { | 1301 | fn test_empty_repeat_vars_in_empty_repeat_vars() { |
1396 | let rules = create_rules( | 1302 | parse_macro( |
1397 | r#" | 1303 | r#" |
1398 | macro_rules! delegate_impl { | 1304 | macro_rules! delegate_impl { |
1399 | ([$self_type:ident, $self_wrap:ty, $self_map:ident] | 1305 | ([$self_type:ident, $self_wrap:ty, $self_map:ident] |
@@ -1440,120 +1346,117 @@ macro_rules! delegate_impl { | |||
1440 | } | 1346 | } |
1441 | } | 1347 | } |
1442 | "#, | 1348 | "#, |
1443 | ); | 1349 | ).assert_expand_items( |
1444 | |||
1445 | assert_expansion( | ||
1446 | MacroKind::Items, | ||
1447 | &rules, | ||
1448 | r#"delegate_impl ! {[G , & 'a mut G , deref] pub trait Data : GraphBase {@ section type type NodeWeight ;}}"#, | 1350 | r#"delegate_impl ! {[G , & 'a mut G , deref] pub trait Data : GraphBase {@ section type type NodeWeight ;}}"#, |
1449 | "impl <> Data for & \'a mut G where G : Data {}", | 1351 | "impl <> Data for & \'a mut G where G : Data {}", |
1450 | ); | 1352 | ); |
1451 | } | 1353 | } |
1452 | 1354 | ||
1453 | pub(crate) fn create_rules(macro_definition: &str) -> MacroRules { | 1355 | #[test] |
1454 | let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap(); | 1356 | fn expr_interpolation() { |
1455 | let macro_definition = | 1357 | let expanded = parse_macro( |
1456 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | 1358 | r#" |
1359 | macro_rules! id { | ||
1360 | ($expr:expr) => { | ||
1361 | map($expr) | ||
1362 | } | ||
1363 | } | ||
1364 | "#, | ||
1365 | ) | ||
1366 | .expand_expr("id!(x + foo);"); | ||
1457 | 1367 | ||
1458 | let (definition_tt, _) = ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); | 1368 | assert_eq!(expanded.to_string(), "map(x+foo)"); |
1459 | crate::MacroRules::parse(&definition_tt).unwrap() | ||
1460 | } | 1369 | } |
1461 | 1370 | ||
1462 | pub(crate) fn expand(rules: &MacroRules, invocation: &str) -> tt::Subtree { | 1371 | pub(crate) struct MacroFixture { |
1463 | let source_file = ast::SourceFile::parse(invocation).ok().unwrap(); | 1372 | rules: MacroRules, |
1464 | let macro_invocation = | 1373 | } |
1465 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | ||
1466 | 1374 | ||
1467 | let (invocation_tt, _) = ast_to_token_tree(¯o_invocation.token_tree().unwrap()).unwrap(); | 1375 | impl MacroFixture { |
1376 | pub(crate) fn expand_tt(&self, invocation: &str) -> tt::Subtree { | ||
1377 | let source_file = ast::SourceFile::parse(invocation).ok().unwrap(); | ||
1378 | let macro_invocation = | ||
1379 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | ||
1468 | 1380 | ||
1469 | rules.expand(&invocation_tt).unwrap() | 1381 | let (invocation_tt, _) = |
1470 | } | 1382 | ast_to_token_tree(¯o_invocation.token_tree().unwrap()).unwrap(); |
1471 | 1383 | ||
1472 | pub(crate) fn expand_and_map( | 1384 | self.rules.expand(&invocation_tt).unwrap() |
1473 | rules: &MacroRules, | 1385 | } |
1474 | invocation: &str, | ||
1475 | ) -> (tt::Subtree, (TokenMap, String)) { | ||
1476 | let source_file = ast::SourceFile::parse(invocation).ok().unwrap(); | ||
1477 | let macro_invocation = | ||
1478 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | ||
1479 | 1386 | ||
1480 | let (invocation_tt, _) = ast_to_token_tree(¯o_invocation.token_tree().unwrap()).unwrap(); | 1387 | fn expand_items(&self, invocation: &str) -> SyntaxNode { |
1481 | let expanded = rules.expand(&invocation_tt).unwrap(); | 1388 | let expanded = self.expand_tt(invocation); |
1389 | token_tree_to_syntax_node(&expanded, FragmentKind::Items).unwrap().0.syntax_node() | ||
1390 | } | ||
1482 | 1391 | ||
1483 | let (node, expanded_token_tree) = | 1392 | fn expand_statements(&self, invocation: &str) -> SyntaxNode { |
1484 | token_tree_to_syntax_node(&expanded, FragmentKind::Items).unwrap(); | 1393 | let expanded = self.expand_tt(invocation); |
1394 | token_tree_to_syntax_node(&expanded, FragmentKind::Statements).unwrap().0.syntax_node() | ||
1395 | } | ||
1485 | 1396 | ||
1486 | (expanded, (expanded_token_tree, node.syntax_node().to_string())) | 1397 | fn expand_expr(&self, invocation: &str) -> SyntaxNode { |
1487 | } | 1398 | let expanded = self.expand_tt(invocation); |
1399 | token_tree_to_syntax_node(&expanded, FragmentKind::Expr).unwrap().0.syntax_node() | ||
1400 | } | ||
1488 | 1401 | ||
1489 | pub(crate) enum MacroKind { | 1402 | fn assert_expand_tt(&self, invocation: &str, expected: &str) { |
1490 | Items, | 1403 | let expansion = self.expand_tt(invocation); |
1491 | Stmts, | 1404 | assert_eq!(expansion.to_string(), expected); |
1492 | } | 1405 | } |
1493 | 1406 | ||
1494 | pub(crate) fn assert_expansion( | 1407 | fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture { |
1495 | kind: MacroKind, | 1408 | self.assert_expansion(FragmentKind::Items, invocation, expected); |
1496 | rules: &MacroRules, | 1409 | self |
1497 | invocation: &str, | 1410 | } |
1498 | expected: &str, | ||
1499 | ) -> tt::Subtree { | ||
1500 | let expanded = expand(rules, invocation); | ||
1501 | assert_eq!(expanded.to_string(), expected); | ||
1502 | 1411 | ||
1503 | let expected = expected.replace("$crate", "C_C__C"); | 1412 | fn assert_expand_statements(&self, invocation: &str, expected: &str) -> &MacroFixture { |
1413 | self.assert_expansion(FragmentKind::Statements, invocation, expected); | ||
1414 | self | ||
1415 | } | ||
1504 | 1416 | ||
1505 | // wrap the given text to a macro call | 1417 | fn assert_expansion(&self, kind: FragmentKind, invocation: &str, expected: &str) { |
1506 | let expected = { | 1418 | let expanded = self.expand_tt(invocation); |
1507 | let wrapped = format!("wrap_macro!( {} )", expected); | 1419 | assert_eq!(expanded.to_string(), expected); |
1508 | let wrapped = ast::SourceFile::parse(&wrapped); | 1420 | |
1509 | let wrapped = wrapped.tree().syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); | 1421 | let expected = expected.replace("$crate", "C_C__C"); |
1510 | let mut wrapped = ast_to_token_tree(&wrapped).unwrap().0; | 1422 | |
1511 | wrapped.delimiter = None; | 1423 | // wrap the given text to a macro call |
1512 | wrapped | 1424 | let expected = { |
1513 | }; | 1425 | let wrapped = format!("wrap_macro!( {} )", expected); |
1514 | let (expanded_tree, expected_tree) = match kind { | 1426 | let wrapped = ast::SourceFile::parse(&wrapped); |
1515 | MacroKind::Items => { | 1427 | let wrapped = |
1516 | let expanded_tree = | 1428 | wrapped.tree().syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); |
1517 | token_tree_to_syntax_node(&expanded, FragmentKind::Items).unwrap().0.syntax_node(); | 1429 | let mut wrapped = ast_to_token_tree(&wrapped).unwrap().0; |
1518 | let expected_tree = | 1430 | wrapped.delimiter = None; |
1519 | token_tree_to_syntax_node(&expected, FragmentKind::Items).unwrap().0.syntax_node(); | 1431 | wrapped |
1520 | 1432 | }; | |
1521 | ( | ||
1522 | debug_dump_ignore_spaces(&expanded_tree).trim().to_string(), | ||
1523 | debug_dump_ignore_spaces(&expected_tree).trim().to_string(), | ||
1524 | ) | ||
1525 | } | ||
1526 | 1433 | ||
1527 | MacroKind::Stmts => { | 1434 | let expanded_tree = token_tree_to_syntax_node(&expanded, kind).unwrap().0.syntax_node(); |
1528 | let expanded_tree = token_tree_to_syntax_node(&expanded, FragmentKind::Statements) | 1435 | let expanded_tree = debug_dump_ignore_spaces(&expanded_tree).trim().to_string(); |
1529 | .unwrap() | ||
1530 | .0 | ||
1531 | .syntax_node(); | ||
1532 | let expected_tree = token_tree_to_syntax_node(&expected, FragmentKind::Statements) | ||
1533 | .unwrap() | ||
1534 | .0 | ||
1535 | .syntax_node(); | ||
1536 | |||
1537 | ( | ||
1538 | debug_dump_ignore_spaces(&expanded_tree).trim().to_string(), | ||
1539 | debug_dump_ignore_spaces(&expected_tree).trim().to_string(), | ||
1540 | ) | ||
1541 | } | ||
1542 | }; | ||
1543 | 1436 | ||
1544 | let expected_tree = expected_tree.replace("C_C__C", "$crate"); | 1437 | let expected_tree = token_tree_to_syntax_node(&expected, kind).unwrap().0.syntax_node(); |
1545 | assert_eq!( | 1438 | let expected_tree = debug_dump_ignore_spaces(&expected_tree).trim().to_string(); |
1546 | expanded_tree, expected_tree, | ||
1547 | "\nleft:\n{}\nright:\n{}", | ||
1548 | expanded_tree, expected_tree, | ||
1549 | ); | ||
1550 | 1439 | ||
1551 | expanded | 1440 | let expected_tree = expected_tree.replace("C_C__C", "$crate"); |
1441 | assert_eq!( | ||
1442 | expanded_tree, expected_tree, | ||
1443 | "\nleft:\n{}\nright:\n{}", | ||
1444 | expanded_tree, expected_tree, | ||
1445 | ); | ||
1446 | } | ||
1552 | } | 1447 | } |
1553 | 1448 | ||
1554 | pub fn debug_dump_ignore_spaces(node: &ra_syntax::SyntaxNode) -> String { | 1449 | pub(crate) fn parse_macro(macro_definition: &str) -> MacroFixture { |
1555 | use std::fmt::Write; | 1450 | let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap(); |
1451 | let macro_definition = | ||
1452 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | ||
1453 | |||
1454 | let (definition_tt, _) = ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); | ||
1455 | let rules = MacroRules::parse(&definition_tt).unwrap(); | ||
1456 | MacroFixture { rules } | ||
1457 | } | ||
1556 | 1458 | ||
1459 | fn debug_dump_ignore_spaces(node: &ra_syntax::SyntaxNode) -> String { | ||
1557 | let mut level = 0; | 1460 | let mut level = 0; |
1558 | let mut buf = String::new(); | 1461 | let mut buf = String::new(); |
1559 | macro_rules! indent { | 1462 | macro_rules! indent { |
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index 6e9e212b7..22f64a9f4 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs | |||
@@ -264,7 +264,7 @@ fn name_r(p: &mut Parser, recovery: TokenSet) { | |||
264 | } | 264 | } |
265 | 265 | ||
266 | fn name(p: &mut Parser) { | 266 | fn name(p: &mut Parser) { |
267 | name_r(p, TokenSet::empty()) | 267 | name_r(p, TokenSet::EMPTY) |
268 | } | 268 | } |
269 | 269 | ||
270 | fn name_ref(p: &mut Parser) { | 270 | fn name_ref(p: &mut Parser) { |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 09f0a2d98..4ac1d6334 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -43,6 +43,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = | |||
43 | T!['('], | 43 | T!['('], |
44 | T!['{'], | 44 | T!['{'], |
45 | T!['['], | 45 | T!['['], |
46 | L_DOLLAR, | ||
46 | T![|], | 47 | T![|], |
47 | T![move], | 48 | T![move], |
48 | T![box], | 49 | T![box], |
@@ -443,7 +444,7 @@ fn match_arm(p: &mut Parser) -> BlockLike { | |||
443 | // } | 444 | // } |
444 | attributes::outer_attributes(p); | 445 | attributes::outer_attributes(p); |
445 | 446 | ||
446 | patterns::pattern_list_r(p, TokenSet::empty()); | 447 | patterns::pattern_list_r(p, TokenSet::EMPTY); |
447 | if p.at(T![if]) { | 448 | if p.at(T![if]) { |
448 | match_guard(p); | 449 | match_guard(p); |
449 | } | 450 | } |
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs index 45241e566..65134277e 100644 --- a/crates/ra_parser/src/lib.rs +++ b/crates/ra_parser/src/lib.rs | |||
@@ -83,6 +83,7 @@ pub fn parse(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | |||
83 | parse_from_tokens(token_source, tree_sink, grammar::root); | 83 | parse_from_tokens(token_source, tree_sink, grammar::root); |
84 | } | 84 | } |
85 | 85 | ||
86 | #[derive(Clone, Copy)] | ||
86 | pub enum FragmentKind { | 87 | pub enum FragmentKind { |
87 | Path, | 88 | Path, |
88 | Expr, | 89 | Expr, |
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs index dafd5247b..1071c46dc 100644 --- a/crates/ra_parser/src/parser.rs +++ b/crates/ra_parser/src/parser.rs | |||
@@ -208,7 +208,7 @@ impl<'t> Parser<'t> { | |||
208 | 208 | ||
209 | /// Create an error node and consume the next token. | 209 | /// Create an error node and consume the next token. |
210 | pub(crate) fn err_and_bump(&mut self, message: &str) { | 210 | pub(crate) fn err_and_bump(&mut self, message: &str) { |
211 | self.err_recover(message, TokenSet::empty()); | 211 | self.err_recover(message, TokenSet::EMPTY); |
212 | } | 212 | } |
213 | 213 | ||
214 | /// Create an error node and consume the next token. | 214 | /// Create an error node and consume the next token. |
diff --git a/crates/ra_parser/src/token_set.rs b/crates/ra_parser/src/token_set.rs index 2a6952c01..994017acf 100644 --- a/crates/ra_parser/src/token_set.rs +++ b/crates/ra_parser/src/token_set.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! A bit-set of `SyntaxKind`s. |
2 | 2 | ||
3 | use crate::SyntaxKind; | 3 | use crate::SyntaxKind; |
4 | 4 | ||
@@ -7,9 +7,7 @@ use crate::SyntaxKind; | |||
7 | pub(crate) struct TokenSet(u128); | 7 | pub(crate) struct TokenSet(u128); |
8 | 8 | ||
9 | impl TokenSet { | 9 | impl TokenSet { |
10 | pub(crate) const fn empty() -> TokenSet { | 10 | pub(crate) const EMPTY: TokenSet = TokenSet(0); |
11 | TokenSet(0) | ||
12 | } | ||
13 | 11 | ||
14 | pub(crate) const fn singleton(kind: SyntaxKind) -> TokenSet { | 12 | pub(crate) const fn singleton(kind: SyntaxKind) -> TokenSet { |
15 | TokenSet(mask(kind)) | 13 | TokenSet(mask(kind)) |
@@ -30,7 +28,7 @@ const fn mask(kind: SyntaxKind) -> u128 { | |||
30 | 28 | ||
31 | #[macro_export] | 29 | #[macro_export] |
32 | macro_rules! token_set { | 30 | macro_rules! token_set { |
33 | ($($t:expr),*) => { TokenSet::empty()$(.union(TokenSet::singleton($t)))* }; | 31 | ($($t:expr),*) => { TokenSet::EMPTY$(.union(TokenSet::singleton($t)))* }; |
34 | ($($t:expr),* ,) => { token_set!($($t),*) }; | 32 | ($($t:expr),* ,) => { token_set!($($t),*) }; |
35 | } | 33 | } |
36 | 34 | ||
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 657ddf2a6..659f77b71 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -207,8 +207,8 @@ pub fn lines_match(expected: &str, actual: &str) -> bool { | |||
207 | // Let's not deal with / vs \ (windows...) | 207 | // Let's not deal with / vs \ (windows...) |
208 | // First replace backslash-escaped backslashes with forward slashes | 208 | // First replace backslash-escaped backslashes with forward slashes |
209 | // which can occur in, for example, JSON output | 209 | // which can occur in, for example, JSON output |
210 | let expected = expected.replace("\\\\", "/").replace("\\", "/"); | 210 | let expected = expected.replace(r"\\", "/").replace(r"\", "/"); |
211 | let mut actual: &str = &actual.replace("\\\\", "/").replace("\\", "/"); | 211 | let mut actual: &str = &actual.replace(r"\\", "/").replace(r"\", "/"); |
212 | for (i, part) in expected.split("[..]").enumerate() { | 212 | for (i, part) in expected.split("[..]").enumerate() { |
213 | match actual.find(part) { | 213 | match actual.find(part) { |
214 | Some(j) => { | 214 | Some(j) => { |
diff --git a/docs/user/README.md b/docs/user/README.md index 04c349342..9cdabfd42 100644 --- a/docs/user/README.md +++ b/docs/user/README.md | |||
@@ -135,37 +135,25 @@ to load path and require it in `init.el` | |||
135 | * (Optionally) bind commands like `rust-analyzer-join-lines`, `rust-analyzer-extend-selection` and `rust-analyzer-expand-macro` to keys, and enable `rust-analyzer-inlay-hints-mode` to get inline type hints | 135 | * (Optionally) bind commands like `rust-analyzer-join-lines`, `rust-analyzer-extend-selection` and `rust-analyzer-expand-macro` to keys, and enable `rust-analyzer-inlay-hints-mode` to get inline type hints |
136 | 136 | ||
137 | 137 | ||
138 | ## Vim and NeoVim | 138 | ## Vim and NeoVim (coc-rust-analyzer) |
139 | 139 | ||
140 | Neovim 0.5 has a built in language server. For a quick start configuration of | 140 | * Install coc.nvim by following the instructions at [coc.nvim][] (nodejs required) |
141 | rust-analyzer, use [neovim/nvim-lsp](https://github.com/neovim/nvim-lsp#rust_analyzer). | 141 | * Run `:CocInstall coc-rust-analyzer` to install [coc-rust-analyzer], this extension implements _most_ of the features supported in the VSCode extension: |
142 | Once `neovim/nvim-lsp` is installed, you can use `call nvim_lsp#setup("rust_analyzer", {})` | ||
143 | or `lua require'nvim_lsp'.rust_analyzer.setup({})` to quickly get set up. | ||
144 | |||
145 | * Install coc.nvim by following the instructions at [coc.nvim] | ||
146 | - You will need nodejs installed. | ||
147 | - You may want to include some of the sample vim configurations [from here][coc-vim-conf] | ||
148 | - Note that if you use a plugin manager other than `vim-plug`, you may need to manually | ||
149 | checkout the `release` branch wherever your plugin manager cloned it. Otherwise you will | ||
150 | get errors about a missing javascript file. | ||
151 | * Run `:CocInstall coc-rust-analyzer` to install [coc-rust-analyzer], this extension implemented _most_ of the features supported in the VSCode extension: | ||
152 | - same configurations as VSCode extension, `rust-analyzer.raLspServerPath`, `rust-analyzer.enableCargoWatchOnStartup` etc. | 142 | - same configurations as VSCode extension, `rust-analyzer.raLspServerPath`, `rust-analyzer.enableCargoWatchOnStartup` etc. |
153 | - same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.startCargoWatch` etc. | 143 | - same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.startCargoWatch` etc. |
154 | - highlighting and inlay_hints are not implemented yet | 144 | - highlighting and inlay_hints are not implemented yet |
155 | 145 | ||
156 | [coc.nvim]: https://github.com/neoclide/coc.nvim | 146 | [coc.nvim]: https://github.com/neoclide/coc.nvim |
157 | [coc-vim-conf]: https://github.com/neoclide/coc.nvim/#example-vim-configuration | ||
158 | [coc-rust-analyzer]: https://github.com/fannheyward/coc-rust-analyzer | 147 | [coc-rust-analyzer]: https://github.com/fannheyward/coc-rust-analyzer |
159 | 148 | ||
160 | ## Vim and NeoVim Alternative | 149 | ## Vim and NeoVim (LanguageClient-neovim) |
161 | 150 | ||
162 | * Install LanguageClient-neovim by following the instructions [here][lang-client-neovim] | 151 | * Install LanguageClient-neovim by following the instructions [here][lang-client-neovim] |
163 | - No extra run-time is required as this server is written in Rust | ||
164 | - The github project wiki has extra tips on configuration | 152 | - The github project wiki has extra tips on configuration |
165 | 153 | ||
166 | * Configure by adding this to your vim/neovim config file (replacing the existing rust specific line if it exists): | 154 | * Configure by adding this to your vim/neovim config file (replacing the existing rust specific line if it exists): |
167 | 155 | ||
168 | ``` | 156 | ```vim |
169 | let g:LanguageClient_serverCommands = { | 157 | let g:LanguageClient_serverCommands = { |
170 | \ 'rust': ['ra_lsp_server'], | 158 | \ 'rust': ['ra_lsp_server'], |
171 | \ } | 159 | \ } |
@@ -173,6 +161,13 @@ let g:LanguageClient_serverCommands = { | |||
173 | 161 | ||
174 | [lang-client-neovim]: https://github.com/autozimu/LanguageClient-neovim | 162 | [lang-client-neovim]: https://github.com/autozimu/LanguageClient-neovim |
175 | 163 | ||
164 | ## NeoVim (nvim-lsp) | ||
165 | |||
166 | NeoVim 0.5 (not yet released) has built in language server support. For a quick start configuration | ||
167 | of rust-analyzer, use [neovim/nvim-lsp](https://github.com/neovim/nvim-lsp#rust_analyzer). | ||
168 | Once `neovim/nvim-lsp` is installed, you can use `call nvim_lsp#setup("rust_analyzer", {})` | ||
169 | or `lua require'nvim_lsp'.rust_analyzer.setup({})` to quickly get set up. | ||
170 | |||
176 | 171 | ||
177 | ## Sublime Text 3 | 172 | ## Sublime Text 3 |
178 | 173 | ||
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index 190baeddf..40a6682be 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs | |||
@@ -144,6 +144,7 @@ pub fn run_fuzzer() -> Result<()> { | |||
144 | } | 144 | } |
145 | 145 | ||
146 | pub fn reformat_staged_files() -> Result<()> { | 146 | pub fn reformat_staged_files() -> Result<()> { |
147 | run_rustfmt(Mode::Overwrite)?; | ||
147 | let root = project_root(); | 148 | let root = project_root(); |
148 | let output = Command::new("git") | 149 | let output = Command::new("git") |
149 | .arg("diff") | 150 | .arg("diff") |
diff --git a/xtask/src/main.rs b/xtask/src/main.rs index c52902bb5..4201c6a6a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs | |||
@@ -20,7 +20,7 @@ use xtask::{ | |||
20 | }; | 20 | }; |
21 | 21 | ||
22 | // Latest stable, feel free to send a PR if this lags behind. | 22 | // Latest stable, feel free to send a PR if this lags behind. |
23 | const REQUIRED_RUST_VERSION: u32 = 39; | 23 | const REQUIRED_RUST_VERSION: u32 = 40; |
24 | 24 | ||
25 | struct InstallOpt { | 25 | struct InstallOpt { |
26 | client: Option<ClientOpt>, | 26 | client: Option<ClientOpt>, |