diff options
87 files changed, 2277 insertions, 1827 deletions
diff --git a/Cargo.lock b/Cargo.lock index 0400c6a94..5a5edc3e2 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -53,7 +53,7 @@ dependencies = [ | |||
53 | "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", | 53 | "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", |
54 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | 54 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", |
55 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", | 55 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", |
56 | "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", | 56 | "rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", |
57 | "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", | 57 | "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |
58 | ] | 58 | ] |
59 | 59 | ||
@@ -62,7 +62,7 @@ name = "backtrace-sys" | |||
62 | version = "0.1.28" | 62 | version = "0.1.28" |
63 | source = "registry+https://github.com/rust-lang/crates.io-index" | 63 | source = "registry+https://github.com/rust-lang/crates.io-index" |
64 | dependencies = [ | 64 | dependencies = [ |
65 | "cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", | 65 | "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", |
66 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", | 66 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", |
67 | ] | 67 | ] |
68 | 68 | ||
@@ -130,7 +130,7 @@ dependencies = [ | |||
130 | 130 | ||
131 | [[package]] | 131 | [[package]] |
132 | name = "cc" | 132 | name = "cc" |
133 | version = "1.0.34" | 133 | version = "1.0.35" |
134 | source = "registry+https://github.com/rust-lang/crates.io-index" | 134 | source = "registry+https://github.com/rust-lang/crates.io-index" |
135 | 135 | ||
136 | [[package]] | 136 | [[package]] |
@@ -156,14 +156,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
156 | 156 | ||
157 | [[package]] | 157 | [[package]] |
158 | name = "clap" | 158 | name = "clap" |
159 | version = "2.32.0" | 159 | version = "2.33.0" |
160 | source = "registry+https://github.com/rust-lang/crates.io-index" | 160 | source = "registry+https://github.com/rust-lang/crates.io-index" |
161 | dependencies = [ | 161 | dependencies = [ |
162 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | 162 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |
163 | "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", | 163 | "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", |
164 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", | 164 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", |
165 | "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", | 165 | "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
166 | "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", | 166 | "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |
167 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 167 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
168 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", | 168 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", |
169 | ] | 169 | ] |
@@ -264,7 +264,7 @@ version = "0.5.6" | |||
264 | source = "registry+https://github.com/rust-lang/crates.io-index" | 264 | source = "registry+https://github.com/rust-lang/crates.io-index" |
265 | dependencies = [ | 265 | dependencies = [ |
266 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 266 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
267 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 267 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
268 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", | 268 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", |
269 | ] | 269 | ] |
270 | 270 | ||
@@ -337,7 +337,7 @@ version = "0.1.5" | |||
337 | source = "registry+https://github.com/rust-lang/crates.io-index" | 337 | source = "registry+https://github.com/rust-lang/crates.io-index" |
338 | dependencies = [ | 338 | dependencies = [ |
339 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 339 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
340 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 340 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
341 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", | 341 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", |
342 | "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", | 342 | "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", |
343 | ] | 343 | ] |
@@ -354,7 +354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
354 | dependencies = [ | 354 | dependencies = [ |
355 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | 355 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", |
356 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", | 356 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", |
357 | "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)", | 357 | "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |
358 | ] | 358 | ] |
359 | 359 | ||
360 | [[package]] | 360 | [[package]] |
@@ -562,7 +562,7 @@ name = "jemalloc-sys" | |||
562 | version = "0.1.8" | 562 | version = "0.1.8" |
563 | source = "registry+https://github.com/rust-lang/crates.io-index" | 563 | source = "registry+https://github.com/rust-lang/crates.io-index" |
564 | dependencies = [ | 564 | dependencies = [ |
565 | "cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", | 565 | "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", |
566 | "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 566 | "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
567 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", | 567 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", |
568 | ] | 568 | ] |
@@ -741,7 +741,7 @@ version = "0.2.4" | |||
741 | source = "registry+https://github.com/rust-lang/crates.io-index" | 741 | source = "registry+https://github.com/rust-lang/crates.io-index" |
742 | dependencies = [ | 742 | dependencies = [ |
743 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 743 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
744 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 744 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
745 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", | 745 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", |
746 | ] | 746 | ] |
747 | 747 | ||
@@ -833,7 +833,7 @@ dependencies = [ | |||
833 | "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 833 | "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
834 | "pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 834 | "pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
835 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 835 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
836 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 836 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
837 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", | 837 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", |
838 | ] | 838 | ] |
839 | 839 | ||
@@ -879,7 +879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
879 | 879 | ||
880 | [[package]] | 880 | [[package]] |
881 | name = "quote" | 881 | name = "quote" |
882 | version = "0.6.11" | 882 | version = "0.6.12" |
883 | source = "registry+https://github.com/rust-lang/crates.io-index" | 883 | source = "registry+https://github.com/rust-lang/crates.io-index" |
884 | dependencies = [ | 884 | dependencies = [ |
885 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 885 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -913,7 +913,7 @@ dependencies = [ | |||
913 | "ra_hir 0.1.0", | 913 | "ra_hir 0.1.0", |
914 | "ra_project_model 0.1.0", | 914 | "ra_project_model 0.1.0", |
915 | "ra_syntax 0.1.0", | 915 | "ra_syntax 0.1.0", |
916 | "ra_vfs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 916 | "ra_vfs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", |
917 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 917 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
918 | "test_utils 0.1.0", | 918 | "test_utils 0.1.0", |
919 | ] | 919 | ] |
@@ -922,7 +922,7 @@ dependencies = [ | |||
922 | name = "ra_cli" | 922 | name = "ra_cli" |
923 | version = "0.1.0" | 923 | version = "0.1.0" |
924 | dependencies = [ | 924 | dependencies = [ |
925 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", | 925 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", |
926 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 926 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
927 | "flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", | 927 | "flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", |
928 | "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | 928 | "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1024,7 +1024,7 @@ dependencies = [ | |||
1024 | "ra_project_model 0.1.0", | 1024 | "ra_project_model 0.1.0", |
1025 | "ra_syntax 0.1.0", | 1025 | "ra_syntax 0.1.0", |
1026 | "ra_text_edit 0.1.0", | 1026 | "ra_text_edit 0.1.0", |
1027 | "ra_vfs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1027 | "ra_vfs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1028 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1028 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1029 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1029 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1030 | "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", | 1030 | "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1088,7 +1088,7 @@ dependencies = [ | |||
1088 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1088 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1089 | "ra_parser 0.1.0", | 1089 | "ra_parser 0.1.0", |
1090 | "ra_text_edit 0.1.0", | 1090 | "ra_text_edit 0.1.0", |
1091 | "rowan 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1091 | "rowan 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1092 | "smol_str 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", | 1092 | "smol_str 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", |
1093 | "test_utils 0.1.0", | 1093 | "test_utils 0.1.0", |
1094 | "text_unit 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1094 | "text_unit 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1114,7 +1114,7 @@ dependencies = [ | |||
1114 | 1114 | ||
1115 | [[package]] | 1115 | [[package]] |
1116 | name = "ra_vfs" | 1116 | name = "ra_vfs" |
1117 | version = "0.2.1" | 1117 | version = "0.2.2" |
1118 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1119 | dependencies = [ | 1119 | dependencies = [ |
1120 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1120 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1253,7 +1253,7 @@ dependencies = [ | |||
1253 | 1253 | ||
1254 | [[package]] | 1254 | [[package]] |
1255 | name = "redox_syscall" | 1255 | name = "redox_syscall" |
1256 | version = "0.1.52" | 1256 | version = "0.1.54" |
1257 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1258 | 1258 | ||
1259 | [[package]] | 1259 | [[package]] |
@@ -1261,7 +1261,7 @@ name = "redox_termios" | |||
1261 | version = "0.1.1" | 1261 | version = "0.1.1" |
1262 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1263 | dependencies = [ | 1263 | dependencies = [ |
1264 | "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)", | 1264 | "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |
1265 | ] | 1265 | ] |
1266 | 1266 | ||
1267 | [[package]] | 1267 | [[package]] |
@@ -1309,7 +1309,7 @@ dependencies = [ | |||
1309 | 1309 | ||
1310 | [[package]] | 1310 | [[package]] |
1311 | name = "rowan" | 1311 | name = "rowan" |
1312 | version = "0.4.0" | 1312 | version = "0.5.0" |
1313 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1314 | dependencies = [ | 1314 | dependencies = [ |
1315 | "colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1315 | "colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1320,7 +1320,7 @@ dependencies = [ | |||
1320 | 1320 | ||
1321 | [[package]] | 1321 | [[package]] |
1322 | name = "rustc-demangle" | 1322 | name = "rustc-demangle" |
1323 | version = "0.1.13" | 1323 | version = "0.1.14" |
1324 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1324 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1325 | 1325 | ||
1326 | [[package]] | 1326 | [[package]] |
@@ -1366,7 +1366,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1366 | dependencies = [ | 1366 | dependencies = [ |
1367 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1367 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1368 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 1368 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
1369 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 1369 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
1370 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", | 1370 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", |
1371 | ] | 1371 | ] |
1372 | 1372 | ||
@@ -1411,7 +1411,7 @@ version = "1.0.90" | |||
1411 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1412 | dependencies = [ | 1412 | dependencies = [ |
1413 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 1413 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
1414 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 1414 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
1415 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", | 1415 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", |
1416 | ] | 1416 | ] |
1417 | 1417 | ||
@@ -1480,7 +1480,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1480 | 1480 | ||
1481 | [[package]] | 1481 | [[package]] |
1482 | name = "strsim" | 1482 | name = "strsim" |
1483 | version = "0.7.0" | 1483 | version = "0.8.0" |
1484 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1485 | 1485 | ||
1486 | [[package]] | 1486 | [[package]] |
@@ -1494,7 +1494,7 @@ version = "0.15.30" | |||
1494 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1494 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1495 | dependencies = [ | 1495 | dependencies = [ |
1496 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 1496 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
1497 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 1497 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
1498 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1498 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1499 | ] | 1499 | ] |
1500 | 1500 | ||
@@ -1504,7 +1504,7 @@ version = "0.10.1" | |||
1504 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1505 | dependencies = [ | 1505 | dependencies = [ |
1506 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | 1506 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
1507 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 1507 | "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |
1508 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", | 1508 | "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", |
1509 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1509 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1510 | ] | 1510 | ] |
@@ -1517,7 +1517,7 @@ dependencies = [ | |||
1517 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | 1517 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", |
1518 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", | 1518 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", |
1519 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1519 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", |
1520 | "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)", | 1520 | "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |
1521 | "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1521 | "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1522 | "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", | 1522 | "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |
1523 | ] | 1523 | ] |
@@ -1559,7 +1559,7 @@ version = "1.5.1" | |||
1559 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1559 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1560 | dependencies = [ | 1560 | dependencies = [ |
1561 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", | 1561 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", |
1562 | "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)", | 1562 | "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |
1563 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1563 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1564 | ] | 1564 | ] |
1565 | 1565 | ||
@@ -1591,7 +1591,7 @@ dependencies = [ | |||
1591 | 1591 | ||
1592 | [[package]] | 1592 | [[package]] |
1593 | name = "textwrap" | 1593 | name = "textwrap" |
1594 | version = "0.10.0" | 1594 | version = "0.11.0" |
1595 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1596 | dependencies = [ | 1596 | dependencies = [ |
1597 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1597 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1627,7 +1627,7 @@ version = "0.1.42" | |||
1627 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1628 | dependencies = [ | 1628 | dependencies = [ |
1629 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", | 1629 | "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", |
1630 | "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)", | 1630 | "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |
1631 | "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", | 1631 | "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |
1632 | ] | 1632 | ] |
1633 | 1633 | ||
@@ -1635,7 +1635,7 @@ dependencies = [ | |||
1635 | name = "tools" | 1635 | name = "tools" |
1636 | version = "0.1.0" | 1636 | version = "0.1.0" |
1637 | dependencies = [ | 1637 | dependencies = [ |
1638 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1638 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1639 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1639 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
1640 | "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1640 | "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1641 | "teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1641 | "teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1865,11 +1865,11 @@ dependencies = [ | |||
1865 | "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" | 1865 | "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" |
1866 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" | 1866 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" |
1867 | "checksum cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "178d62b240c34223f265a4c1e275e37d62da163d421fc8d7f7e3ee340f803c57" | 1867 | "checksum cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "178d62b240c34223f265a4c1e275e37d62da163d421fc8d7f7e3ee340f803c57" |
1868 | "checksum cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)" = "30f813bf45048a18eda9190fd3c6b78644146056740c43172a5a3699118588fd" | 1868 | "checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" |
1869 | "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" | 1869 | "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" |
1870 | "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" | 1870 | "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" |
1871 | "checksum ci_info 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e5e881307a989a3a5e20d52a32cc05950e3c2178cccfcc9428271a6cde09f902" | 1871 | "checksum ci_info 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e5e881307a989a3a5e20d52a32cc05950e3c2178cccfcc9428271a6cde09f902" |
1872 | "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" | 1872 | "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" |
1873 | "checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" | 1873 | "checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" |
1874 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" | 1874 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" |
1875 | "checksum colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "370c83b49aedf022ee27942e8ae1d9de1cf40dc9653ee6550e4455d08f6406f9" | 1875 | "checksum colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "370c83b49aedf022ee27942e8ae1d9de1cf40dc9653ee6550e4455d08f6406f9" |
@@ -1953,8 +1953,8 @@ dependencies = [ | |||
1953 | "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" | 1953 | "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" |
1954 | "checksum proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24f5844db2f839e97e3021980975f6ebf8691d9b9b2ca67ed3feb38dc3edb52c" | 1954 | "checksum proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24f5844db2f839e97e3021980975f6ebf8691d9b9b2ca67ed3feb38dc3edb52c" |
1955 | "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" | 1955 | "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" |
1956 | "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" | 1956 | "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" |
1957 | "checksum ra_vfs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d75d08da053ec832676686c72dfe509fdd1e807191a50ac79087466ffefccb1c" | 1957 | "checksum ra_vfs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "411d8ce8abf262b08421e6446c4fd5b420206cf221cd21fcfc793445fb3825b2" |
1958 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" | 1958 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" |
1959 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" | 1959 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" |
1960 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" | 1960 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" |
@@ -1968,15 +1968,15 @@ dependencies = [ | |||
1968 | "checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" | 1968 | "checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" |
1969 | "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" | 1969 | "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" |
1970 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" | 1970 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" |
1971 | "checksum redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)" = "d32b3053e5ced86e4bc0411fec997389532bf56b000e66cb4884eeeb41413d69" | 1971 | "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" |
1972 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" | 1972 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" |
1973 | "checksum regex 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "559008764a17de49a3146b234641644ed37d118d1ef641a0bb573d146edc6ce0" | 1973 | "checksum regex 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "559008764a17de49a3146b234641644ed37d118d1ef641a0bb573d146edc6ce0" |
1974 | "checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" | 1974 | "checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" |
1975 | "checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c" | 1975 | "checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c" |
1976 | "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" | 1976 | "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" |
1977 | "checksum ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "17f52a24414403f81528b67488cf8edc4eda977d3af1646bb6b106a600ead78f" | 1977 | "checksum ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "17f52a24414403f81528b67488cf8edc4eda977d3af1646bb6b106a600ead78f" |
1978 | "checksum rowan 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "397cd19c109641f10f3c66433440285e232d8cbd37406cf8f944a15ab1e63a8e" | 1978 | "checksum rowan 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91237e0f16ac1073139acd696d9d386c3225ba1d6eafc09b105984905994068d" |
1979 | "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" | 1979 | "checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" |
1980 | "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" | 1980 | "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" |
1981 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" | 1981 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" |
1982 | "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" | 1982 | "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" |
@@ -1996,7 +1996,7 @@ dependencies = [ | |||
1996 | "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" | 1996 | "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" |
1997 | "checksum smol_str 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d077b3367211e9c6e2e012fb804c444e0d80ab5a51ae4137739b58e6446dcaef" | 1997 | "checksum smol_str 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d077b3367211e9c6e2e012fb804c444e0d80ab5a51ae4137739b58e6446dcaef" |
1998 | "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" | 1998 | "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" |
1999 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" | 1999 | "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" |
2000 | "checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" | 2000 | "checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" |
2001 | "checksum syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)" = "66c8865bf5a7cbb662d8b011950060b3c8743dca141b054bf7195b20d314d8e2" | 2001 | "checksum syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)" = "66c8865bf5a7cbb662d8b011950060b3c8743dca141b054bf7195b20d314d8e2" |
2002 | "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" | 2002 | "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" |
@@ -2006,7 +2006,7 @@ dependencies = [ | |||
2006 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" | 2006 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" |
2007 | "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" | 2007 | "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" |
2008 | "checksum text_unit 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "158bb1c22b638b1da3c95a8ad9f061ea40d4d39fd0301be3a520f92efeeb189e" | 2008 | "checksum text_unit 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "158bb1c22b638b1da3c95a8ad9f061ea40d4d39fd0301be3a520f92efeeb189e" |
2009 | "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" | 2009 | "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" |
2010 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" | 2010 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" |
2011 | "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" | 2011 | "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" |
2012 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" | 2012 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" |
diff --git a/crates/ra_assists/src/add_explicit_type.rs b/crates/ra_assists/src/add_explicit_type.rs new file mode 100644 index 000000000..cb0ac9885 --- /dev/null +++ b/crates/ra_assists/src/add_explicit_type.rs | |||
@@ -0,0 +1,89 @@ | |||
1 | use hir::{ | ||
2 | HirDisplay, Ty, | ||
3 | db::HirDatabase, | ||
4 | }; | ||
5 | use ra_syntax::{ | ||
6 | SyntaxKind, | ||
7 | ast::{LetStmt, PatKind, NameOwner, AstNode} | ||
8 | }; | ||
9 | |||
10 | use crate::{AssistCtx, Assist, AssistId}; | ||
11 | |||
12 | /// Add explicit type assist. | ||
13 | pub(crate) fn add_explicit_type(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | ||
14 | let stmt = ctx.node_at_offset::<LetStmt>()?; | ||
15 | let expr = stmt.initializer()?; | ||
16 | let pat = stmt.pat()?; | ||
17 | // Must be a binding | ||
18 | let pat = match pat.kind() { | ||
19 | PatKind::BindPat(bind_pat) => bind_pat, | ||
20 | _ => return None, | ||
21 | }; | ||
22 | let pat_range = pat.syntax().range(); | ||
23 | // The binding must have a name | ||
24 | let name = pat.name()?; | ||
25 | let name_range = name.syntax().range(); | ||
26 | // Assist not applicable if the type has already been specified | ||
27 | if stmt.syntax().children_with_tokens().any(|child| child.kind() == SyntaxKind::COLON) { | ||
28 | return None; | ||
29 | } | ||
30 | // Infer type | ||
31 | let db = ctx.db; | ||
32 | let analyzer = hir::SourceAnalyzer::new(db, ctx.frange.file_id, stmt.syntax(), None); | ||
33 | let ty = analyzer.type_of(db, expr)?; | ||
34 | // Assist not applicable if the type is unknown | ||
35 | if is_unknown(&ty) { | ||
36 | return None; | ||
37 | } | ||
38 | |||
39 | ctx.add_action(AssistId("add_explicit_type"), "add explicit type", |edit| { | ||
40 | edit.target(pat_range); | ||
41 | edit.insert(name_range.end(), format!(": {}", ty.display(db))); | ||
42 | }); | ||
43 | ctx.build() | ||
44 | } | ||
45 | |||
46 | /// Returns true if any type parameter is unknown | ||
47 | fn is_unknown(ty: &Ty) -> bool { | ||
48 | match ty { | ||
49 | Ty::Unknown => true, | ||
50 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(is_unknown), | ||
51 | _ => false, | ||
52 | } | ||
53 | } | ||
54 | |||
55 | #[cfg(test)] | ||
56 | mod tests { | ||
57 | use super::*; | ||
58 | |||
59 | use crate::helpers::{ check_assist, check_assist_target, check_assist_not_applicable }; | ||
60 | |||
61 | #[test] | ||
62 | fn add_explicit_type_target() { | ||
63 | check_assist_target(add_explicit_type, "fn f() { let a<|> = 1; }", "a"); | ||
64 | } | ||
65 | |||
66 | #[test] | ||
67 | fn add_explicit_type_works_for_simple_expr() { | ||
68 | check_assist( | ||
69 | add_explicit_type, | ||
70 | "fn f() { let a<|> = 1; }", | ||
71 | "fn f() { let a<|>: i32 = 1; }", | ||
72 | ); | ||
73 | } | ||
74 | |||
75 | #[test] | ||
76 | fn add_explicit_type_not_applicable_if_ty_not_inferred() { | ||
77 | check_assist_not_applicable(add_explicit_type, "fn f() { let a<|> = None; }"); | ||
78 | } | ||
79 | |||
80 | #[test] | ||
81 | fn add_explicit_type_not_applicable_if_ty_already_specified() { | ||
82 | check_assist_not_applicable(add_explicit_type, "fn f() { let a<|>: i32 = 1; }"); | ||
83 | } | ||
84 | |||
85 | #[test] | ||
86 | fn add_explicit_type_not_applicable_if_specified_ty_is_tuple() { | ||
87 | check_assist_not_applicable(add_explicit_type, "fn f() { let a<|>: (i32, i32) = (3, 4); }"); | ||
88 | } | ||
89 | } | ||
diff --git a/crates/ra_assists/src/add_missing_impl_members.rs b/crates/ra_assists/src/add_missing_impl_members.rs index 19a2d05bc..100ebb7b6 100644 --- a/crates/ra_assists/src/add_missing_impl_members.rs +++ b/crates/ra_assists/src/add_missing_impl_members.rs | |||
@@ -2,7 +2,6 @@ use std::fmt::Write; | |||
2 | 2 | ||
3 | use crate::{Assist, AssistId, AssistCtx}; | 3 | use crate::{Assist, AssistId, AssistCtx}; |
4 | 4 | ||
5 | use hir::Resolver; | ||
6 | use hir::db::HirDatabase; | 5 | use hir::db::HirDatabase; |
7 | use ra_syntax::{SmolStr, SyntaxKind, TextRange, TextUnit, TreeArc}; | 6 | use ra_syntax::{SmolStr, SyntaxKind, TextRange, TextUnit, TreeArc}; |
8 | use ra_syntax::ast::{self, AstNode, AstToken, FnDef, ImplItem, ImplItemKind, NameOwner}; | 7 | use ra_syntax::ast::{self, AstNode, AstToken, FnDef, ImplItem, ImplItemKind, NameOwner}; |
@@ -46,9 +45,9 @@ fn add_missing_impl_members_inner( | |||
46 | let trait_def = { | 45 | let trait_def = { |
47 | let file_id = ctx.frange.file_id; | 46 | let file_id = ctx.frange.file_id; |
48 | let position = FilePosition { file_id, offset: impl_node.syntax().range().start() }; | 47 | let position = FilePosition { file_id, offset: impl_node.syntax().range().start() }; |
49 | let resolver = hir::source_binder::resolver_for_position(ctx.db, position); | 48 | let analyzer = hir::SourceAnalyzer::new(ctx.db, position.file_id, impl_node.syntax(), None); |
50 | 49 | ||
51 | resolve_target_trait_def(ctx.db, &resolver, impl_node)? | 50 | resolve_target_trait_def(ctx.db, &analyzer, impl_node)? |
52 | }; | 51 | }; |
53 | 52 | ||
54 | let missing_fns: Vec<_> = { | 53 | let missing_fns: Vec<_> = { |
@@ -122,14 +121,14 @@ fn add_missing_impl_members_inner( | |||
122 | /// implemented) to a `ast::TraitDef`. | 121 | /// implemented) to a `ast::TraitDef`. |
123 | fn resolve_target_trait_def( | 122 | fn resolve_target_trait_def( |
124 | db: &impl HirDatabase, | 123 | db: &impl HirDatabase, |
125 | resolver: &Resolver, | 124 | analyzer: &hir::SourceAnalyzer, |
126 | impl_block: &ast::ImplBlock, | 125 | impl_block: &ast::ImplBlock, |
127 | ) -> Option<TreeArc<ast::TraitDef>> { | 126 | ) -> Option<TreeArc<ast::TraitDef>> { |
128 | let ast_path = impl_block.target_trait().map(AstNode::syntax).and_then(ast::PathType::cast)?; | 127 | let ast_path = |
129 | let hir_path = ast_path.path().and_then(hir::Path::from_ast)?; | 128 | impl_block.target_trait().map(AstNode::syntax).and_then(ast::PathType::cast)?.path()?; |
130 | 129 | ||
131 | match resolver.resolve_path(db, &hir_path).take_types() { | 130 | match analyzer.resolve_path(db, &ast_path) { |
132 | Some(hir::Resolution::Def(hir::ModuleDef::Trait(def))) => Some(def.source(db).1), | 131 | Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def.source(db).1), |
133 | _ => None, | 132 | _ => None, |
134 | } | 133 | } |
135 | } | 134 | } |
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index da67ab667..45e327cd4 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::fmt::Write; | 1 | use std::fmt::Write; |
2 | 2 | ||
3 | use hir::{ | 3 | use hir::{ |
4 | AdtDef, FieldSource, source_binder, | 4 | AdtDef, FieldSource, |
5 | db::HirDatabase, | 5 | db::HirDatabase, |
6 | }; | 6 | }; |
7 | use ra_syntax::ast::{self, AstNode}; | 7 | use ra_syntax::ast::{self, AstNode}; |
@@ -20,12 +20,8 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<As | |||
20 | } | 20 | } |
21 | 21 | ||
22 | let expr = match_expr.expr()?; | 22 | let expr = match_expr.expr()?; |
23 | let function = | 23 | let analyzer = hir::SourceAnalyzer::new(ctx.db, ctx.frange.file_id, expr.syntax(), None); |
24 | source_binder::function_from_child_node(ctx.db, ctx.frange.file_id, expr.syntax())?; | 24 | let match_expr_ty = analyzer.type_of(ctx.db, expr)?; |
25 | let infer_result = function.infer(ctx.db); | ||
26 | let source_map = function.body_source_map(ctx.db); | ||
27 | let node_expr = source_map.node_expr(expr)?; | ||
28 | let match_expr_ty = infer_result[node_expr].clone(); | ||
29 | let enum_def = match_expr_ty.autoderef(ctx.db).find_map(|ty| match ty.as_adt() { | 25 | let enum_def = match_expr_ty.autoderef(ctx.db).find_map(|ty| match ty.as_adt() { |
30 | Some((AdtDef::Enum(e), _)) => Some(e), | 26 | Some((AdtDef::Enum(e), _)) => Some(e), |
31 | _ => None, | 27 | _ => None, |
diff --git a/crates/ra_assists/src/fill_struct_fields.rs b/crates/ra_assists/src/fill_struct_fields.rs index c7790dc72..663b4f669 100644 --- a/crates/ra_assists/src/fill_struct_fields.rs +++ b/crates/ra_assists/src/fill_struct_fields.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::fmt::Write; | 1 | use std::fmt::Write; |
2 | 2 | ||
3 | use hir::{AdtDef, db::HirDatabase, source_binder::function_from_child_node}; | 3 | use hir::{AdtDef, db::HirDatabase}; |
4 | 4 | ||
5 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | 6 | ||
@@ -51,15 +51,13 @@ where | |||
51 | } | 51 | } |
52 | 52 | ||
53 | fn evaluate_struct_def_fields(&mut self) -> Option<()> { | 53 | fn evaluate_struct_def_fields(&mut self) -> Option<()> { |
54 | let function = function_from_child_node( | 54 | let analyzer = hir::SourceAnalyzer::new( |
55 | self.ctx.db, | 55 | self.ctx.db, |
56 | self.ctx.frange.file_id, | 56 | self.ctx.frange.file_id, |
57 | self.struct_lit.syntax(), | 57 | self.struct_lit.syntax(), |
58 | )?; | 58 | None, |
59 | let infer_result = function.infer(self.ctx.db); | 59 | ); |
60 | let source_map = function.body_source_map(self.ctx.db); | 60 | let struct_lit_ty = analyzer.type_of(self.ctx.db, self.struct_lit.into())?; |
61 | let node_expr = source_map.node_expr(self.struct_lit.into())?; | ||
62 | let struct_lit_ty = infer_result[node_expr].clone(); | ||
63 | let struct_def = match struct_lit_ty.as_adt() { | 61 | let struct_def = match struct_lit_ty.as_adt() { |
64 | Some((AdtDef::Struct(s), _)) => s, | 62 | Some((AdtDef::Struct(s), _)) => s, |
65 | _ => return None, | 63 | _ => return None, |
diff --git a/crates/ra_assists/src/inline_local_variable.rs b/crates/ra_assists/src/inline_local_variable.rs index 950c2910b..e0479ef13 100644 --- a/crates/ra_assists/src/inline_local_variable.rs +++ b/crates/ra_assists/src/inline_local_variable.rs | |||
@@ -1,7 +1,4 @@ | |||
1 | use hir::{ | 1 | use hir::db::HirDatabase; |
2 | db::HirDatabase, | ||
3 | source_binder::function_from_child_node, | ||
4 | }; | ||
5 | use ra_syntax::{ | 2 | use ra_syntax::{ |
6 | ast::{self, AstNode, AstToken, PatKind, ExprKind}, | 3 | ast::{self, AstNode, AstToken, PatKind, ExprKind}, |
7 | TextRange, | 4 | TextRange, |
@@ -29,10 +26,8 @@ pub(crate) fn inline_local_varialbe(mut ctx: AssistCtx<impl HirDatabase>) -> Opt | |||
29 | } else { | 26 | } else { |
30 | let_stmt.syntax().range() | 27 | let_stmt.syntax().range() |
31 | }; | 28 | }; |
32 | 29 | let analyzer = hir::SourceAnalyzer::new(ctx.db, ctx.frange.file_id, bind_pat.syntax(), None); | |
33 | let function = function_from_child_node(ctx.db, ctx.frange.file_id, bind_pat.syntax())?; | 30 | let refs = analyzer.find_all_refs(bind_pat); |
34 | let scope = function.scopes(ctx.db); | ||
35 | let refs = scope.find_all_refs(bind_pat); | ||
36 | 31 | ||
37 | let mut wrap_in_parens = vec![true; refs.len()]; | 32 | let mut wrap_in_parens = vec![true; refs.len()]; |
38 | 33 | ||
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index c1514f8e5..ded401b63 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -86,6 +86,7 @@ where | |||
86 | } | 86 | } |
87 | 87 | ||
88 | mod add_derive; | 88 | mod add_derive; |
89 | mod add_explicit_type; | ||
89 | mod add_impl; | 90 | mod add_impl; |
90 | mod flip_comma; | 91 | mod flip_comma; |
91 | mod flip_binexpr; | 92 | mod flip_binexpr; |
@@ -103,6 +104,7 @@ mod add_missing_impl_members; | |||
103 | fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assist>] { | 104 | fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assist>] { |
104 | &[ | 105 | &[ |
105 | add_derive::add_derive, | 106 | add_derive::add_derive, |
107 | add_explicit_type::add_explicit_type, | ||
106 | add_impl::add_impl, | 108 | add_impl::add_impl, |
107 | change_visibility::change_visibility, | 109 | change_visibility::change_visibility, |
108 | fill_match_arms::fill_match_arms, | 110 | fill_match_arms::fill_match_arms, |
diff --git a/crates/ra_assists/src/split_import.rs b/crates/ra_assists/src/split_import.rs index 4bf1852db..57e0efaf2 100644 --- a/crates/ra_assists/src/split_import.rs +++ b/crates/ra_assists/src/split_import.rs | |||
@@ -1,8 +1,9 @@ | |||
1 | use std::iter::successors; | ||
2 | |||
1 | use hir::db::HirDatabase; | 3 | use hir::db::HirDatabase; |
2 | use ra_syntax::{ | 4 | use ra_syntax::{ |
3 | TextUnit, AstNode, SyntaxKind::COLONCOLON, | 5 | TextUnit, AstNode, SyntaxKind::COLONCOLON, |
4 | ast, | 6 | ast, |
5 | algo::generate, | ||
6 | }; | 7 | }; |
7 | 8 | ||
8 | use crate::{AssistCtx, Assist, AssistId}; | 9 | use crate::{AssistCtx, Assist, AssistId}; |
@@ -10,7 +11,7 @@ use crate::{AssistCtx, Assist, AssistId}; | |||
10 | pub(crate) fn split_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 11 | pub(crate) fn split_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | let colon_colon = ctx.token_at_offset().find(|leaf| leaf.kind() == COLONCOLON)?; | 12 | let colon_colon = ctx.token_at_offset().find(|leaf| leaf.kind() == COLONCOLON)?; |
12 | let path = ast::Path::cast(colon_colon.parent())?; | 13 | let path = ast::Path::cast(colon_colon.parent())?; |
13 | let top_path = generate(Some(path), |it| it.parent_path()).last()?; | 14 | let top_path = successors(Some(path), |it| it.parent_path()).last()?; |
14 | 15 | ||
15 | let use_tree = top_path.syntax().ancestors().find_map(ast::UseTree::cast); | 16 | let use_tree = top_path.syntax().ancestors().find_map(ast::UseTree::cast); |
16 | if use_tree.is_none() { | 17 | if use_tree.is_none() { |
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index 5bb47afb2..0cafe617d 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs | |||
@@ -9,7 +9,7 @@ use rustc_hash::FxHashMap; | |||
9 | use ra_db::{ | 9 | use ra_db::{ |
10 | CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa, | 10 | CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa, |
11 | }; | 11 | }; |
12 | use ra_hir::{db, HirInterner}; | 12 | use ra_hir::db; |
13 | use ra_project_model::ProjectWorkspace; | 13 | use ra_project_model::ProjectWorkspace; |
14 | use ra_vfs::{Vfs, VfsChange}; | 14 | use ra_vfs::{Vfs, VfsChange}; |
15 | use vfs_filter::IncludeRustFiles; | 15 | use vfs_filter::IncludeRustFiles; |
@@ -20,7 +20,6 @@ type Result<T> = std::result::Result<T, failure::Error>; | |||
20 | #[derive(Debug)] | 20 | #[derive(Debug)] |
21 | pub struct BatchDatabase { | 21 | pub struct BatchDatabase { |
22 | runtime: salsa::Runtime<BatchDatabase>, | 22 | runtime: salsa::Runtime<BatchDatabase>, |
23 | interner: Arc<HirInterner>, | ||
24 | } | 23 | } |
25 | 24 | ||
26 | impl salsa::Database for BatchDatabase { | 25 | impl salsa::Database for BatchDatabase { |
@@ -29,12 +28,6 @@ impl salsa::Database for BatchDatabase { | |||
29 | } | 28 | } |
30 | } | 29 | } |
31 | 30 | ||
32 | impl AsRef<HirInterner> for BatchDatabase { | ||
33 | fn as_ref(&self) -> &HirInterner { | ||
34 | &self.interner | ||
35 | } | ||
36 | } | ||
37 | |||
38 | fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { | 31 | fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { |
39 | FileId(f.0.into()) | 32 | FileId(f.0.into()) |
40 | } | 33 | } |
@@ -44,8 +37,7 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { | |||
44 | 37 | ||
45 | impl BatchDatabase { | 38 | impl BatchDatabase { |
46 | pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase { | 39 | pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase { |
47 | let mut db = | 40 | let mut db = BatchDatabase { runtime: salsa::Runtime::default() }; |
48 | BatchDatabase { runtime: salsa::Runtime::default(), interner: Default::default() }; | ||
49 | db.set_crate_graph(Arc::new(crate_graph)); | 41 | db.set_crate_graph(Arc::new(crate_graph)); |
50 | 42 | ||
51 | // wait until Vfs has loaded all roots | 43 | // wait until Vfs has loaded all roots |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index f3389c91f..1cd400752 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -1,11 +1,8 @@ | |||
1 | //! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. | 1 | //! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. |
2 | mod cancellation; | 2 | mod cancellation; |
3 | mod input; | 3 | mod input; |
4 | mod loc2id; | ||
5 | 4 | ||
6 | use std::{ | 5 | use std::{panic, sync::Arc}; |
7 | panic, sync::Arc, | ||
8 | }; | ||
9 | 6 | ||
10 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; | 7 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; |
11 | use relative_path::RelativePathBuf; | 8 | use relative_path::RelativePathBuf; |
@@ -16,7 +13,6 @@ pub use crate::{ | |||
16 | input::{ | 13 | input::{ |
17 | FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, Edition, | 14 | FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, Edition, |
18 | }, | 15 | }, |
19 | loc2id::LocationInterner, | ||
20 | }; | 16 | }; |
21 | 17 | ||
22 | pub trait CheckCanceled: panic::RefUnwindSafe { | 18 | pub trait CheckCanceled: panic::RefUnwindSafe { |
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs deleted file mode 100644 index eae64a4eb..000000000 --- a/crates/ra_db/src/loc2id.rs +++ /dev/null | |||
@@ -1,103 +0,0 @@ | |||
1 | use std::{panic, hash::Hash}; | ||
2 | |||
3 | use parking_lot::Mutex; | ||
4 | use rustc_hash::FxHashMap; | ||
5 | use ra_arena::{Arena, ArenaId}; | ||
6 | |||
7 | /// There are two principle ways to refer to things: | ||
8 | /// - by their location (module in foo/bar/baz.rs at line 42) | ||
9 | /// - by their numeric id (module `ModuleId(42)`) | ||
10 | /// | ||
11 | /// The first one is more powerful (you can actually find the thing in question | ||
12 | /// by id), but the second one is so much more compact. | ||
13 | /// | ||
14 | /// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a | ||
15 | /// bidirectional mapping between positional and numeric ids, we can use compact | ||
16 | /// representation which still allows us to get the actual item. | ||
17 | #[derive(Debug)] | ||
18 | struct Loc2IdMap<LOC, ID> | ||
19 | where | ||
20 | ID: ArenaId + Clone, | ||
21 | LOC: Clone + Eq + Hash, | ||
22 | { | ||
23 | id2loc: Arena<ID, LOC>, | ||
24 | loc2id: FxHashMap<LOC, ID>, | ||
25 | } | ||
26 | |||
27 | impl<LOC, ID> Default for Loc2IdMap<LOC, ID> | ||
28 | where | ||
29 | ID: ArenaId + Clone, | ||
30 | LOC: Clone + Eq + Hash, | ||
31 | { | ||
32 | fn default() -> Self { | ||
33 | Loc2IdMap { id2loc: Arena::default(), loc2id: FxHashMap::default() } | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl<LOC, ID> Loc2IdMap<LOC, ID> | ||
38 | where | ||
39 | ID: ArenaId + Clone, | ||
40 | LOC: Clone + Eq + Hash, | ||
41 | { | ||
42 | pub fn len(&self) -> usize { | ||
43 | self.id2loc.len() | ||
44 | } | ||
45 | |||
46 | pub fn loc2id(&mut self, loc: &LOC) -> ID { | ||
47 | match self.loc2id.get(loc) { | ||
48 | Some(id) => return id.clone(), | ||
49 | None => (), | ||
50 | } | ||
51 | let id = self.id2loc.alloc(loc.clone()); | ||
52 | self.loc2id.insert(loc.clone(), id.clone()); | ||
53 | id | ||
54 | } | ||
55 | |||
56 | pub fn id2loc(&self, id: ID) -> LOC { | ||
57 | self.id2loc[id].clone() | ||
58 | } | ||
59 | } | ||
60 | |||
61 | #[derive(Debug)] | ||
62 | pub struct LocationInterner<LOC, ID> | ||
63 | where | ||
64 | ID: ArenaId + Clone, | ||
65 | LOC: Clone + Eq + Hash, | ||
66 | { | ||
67 | map: Mutex<Loc2IdMap<LOC, ID>>, | ||
68 | } | ||
69 | |||
70 | impl<LOC, ID> panic::RefUnwindSafe for LocationInterner<LOC, ID> | ||
71 | where | ||
72 | ID: ArenaId + Clone, | ||
73 | LOC: Clone + Eq + Hash, | ||
74 | ID: panic::RefUnwindSafe, | ||
75 | LOC: panic::RefUnwindSafe, | ||
76 | { | ||
77 | } | ||
78 | |||
79 | impl<LOC, ID> Default for LocationInterner<LOC, ID> | ||
80 | where | ||
81 | ID: ArenaId + Clone, | ||
82 | LOC: Clone + Eq + Hash, | ||
83 | { | ||
84 | fn default() -> Self { | ||
85 | LocationInterner { map: Default::default() } | ||
86 | } | ||
87 | } | ||
88 | |||
89 | impl<LOC, ID> LocationInterner<LOC, ID> | ||
90 | where | ||
91 | ID: ArenaId + Clone, | ||
92 | LOC: Clone + Eq + Hash, | ||
93 | { | ||
94 | pub fn len(&self) -> usize { | ||
95 | self.map.lock().len() | ||
96 | } | ||
97 | pub fn loc2id(&self, loc: &LOC) -> ID { | ||
98 | self.map.lock().loc2id(loc) | ||
99 | } | ||
100 | pub fn id2loc(&self, id: ID) -> LOC { | ||
101 | self.map.lock().id2loc(id) | ||
102 | } | ||
103 | } | ||
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs index 85b7ce250..603be1854 100644 --- a/crates/ra_fmt/src/lib.rs +++ b/crates/ra_fmt/src/lib.rs | |||
@@ -1,10 +1,10 @@ | |||
1 | //! This crate provides some utilities for indenting rust code. | 1 | //! This crate provides some utilities for indenting rust code. |
2 | //! | 2 | //! |
3 | use std::iter::successors; | ||
3 | use itertools::Itertools; | 4 | use itertools::Itertools; |
4 | use ra_syntax::{ | 5 | use ra_syntax::{ |
5 | SyntaxNode, SyntaxKind::*, SyntaxToken, SyntaxKind, | 6 | SyntaxNode, SyntaxKind::*, SyntaxToken, SyntaxKind, |
6 | ast::{self, AstNode, AstToken}, | 7 | ast::{self, AstNode, AstToken}, |
7 | algo::generate, | ||
8 | }; | 8 | }; |
9 | 9 | ||
10 | pub fn reindent(text: &str, indent: &str) -> String { | 10 | pub fn reindent(text: &str, indent: &str) -> String { |
@@ -29,7 +29,7 @@ pub fn leading_indent(node: &SyntaxNode) -> Option<&str> { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { | 31 | fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { |
32 | generate(token.prev_token(), |&token| token.prev_token()) | 32 | successors(token.prev_token(), |&token| token.prev_token()) |
33 | } | 33 | } |
34 | 34 | ||
35 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> { | 35 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> { |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 9e6170440..8f1ed1086 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -4,14 +4,14 @@ use ra_db::{CrateId, SourceRootId, Edition}; | |||
4 | use ra_syntax::{ast::self, TreeArc}; | 4 | use ra_syntax::{ast::self, TreeArc}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | Name, ScopesWithSourceMap, Ty, HirFileId, ImportSource, | 7 | Name, Ty, HirFileId, Either, |
8 | HirDatabase, DefDatabase, | 8 | HirDatabase, DefDatabase, |
9 | type_ref::TypeRef, | 9 | type_ref::TypeRef, |
10 | nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, | 10 | nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, |
11 | expr::{Body, BodySourceMap}, | 11 | expr::{Body, BodySourceMap}, |
12 | ty::InferenceResult, | 12 | ty::InferenceResult, |
13 | adt::{EnumVariantId, StructFieldId, VariantDef}, | 13 | adt::{EnumVariantId, StructFieldId, VariantDef}, |
14 | generics::GenericParams, | 14 | generics::HasGenericParams, |
15 | docs::{Documentation, Docs, docs_from_ast}, | 15 | docs::{Documentation, Docs, docs_from_ast}, |
16 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeAliasId}, | 16 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeAliasId}, |
17 | impl_block::ImplBlock, | 17 | impl_block::ImplBlock, |
@@ -117,8 +117,14 @@ impl Module { | |||
117 | } | 117 | } |
118 | 118 | ||
119 | /// Returns the syntax of the last path segment corresponding to this import | 119 | /// Returns the syntax of the last path segment corresponding to this import |
120 | pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> ImportSource { | 120 | pub fn import_source( |
121 | self.import_source_impl(db, import) | 121 | &self, |
122 | db: &impl HirDatabase, | ||
123 | import: ImportId, | ||
124 | ) -> Either<TreeArc<ast::UseTree>, TreeArc<ast::ExternCrateItem>> { | ||
125 | let (file_id, source) = self.definition_source(db); | ||
126 | let (_, source_map) = db.raw_items_with_source_map(file_id); | ||
127 | source_map.get(&source, import) | ||
122 | } | 128 | } |
123 | 129 | ||
124 | /// Returns the crate this module is part of. | 130 | /// Returns the crate this module is part of. |
@@ -183,12 +189,12 @@ impl Module { | |||
183 | } | 189 | } |
184 | } | 190 | } |
185 | 191 | ||
186 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 192 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { |
187 | let def_map = db.crate_def_map(self.krate); | 193 | let def_map = db.crate_def_map(self.krate); |
188 | Resolver::default().push_module_scope(def_map, self.module_id) | 194 | Resolver::default().push_module_scope(def_map, self.module_id) |
189 | } | 195 | } |
190 | 196 | ||
191 | pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> { | 197 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { |
192 | let def_map = db.crate_def_map(self.krate); | 198 | let def_map = db.crate_def_map(self.krate); |
193 | def_map[self.module_id] | 199 | def_map[self.module_id] |
194 | .scope | 200 | .scope |
@@ -293,10 +299,6 @@ impl Struct { | |||
293 | .map(|(id, _)| StructField { parent: (*self).into(), id }) | 299 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
294 | } | 300 | } |
295 | 301 | ||
296 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
297 | db.generic_params((*self).into()) | ||
298 | } | ||
299 | |||
300 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { | 302 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { |
301 | db.type_for_def((*self).into(), Namespace::Types) | 303 | db.type_for_def((*self).into(), Namespace::Types) |
302 | } | 304 | } |
@@ -307,7 +309,7 @@ impl Struct { | |||
307 | 309 | ||
308 | // FIXME move to a more general type | 310 | // FIXME move to a more general type |
309 | /// Builds a resolver for type references inside this struct. | 311 | /// Builds a resolver for type references inside this struct. |
310 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 312 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
311 | // take the outer scope... | 313 | // take the outer scope... |
312 | let r = self.module(db).resolver(db); | 314 | let r = self.module(db).resolver(db); |
313 | // ...and add generic params, if present | 315 | // ...and add generic params, if present |
@@ -357,17 +359,13 @@ impl Enum { | |||
357 | .map(|(id, _)| EnumVariant { parent: *self, id }) | 359 | .map(|(id, _)| EnumVariant { parent: *self, id }) |
358 | } | 360 | } |
359 | 361 | ||
360 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
361 | db.generic_params((*self).into()) | ||
362 | } | ||
363 | |||
364 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { | 362 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { |
365 | db.type_for_def((*self).into(), Namespace::Types) | 363 | db.type_for_def((*self).into(), Namespace::Types) |
366 | } | 364 | } |
367 | 365 | ||
368 | // FIXME: move to a more general type | 366 | // FIXME: move to a more general type |
369 | /// Builds a resolver for type references inside this struct. | 367 | /// Builds a resolver for type references inside this struct. |
370 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 368 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
371 | // take the outer scope... | 369 | // take the outer scope... |
372 | let r = self.module(db).resolver(db); | 370 | let r = self.module(db).resolver(db); |
373 | // ...and add generic params, if present | 371 | // ...and add generic params, if present |
@@ -444,28 +442,22 @@ impl DefWithBody { | |||
444 | db.infer(*self) | 442 | db.infer(*self) |
445 | } | 443 | } |
446 | 444 | ||
447 | pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
448 | db.body_with_source_map(*self).1 | ||
449 | } | ||
450 | |||
451 | pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> { | 445 | pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> { |
452 | db.body_hir(*self) | 446 | db.body_hir(*self) |
453 | } | 447 | } |
454 | 448 | ||
449 | pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
450 | db.body_with_source_map(*self).1 | ||
451 | } | ||
452 | |||
455 | /// Builds a resolver for code inside this item. | 453 | /// Builds a resolver for code inside this item. |
456 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 454 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
457 | match *self { | 455 | match *self { |
458 | DefWithBody::Const(ref c) => c.resolver(db), | 456 | DefWithBody::Const(ref c) => c.resolver(db), |
459 | DefWithBody::Function(ref f) => f.resolver(db), | 457 | DefWithBody::Function(ref f) => f.resolver(db), |
460 | DefWithBody::Static(ref s) => s.resolver(db), | 458 | DefWithBody::Static(ref s) => s.resolver(db), |
461 | } | 459 | } |
462 | } | 460 | } |
463 | |||
464 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSourceMap { | ||
465 | let scopes = db.expr_scopes(*self); | ||
466 | let source_map = db.body_with_source_map(*self).1; | ||
467 | ScopesWithSourceMap { scopes, source_map } | ||
468 | } | ||
469 | } | 461 | } |
470 | 462 | ||
471 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 463 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -517,7 +509,7 @@ impl Function { | |||
517 | self.signature(db).name.clone() | 509 | self.signature(db).name.clone() |
518 | } | 510 | } |
519 | 511 | ||
520 | pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 512 | pub(crate) fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
521 | db.body_with_source_map((*self).into()).1 | 513 | db.body_with_source_map((*self).into()).1 |
522 | } | 514 | } |
523 | 515 | ||
@@ -529,12 +521,6 @@ impl Function { | |||
529 | db.type_for_def((*self).into(), Namespace::Values) | 521 | db.type_for_def((*self).into(), Namespace::Values) |
530 | } | 522 | } |
531 | 523 | ||
532 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSourceMap { | ||
533 | let scopes = db.expr_scopes((*self).into()); | ||
534 | let source_map = db.body_with_source_map((*self).into()).1; | ||
535 | ScopesWithSourceMap { scopes, source_map } | ||
536 | } | ||
537 | |||
538 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { | 524 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { |
539 | db.fn_signature(*self) | 525 | db.fn_signature(*self) |
540 | } | 526 | } |
@@ -543,24 +529,32 @@ impl Function { | |||
543 | db.infer((*self).into()) | 529 | db.infer((*self).into()) |
544 | } | 530 | } |
545 | 531 | ||
546 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
547 | db.generic_params((*self).into()) | ||
548 | } | ||
549 | |||
550 | /// The containing impl block, if this is a method. | 532 | /// The containing impl block, if this is a method. |
551 | pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> { | 533 | pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> { |
552 | let module_impls = db.impls_in_module(self.module(db)); | 534 | let module_impls = db.impls_in_module(self.module(db)); |
553 | ImplBlock::containing(module_impls, (*self).into()) | 535 | ImplBlock::containing(module_impls, (*self).into()) |
554 | } | 536 | } |
555 | 537 | ||
538 | /// The containing trait, if this is a trait method definition. | ||
539 | pub fn parent_trait(&self, db: &impl DefDatabase) -> Option<Trait> { | ||
540 | db.trait_items_index(self.module(db)).get_parent_trait((*self).into()) | ||
541 | } | ||
542 | |||
543 | pub fn container(&self, db: &impl DefDatabase) -> Option<Container> { | ||
544 | if let Some(impl_block) = self.impl_block(db) { | ||
545 | Some(impl_block.into()) | ||
546 | } else if let Some(trait_) = self.parent_trait(db) { | ||
547 | Some(trait_.into()) | ||
548 | } else { | ||
549 | None | ||
550 | } | ||
551 | } | ||
552 | |||
556 | // FIXME: move to a more general type for 'body-having' items | 553 | // FIXME: move to a more general type for 'body-having' items |
557 | /// Builds a resolver for code inside this item. | 554 | /// Builds a resolver for code inside this item. |
558 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 555 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
559 | // take the outer scope... | 556 | // take the outer scope... |
560 | let r = self | 557 | let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); |
561 | .impl_block(db) | ||
562 | .map(|ib| ib.resolver(db)) | ||
563 | .unwrap_or_else(|| self.module(db).resolver(db)); | ||
564 | // ...and add generic params, if present | 558 | // ...and add generic params, if present |
565 | let p = self.generic_params(db); | 559 | let p = self.generic_params(db); |
566 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | 560 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
@@ -600,10 +594,6 @@ impl Const { | |||
600 | db.infer((*self).into()) | 594 | db.infer((*self).into()) |
601 | } | 595 | } |
602 | 596 | ||
603 | pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
604 | db.body_with_source_map((*self).into()).1 | ||
605 | } | ||
606 | |||
607 | /// The containing impl block, if this is a method. | 597 | /// The containing impl block, if this is a method. |
608 | pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> { | 598 | pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> { |
609 | let module_impls = db.impls_in_module(self.module(db)); | 599 | let module_impls = db.impls_in_module(self.module(db)); |
@@ -612,7 +602,7 @@ impl Const { | |||
612 | 602 | ||
613 | // FIXME: move to a more general type for 'body-having' items | 603 | // FIXME: move to a more general type for 'body-having' items |
614 | /// Builds a resolver for code inside this item. | 604 | /// Builds a resolver for code inside this item. |
615 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 605 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
616 | // take the outer scope... | 606 | // take the outer scope... |
617 | let r = self | 607 | let r = self |
618 | .impl_block(db) | 608 | .impl_block(db) |
@@ -664,7 +654,7 @@ impl Static { | |||
664 | } | 654 | } |
665 | 655 | ||
666 | /// Builds a resolver for code inside this item. | 656 | /// Builds a resolver for code inside this item. |
667 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 657 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
668 | // take the outer scope... | 658 | // take the outer scope... |
669 | self.module(db).resolver(db) | 659 | self.module(db).resolver(db) |
670 | } | 660 | } |
@@ -672,10 +662,6 @@ impl Static { | |||
672 | pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 662 | pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
673 | db.infer((*self).into()) | 663 | db.infer((*self).into()) |
674 | } | 664 | } |
675 | |||
676 | pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
677 | db.body_with_source_map((*self).into()).1 | ||
678 | } | ||
679 | } | 665 | } |
680 | 666 | ||
681 | impl Docs for Static { | 667 | impl Docs for Static { |
@@ -698,10 +684,6 @@ impl Trait { | |||
698 | self.id.module(db) | 684 | self.id.module(db) |
699 | } | 685 | } |
700 | 686 | ||
701 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
702 | db.generic_params((*self).into()) | ||
703 | } | ||
704 | |||
705 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 687 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
706 | self.trait_data(db).name().clone() | 688 | self.trait_data(db).name().clone() |
707 | } | 689 | } |
@@ -713,6 +695,14 @@ impl Trait { | |||
713 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { | 695 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { |
714 | db.trait_data(self) | 696 | db.trait_data(self) |
715 | } | 697 | } |
698 | |||
699 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { | ||
700 | let r = self.module(db).resolver(db); | ||
701 | // add generic params, if present | ||
702 | let p = self.generic_params(db); | ||
703 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
704 | r | ||
705 | } | ||
716 | } | 706 | } |
717 | 707 | ||
718 | impl Docs for Trait { | 708 | impl Docs for Trait { |
@@ -731,10 +721,6 @@ impl TypeAlias { | |||
731 | self.id.source(db) | 721 | self.id.source(db) |
732 | } | 722 | } |
733 | 723 | ||
734 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
735 | db.generic_params((*self).into()) | ||
736 | } | ||
737 | |||
738 | pub fn module(&self, db: &impl DefDatabase) -> Module { | 724 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
739 | self.id.module(db) | 725 | self.id.module(db) |
740 | } | 726 | } |
@@ -745,12 +731,27 @@ impl TypeAlias { | |||
745 | ImplBlock::containing(module_impls, (*self).into()) | 731 | ImplBlock::containing(module_impls, (*self).into()) |
746 | } | 732 | } |
747 | 733 | ||
734 | /// The containing trait, if this is a trait method definition. | ||
735 | pub fn parent_trait(&self, db: &impl DefDatabase) -> Option<Trait> { | ||
736 | db.trait_items_index(self.module(db)).get_parent_trait((*self).into()) | ||
737 | } | ||
738 | |||
739 | pub fn container(&self, db: &impl DefDatabase) -> Option<Container> { | ||
740 | if let Some(impl_block) = self.impl_block(db) { | ||
741 | Some(impl_block.into()) | ||
742 | } else if let Some(trait_) = self.parent_trait(db) { | ||
743 | Some(trait_.into()) | ||
744 | } else { | ||
745 | None | ||
746 | } | ||
747 | } | ||
748 | |||
748 | pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> { | 749 | pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> { |
749 | db.type_alias_ref(self) | 750 | db.type_alias_ref(self) |
750 | } | 751 | } |
751 | 752 | ||
752 | /// Builds a resolver for the type references in this type alias. | 753 | /// Builds a resolver for the type references in this type alias. |
753 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 754 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
754 | // take the outer scope... | 755 | // take the outer scope... |
755 | let r = self | 756 | let r = self |
756 | .impl_block(db) | 757 | .impl_block(db) |
@@ -768,3 +769,18 @@ impl Docs for TypeAlias { | |||
768 | docs_from_ast(&*self.source(db).1) | 769 | docs_from_ast(&*self.source(db).1) |
769 | } | 770 | } |
770 | } | 771 | } |
772 | |||
773 | pub enum Container { | ||
774 | Trait(Trait), | ||
775 | ImplBlock(ImplBlock), | ||
776 | } | ||
777 | impl_froms!(Container: Trait, ImplBlock); | ||
778 | |||
779 | impl Container { | ||
780 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { | ||
781 | match self { | ||
782 | Container::Trait(trait_) => trait_.resolver(db), | ||
783 | Container::ImplBlock(impl_block) => impl_block.resolver(db), | ||
784 | } | ||
785 | } | ||
786 | } | ||
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 88dee3a69..5c2ea73ce 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -3,9 +3,9 @@ use ra_syntax::{ast, TreeArc}; | |||
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Name, AstId, | 5 | Module, ModuleSource, Name, AstId, |
6 | nameres::{CrateModuleId, ImportId}, | 6 | nameres::CrateModuleId, |
7 | HirDatabase, DefDatabase, | 7 | HirDatabase, DefDatabase, |
8 | HirFileId, ImportSource, | 8 | HirFileId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | impl ModuleSource { | 11 | impl ModuleSource { |
@@ -68,16 +68,6 @@ impl Module { | |||
68 | Some((decl.file_id(), ast)) | 68 | Some((decl.file_id(), ast)) |
69 | } | 69 | } |
70 | 70 | ||
71 | pub(crate) fn import_source_impl( | ||
72 | &self, | ||
73 | db: &impl HirDatabase, | ||
74 | import: ImportId, | ||
75 | ) -> ImportSource { | ||
76 | let (file_id, source) = self.definition_source(db); | ||
77 | let (_, source_map) = db.raw_items_with_source_map(file_id); | ||
78 | source_map.get(&source, import) | ||
79 | } | ||
80 | |||
81 | pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module { | 71 | pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module { |
82 | let def_map = db.crate_def_map(self.krate); | 72 | let def_map = db.crate_def_map(self.krate); |
83 | self.with_module_id(def_map.root()) | 73 | self.with_module_id(def_map.root()) |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index be8a8c98b..18627bbc2 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,10 +1,10 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; | 3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile, ast}; |
4 | use ra_db::{SourceDatabase, salsa}; | 4 | use ra_db::{SourceDatabase, salsa}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, HirInterner, | 7 | HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, MacroCallLoc, |
8 | Function, FnSignature, ExprScopes, TypeAlias, | 8 | Function, FnSignature, ExprScopes, TypeAlias, |
9 | Struct, Enum, StructField, | 9 | Struct, Enum, StructField, |
10 | Const, ConstSignature, Static, | 10 | Const, ConstSignature, Static, |
@@ -15,11 +15,29 @@ use crate::{ | |||
15 | impl_block::{ModuleImplBlocks, ImplSourceMap}, | 15 | impl_block::{ModuleImplBlocks, ImplSourceMap}, |
16 | generics::{GenericParams, GenericDef}, | 16 | generics::{GenericParams, GenericDef}, |
17 | type_ref::TypeRef, | 17 | type_ref::TypeRef, |
18 | traits::TraitData, Trait, ty::TraitRef | 18 | traits::TraitData, Trait, ty::TraitRef, |
19 | ids | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | #[salsa::query_group(DefDatabaseStorage)] | 22 | #[salsa::query_group(DefDatabaseStorage)] |
22 | pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> { | 23 | pub trait DefDatabase: SourceDatabase { |
24 | #[salsa::interned] | ||
25 | fn intern_macro(&self, macro_call: MacroCallLoc) -> ids::MacroCallId; | ||
26 | #[salsa::interned] | ||
27 | fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId; | ||
28 | #[salsa::interned] | ||
29 | fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId; | ||
30 | #[salsa::interned] | ||
31 | fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId; | ||
32 | #[salsa::interned] | ||
33 | fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId; | ||
34 | #[salsa::interned] | ||
35 | fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId; | ||
36 | #[salsa::interned] | ||
37 | fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId; | ||
38 | #[salsa::interned] | ||
39 | fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId; | ||
40 | |||
23 | #[salsa::invoke(crate::ids::macro_def_query)] | 41 | #[salsa::invoke(crate::ids::macro_def_query)] |
24 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; | 42 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; |
25 | 43 | ||
@@ -35,6 +53,9 @@ pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> { | |||
35 | #[salsa::invoke(crate::traits::TraitData::trait_data_query)] | 53 | #[salsa::invoke(crate::traits::TraitData::trait_data_query)] |
36 | fn trait_data(&self, t: Trait) -> Arc<TraitData>; | 54 | fn trait_data(&self, t: Trait) -> Arc<TraitData>; |
37 | 55 | ||
56 | #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] | ||
57 | fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; | ||
58 | |||
38 | #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)] | 59 | #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)] |
39 | fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; | 60 | fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; |
40 | 61 | ||
@@ -110,8 +131,8 @@ pub trait HirDatabase: DefDatabase { | |||
110 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 131 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
111 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 132 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; |
112 | 133 | ||
113 | #[salsa::invoke(crate::ty::method_resolution::implements)] | 134 | #[salsa::invoke(crate::ty::traits::implements)] |
114 | fn implements(&self, trait_ref: TraitRef) -> bool; | 135 | fn implements(&self, trait_ref: TraitRef) -> Option<crate::ty::traits::Solution>; |
115 | } | 136 | } |
116 | 137 | ||
117 | #[test] | 138 | #[test] |
diff --git a/crates/ra_hir/src/either.rs b/crates/ra_hir/src/either.rs new file mode 100644 index 000000000..4073cc82e --- /dev/null +++ b/crates/ra_hir/src/either.rs | |||
@@ -0,0 +1,28 @@ | |||
1 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
2 | pub enum Either<A, B> { | ||
3 | A(A), | ||
4 | B(B), | ||
5 | } | ||
6 | |||
7 | impl<A, B> Either<A, B> { | ||
8 | pub fn either<R, F1, F2>(self, f1: F1, f2: F2) -> R | ||
9 | where | ||
10 | F1: FnOnce(A) -> R, | ||
11 | F2: FnOnce(B) -> R, | ||
12 | { | ||
13 | match self { | ||
14 | Either::A(a) => f1(a), | ||
15 | Either::B(b) => f2(b), | ||
16 | } | ||
17 | } | ||
18 | pub fn map<U, V, F1, F2>(self, f1: F1, f2: F2) -> Either<U, V> | ||
19 | where | ||
20 | F1: FnOnce(A) -> U, | ||
21 | F2: FnOnce(B) -> V, | ||
22 | { | ||
23 | match self { | ||
24 | Either::A(a) => Either::A(f1(a)), | ||
25 | Either::B(b) => Either::B(f2(b)), | ||
26 | } | ||
27 | } | ||
28 | } | ||
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 589a9b2db..817e660f9 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -10,13 +10,13 @@ use ra_syntax::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Path, Name, HirDatabase, Resolver,DefWithBody, | 13 | Path, Name, HirDatabase, Resolver,DefWithBody, Either, |
14 | name::AsName, | 14 | name::AsName, |
15 | type_ref::{Mutability, TypeRef}, | 15 | type_ref::{Mutability, TypeRef}, |
16 | }; | 16 | }; |
17 | use crate::{ path::GenericArgs, ty::primitive::{IntTy, UncertainIntTy, FloatTy, UncertainFloatTy}}; | 17 | use crate::{path::GenericArgs, ty::primitive::{IntTy, UncertainIntTy, FloatTy, UncertainFloatTy}}; |
18 | 18 | ||
19 | pub use self::scope::{ExprScopes, ScopesWithSourceMap, ScopeEntryWithSyntax}; | 19 | pub use self::scope::ExprScopes; |
20 | 20 | ||
21 | pub(crate) mod scope; | 21 | pub(crate) mod scope; |
22 | 22 | ||
@@ -51,11 +51,13 @@ pub struct Body { | |||
51 | pub struct BodySourceMap { | 51 | pub struct BodySourceMap { |
52 | expr_map: FxHashMap<SyntaxNodePtr, ExprId>, | 52 | expr_map: FxHashMap<SyntaxNodePtr, ExprId>, |
53 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, | 53 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, |
54 | pat_map: FxHashMap<SyntaxNodePtr, PatId>, | 54 | pat_map: FxHashMap<PatPtr, PatId>, |
55 | pat_map_back: ArenaMap<PatId, SyntaxNodePtr>, | 55 | pat_map_back: ArenaMap<PatId, PatPtr>, |
56 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::NamedField>>, | 56 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::NamedField>>, |
57 | } | 57 | } |
58 | 58 | ||
59 | type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; | ||
60 | |||
59 | impl Body { | 61 | impl Body { |
60 | pub fn params(&self) -> &[PatId] { | 62 | pub fn params(&self) -> &[PatId] { |
61 | &self.params | 63 | &self.params |
@@ -79,19 +81,23 @@ impl Body { | |||
79 | } | 81 | } |
80 | 82 | ||
81 | // needs arbitrary_self_types to be a method... or maybe move to the def? | 83 | // needs arbitrary_self_types to be a method... or maybe move to the def? |
82 | pub fn resolver_for_expr(body: Arc<Body>, db: &impl HirDatabase, expr_id: ExprId) -> Resolver { | 84 | pub(crate) fn resolver_for_expr( |
85 | body: Arc<Body>, | ||
86 | db: &impl HirDatabase, | ||
87 | expr_id: ExprId, | ||
88 | ) -> Resolver { | ||
83 | let scopes = db.expr_scopes(body.owner); | 89 | let scopes = db.expr_scopes(body.owner); |
84 | resolver_for_scope(body, db, scopes.scope_for(expr_id)) | 90 | resolver_for_scope(body, db, scopes.scope_for(expr_id)) |
85 | } | 91 | } |
86 | 92 | ||
87 | pub fn resolver_for_scope( | 93 | pub(crate) fn resolver_for_scope( |
88 | body: Arc<Body>, | 94 | body: Arc<Body>, |
89 | db: &impl HirDatabase, | 95 | db: &impl HirDatabase, |
90 | scope_id: Option<scope::ScopeId>, | 96 | scope_id: Option<scope::ScopeId>, |
91 | ) -> Resolver { | 97 | ) -> Resolver { |
92 | let mut r = body.owner.resolver(db); | 98 | let mut r = body.owner.resolver(db); |
93 | let scopes = db.expr_scopes(body.owner); | 99 | let scopes = db.expr_scopes(body.owner); |
94 | let scope_chain = scopes.scope_chain_for(scope_id).collect::<Vec<_>>(); | 100 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); |
95 | for scope in scope_chain.into_iter().rev() { | 101 | for scope in scope_chain.into_iter().rev() { |
96 | r = r.push_expr_scope(Arc::clone(&scopes), scope); | 102 | r = r.push_expr_scope(Arc::clone(&scopes), scope); |
97 | } | 103 | } |
@@ -115,31 +121,27 @@ impl Index<PatId> for Body { | |||
115 | } | 121 | } |
116 | 122 | ||
117 | impl BodySourceMap { | 123 | impl BodySourceMap { |
118 | pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { | 124 | pub(crate) fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { |
119 | self.expr_map_back.get(expr).cloned() | 125 | self.expr_map_back.get(expr).cloned() |
120 | } | 126 | } |
121 | 127 | ||
122 | pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> { | 128 | pub(crate) fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> { |
123 | self.expr_map.get(&ptr).cloned() | 129 | self.expr_map.get(&ptr).cloned() |
124 | } | 130 | } |
125 | 131 | ||
126 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { | 132 | pub(crate) fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { |
127 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | 133 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
128 | } | 134 | } |
129 | 135 | ||
130 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { | 136 | pub(crate) fn pat_syntax(&self, pat: PatId) -> Option<PatPtr> { |
131 | self.pat_map_back.get(pat).cloned() | 137 | self.pat_map_back.get(pat).cloned() |
132 | } | 138 | } |
133 | 139 | ||
134 | pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> { | 140 | pub(crate) fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
135 | self.pat_map.get(&ptr).cloned() | 141 | self.pat_map.get(&Either::A(AstPtr::new(node))).cloned() |
136 | } | ||
137 | |||
138 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | ||
139 | self.pat_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | ||
140 | } | 142 | } |
141 | 143 | ||
142 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::NamedField> { | 144 | pub(crate) fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::NamedField> { |
143 | self.field_map[&(expr, field)].clone() | 145 | self.field_map[&(expr, field)].clone() |
144 | } | 146 | } |
145 | } | 147 | } |
@@ -504,10 +506,10 @@ impl ExprCollector { | |||
504 | id | 506 | id |
505 | } | 507 | } |
506 | 508 | ||
507 | fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId { | 509 | fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { |
508 | let id = self.pats.alloc(pat); | 510 | let id = self.pats.alloc(pat); |
509 | self.source_map.pat_map.insert(syntax_ptr, id); | 511 | self.source_map.pat_map.insert(ptr, id); |
510 | self.source_map.pat_map_back.insert(id, syntax_ptr); | 512 | self.source_map.pat_map_back.insert(id, ptr); |
511 | id | 513 | id |
512 | } | 514 | } |
513 | 515 | ||
@@ -886,8 +888,8 @@ impl ExprCollector { | |||
886 | ast::PatKind::LiteralPat(_) => Pat::Missing, | 888 | ast::PatKind::LiteralPat(_) => Pat::Missing, |
887 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, | 889 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, |
888 | }; | 890 | }; |
889 | let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); | 891 | let ptr = AstPtr::new(pat); |
890 | self.alloc_pat(pattern, syntax_ptr) | 892 | self.alloc_pat(pattern, Either::A(ptr)) |
891 | } | 893 | } |
892 | 894 | ||
893 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { | 895 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { |
@@ -911,14 +913,14 @@ impl ExprCollector { | |||
911 | fn collect_fn_body(&mut self, node: &ast::FnDef) { | 913 | fn collect_fn_body(&mut self, node: &ast::FnDef) { |
912 | if let Some(param_list) = node.param_list() { | 914 | if let Some(param_list) = node.param_list() { |
913 | if let Some(self_param) = param_list.self_param() { | 915 | if let Some(self_param) = param_list.self_param() { |
914 | let self_param = SyntaxNodePtr::new(self_param.syntax()); | 916 | let ptr = AstPtr::new(self_param); |
915 | let param_pat = self.alloc_pat( | 917 | let param_pat = self.alloc_pat( |
916 | Pat::Bind { | 918 | Pat::Bind { |
917 | name: Name::self_param(), | 919 | name: Name::self_param(), |
918 | mode: BindingAnnotation::Unannotated, | 920 | mode: BindingAnnotation::Unannotated, |
919 | subpat: None, | 921 | subpat: None, |
920 | }, | 922 | }, |
921 | self_param, | 923 | Either::B(ptr), |
922 | ); | 924 | ); |
923 | self.params.push(param_pat); | 925 | self.params.push(param_pat); |
924 | } | 926 | } |
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index 48283907b..58f365128 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs | |||
@@ -1,17 +1,11 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::FxHashMap; |
4 | |||
5 | use ra_syntax::{ | ||
6 | AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr, | ||
7 | algo::generate, | ||
8 | ast, | ||
9 | }; | ||
10 | use ra_arena::{Arena, RawId, impl_arena_id}; | 4 | use ra_arena::{Arena, RawId, impl_arena_id}; |
11 | 5 | ||
12 | use crate::{ | 6 | use crate::{ |
13 | Name, AsName,DefWithBody, | 7 | Name, DefWithBody, |
14 | expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySourceMap}, | 8 | expr::{PatId, ExprId, Pat, Expr, Body, Statement}, |
15 | HirDatabase, | 9 | HirDatabase, |
16 | }; | 10 | }; |
17 | 11 | ||
@@ -23,23 +17,32 @@ impl_arena_id!(ScopeId); | |||
23 | pub struct ExprScopes { | 17 | pub struct ExprScopes { |
24 | body: Arc<Body>, | 18 | body: Arc<Body>, |
25 | scopes: Arena<ScopeId, ScopeData>, | 19 | scopes: Arena<ScopeId, ScopeData>, |
26 | scope_for: FxHashMap<ExprId, ScopeId>, | 20 | scope_by_expr: FxHashMap<ExprId, ScopeId>, |
27 | } | 21 | } |
28 | 22 | ||
29 | #[derive(Debug, PartialEq, Eq)] | 23 | #[derive(Debug, PartialEq, Eq)] |
30 | pub struct ScopeEntry { | 24 | pub(crate) struct ScopeEntry { |
31 | name: Name, | 25 | name: Name, |
32 | pat: PatId, | 26 | pat: PatId, |
33 | } | 27 | } |
34 | 28 | ||
29 | impl ScopeEntry { | ||
30 | pub(crate) fn name(&self) -> &Name { | ||
31 | &self.name | ||
32 | } | ||
33 | |||
34 | pub(crate) fn pat(&self) -> PatId { | ||
35 | self.pat | ||
36 | } | ||
37 | } | ||
38 | |||
35 | #[derive(Debug, PartialEq, Eq)] | 39 | #[derive(Debug, PartialEq, Eq)] |
36 | pub struct ScopeData { | 40 | pub(crate) struct ScopeData { |
37 | parent: Option<ScopeId>, | 41 | parent: Option<ScopeId>, |
38 | entries: Vec<ScopeEntry>, | 42 | entries: Vec<ScopeEntry>, |
39 | } | 43 | } |
40 | 44 | ||
41 | impl ExprScopes { | 45 | impl ExprScopes { |
42 | // FIXME: This should take something more general than Function | ||
43 | pub(crate) fn expr_scopes_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<ExprScopes> { | 46 | pub(crate) fn expr_scopes_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<ExprScopes> { |
44 | let body = db.body_hir(def); | 47 | let body = db.body_hir(def); |
45 | let res = ExprScopes::new(body); | 48 | let res = ExprScopes::new(body); |
@@ -50,7 +53,7 @@ impl ExprScopes { | |||
50 | let mut scopes = ExprScopes { | 53 | let mut scopes = ExprScopes { |
51 | body: body.clone(), | 54 | body: body.clone(), |
52 | scopes: Arena::default(), | 55 | scopes: Arena::default(), |
53 | scope_for: FxHashMap::default(), | 56 | scope_by_expr: FxHashMap::default(), |
54 | }; | 57 | }; |
55 | let root = scopes.root_scope(); | 58 | let root = scopes.root_scope(); |
56 | scopes.add_params_bindings(root, body.params()); | 59 | scopes.add_params_bindings(root, body.params()); |
@@ -58,19 +61,23 @@ impl ExprScopes { | |||
58 | scopes | 61 | scopes |
59 | } | 62 | } |
60 | 63 | ||
61 | pub fn body(&self) -> Arc<Body> { | 64 | pub(crate) fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { |
62 | self.body.clone() | ||
63 | } | ||
64 | |||
65 | pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { | ||
66 | &self.scopes[scope].entries | 65 | &self.scopes[scope].entries |
67 | } | 66 | } |
68 | 67 | ||
69 | pub fn scope_chain_for<'a>( | 68 | pub(crate) fn scope_chain<'a>( |
70 | &'a self, | 69 | &'a self, |
71 | scope: Option<ScopeId>, | 70 | scope: Option<ScopeId>, |
72 | ) -> impl Iterator<Item = ScopeId> + 'a { | 71 | ) -> impl Iterator<Item = ScopeId> + 'a { |
73 | generate(scope, move |&scope| self.scopes[scope].parent) | 72 | std::iter::successors(scope, move |&scope| self.scopes[scope].parent) |
73 | } | ||
74 | |||
75 | pub(crate) fn scope_for(&self, expr: ExprId) -> Option<ScopeId> { | ||
76 | self.scope_by_expr.get(&expr).map(|&scope| scope) | ||
77 | } | ||
78 | |||
79 | pub(crate) fn scope_by_expr(&self) -> &FxHashMap<ExprId, ScopeId> { | ||
80 | &self.scope_by_expr | ||
74 | } | 81 | } |
75 | 82 | ||
76 | fn root_scope(&mut self) -> ScopeId { | 83 | fn root_scope(&mut self) -> ScopeId { |
@@ -99,130 +106,7 @@ impl ExprScopes { | |||
99 | } | 106 | } |
100 | 107 | ||
101 | fn set_scope(&mut self, node: ExprId, scope: ScopeId) { | 108 | fn set_scope(&mut self, node: ExprId, scope: ScopeId) { |
102 | self.scope_for.insert(node, scope); | 109 | self.scope_by_expr.insert(node, scope); |
103 | } | ||
104 | |||
105 | pub fn scope_for(&self, expr: ExprId) -> Option<ScopeId> { | ||
106 | self.scope_for.get(&expr).map(|&scope| scope) | ||
107 | } | ||
108 | } | ||
109 | |||
110 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
111 | pub struct ScopesWithSourceMap { | ||
112 | pub source_map: Arc<BodySourceMap>, | ||
113 | pub scopes: Arc<ExprScopes>, | ||
114 | } | ||
115 | |||
116 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
117 | pub struct ScopeEntryWithSyntax { | ||
118 | name: Name, | ||
119 | ptr: SyntaxNodePtr, | ||
120 | } | ||
121 | |||
122 | impl ScopeEntryWithSyntax { | ||
123 | pub fn name(&self) -> &Name { | ||
124 | &self.name | ||
125 | } | ||
126 | |||
127 | pub fn ptr(&self) -> SyntaxNodePtr { | ||
128 | self.ptr | ||
129 | } | ||
130 | } | ||
131 | |||
132 | impl ScopesWithSourceMap { | ||
133 | fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a { | ||
134 | generate(self.scope_for(node), move |&scope| self.scopes.scopes[scope].parent) | ||
135 | } | ||
136 | |||
137 | pub fn scope_for_offset(&self, offset: TextUnit) -> Option<ScopeId> { | ||
138 | self.scopes | ||
139 | .scope_for | ||
140 | .iter() | ||
141 | .filter_map(|(id, scope)| Some((self.source_map.expr_syntax(*id)?, scope))) | ||
142 | // find containing scope | ||
143 | .min_by_key(|(ptr, _scope)| { | ||
144 | (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len()) | ||
145 | }) | ||
146 | .map(|(ptr, scope)| self.adjust(ptr, *scope, offset)) | ||
147 | } | ||
148 | |||
149 | // XXX: during completion, cursor might be outside of any particular | ||
150 | // expression. Try to figure out the correct scope... | ||
151 | // FIXME: move this to source binder? | ||
152 | fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { | ||
153 | let r = ptr.range(); | ||
154 | let child_scopes = self | ||
155 | .scopes | ||
156 | .scope_for | ||
157 | .iter() | ||
158 | .filter_map(|(id, scope)| Some((self.source_map.expr_syntax(*id)?, scope))) | ||
159 | .map(|(ptr, scope)| (ptr.range(), scope)) | ||
160 | .filter(|(range, _)| range.start() <= offset && range.is_subrange(&r) && *range != r); | ||
161 | |||
162 | child_scopes | ||
163 | .max_by(|(r1, _), (r2, _)| { | ||
164 | if r2.is_subrange(&r1) { | ||
165 | std::cmp::Ordering::Greater | ||
166 | } else if r1.is_subrange(&r2) { | ||
167 | std::cmp::Ordering::Less | ||
168 | } else { | ||
169 | r1.start().cmp(&r2.start()) | ||
170 | } | ||
171 | }) | ||
172 | .map(|(_ptr, scope)| *scope) | ||
173 | .unwrap_or(original_scope) | ||
174 | } | ||
175 | |||
176 | pub fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> { | ||
177 | let mut shadowed = FxHashSet::default(); | ||
178 | let name = name_ref.as_name(); | ||
179 | let ret = self | ||
180 | .scope_chain(name_ref.syntax()) | ||
181 | .flat_map(|scope| self.scopes.entries(scope).iter()) | ||
182 | .filter(|entry| shadowed.insert(entry.name())) | ||
183 | .filter(|entry| entry.name() == &name) | ||
184 | .nth(0); | ||
185 | ret.and_then(|entry| { | ||
186 | Some(ScopeEntryWithSyntax { | ||
187 | name: entry.name().clone(), | ||
188 | ptr: self.source_map.pat_syntax(entry.pat())?, | ||
189 | }) | ||
190 | }) | ||
191 | } | ||
192 | |||
193 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | ||
194 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | ||
195 | let name_ptr = SyntaxNodePtr::new(pat.syntax()); | ||
196 | fn_def | ||
197 | .syntax() | ||
198 | .descendants() | ||
199 | .filter_map(ast::NameRef::cast) | ||
200 | .filter(|name_ref| match self.resolve_local_name(*name_ref) { | ||
201 | None => false, | ||
202 | Some(entry) => entry.ptr() == name_ptr, | ||
203 | }) | ||
204 | .map(|name_ref| ReferenceDescriptor { | ||
205 | name: name_ref.syntax().text().to_string(), | ||
206 | range: name_ref.syntax().range(), | ||
207 | }) | ||
208 | .collect() | ||
209 | } | ||
210 | |||
211 | pub fn scope_for(&self, node: &SyntaxNode) -> Option<ScopeId> { | ||
212 | node.ancestors() | ||
213 | .map(SyntaxNodePtr::new) | ||
214 | .filter_map(|ptr| self.source_map.syntax_expr(ptr)) | ||
215 | .find_map(|it| self.scopes.scope_for(it)) | ||
216 | } | ||
217 | } | ||
218 | |||
219 | impl ScopeEntry { | ||
220 | pub fn name(&self) -> &Name { | ||
221 | &self.name | ||
222 | } | ||
223 | |||
224 | pub fn pat(&self) -> PatId { | ||
225 | self.pat | ||
226 | } | 110 | } |
227 | } | 111 | } |
228 | 112 | ||
@@ -286,22 +170,13 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope | |||
286 | }; | 170 | }; |
287 | } | 171 | } |
288 | 172 | ||
289 | #[derive(Debug)] | ||
290 | pub struct ReferenceDescriptor { | ||
291 | pub range: TextRange, | ||
292 | pub name: String, | ||
293 | } | ||
294 | |||
295 | #[cfg(test)] | 173 | #[cfg(test)] |
296 | mod tests { | 174 | mod tests { |
297 | use ra_syntax::{SourceFile, algo::find_node_at_offset}; | 175 | use ra_db::SourceDatabase; |
176 | use ra_syntax::{algo::find_node_at_offset, AstNode, SyntaxNodePtr, ast}; | ||
298 | use test_utils::{extract_offset, assert_eq_text}; | 177 | use test_utils::{extract_offset, assert_eq_text}; |
299 | use ra_arena::ArenaId; | ||
300 | use crate::Function; | ||
301 | |||
302 | use crate::expr::{ExprCollector}; | ||
303 | 178 | ||
304 | use super::*; | 179 | use crate::{source_binder::SourceAnalyzer, mock::MockDatabase}; |
305 | 180 | ||
306 | fn do_check(code: &str, expected: &[&str]) { | 181 | fn do_check(code: &str, expected: &[&str]) { |
307 | let (off, code) = extract_offset(code); | 182 | let (off, code) = extract_offset(code); |
@@ -313,17 +188,20 @@ mod tests { | |||
313 | buf.push_str(&code[off..]); | 188 | buf.push_str(&code[off..]); |
314 | buf | 189 | buf |
315 | }; | 190 | }; |
316 | let file = SourceFile::parse(&code); | 191 | |
192 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&code); | ||
193 | let file = db.parse(file_id); | ||
317 | let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); | 194 | let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); |
318 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | 195 | let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); |
319 | let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; | 196 | |
320 | let (body, source_map) = collect_fn_body_syntax(irrelevant_function, fn_def); | 197 | let scopes = analyzer.scopes(); |
321 | let scopes = ExprScopes::new(Arc::new(body)); | 198 | let expr_id = |
322 | let scopes = | 199 | analyzer.body_source_map().syntax_expr(SyntaxNodePtr::new(marker.syntax())).unwrap(); |
323 | ScopesWithSourceMap { scopes: Arc::new(scopes), source_map: Arc::new(source_map) }; | 200 | let scope = scopes.scope_for(expr_id); |
201 | |||
324 | let actual = scopes | 202 | let actual = scopes |
325 | .scope_chain(marker.syntax()) | 203 | .scope_chain(scope) |
326 | .flat_map(|scope| scopes.scopes.entries(scope)) | 204 | .flat_map(|scope| scopes.entries(scope)) |
327 | .map(|it| it.name().to_string()) | 205 | .map(|it| it.name().to_string()) |
328 | .collect::<Vec<_>>() | 206 | .collect::<Vec<_>>() |
329 | .join("\n"); | 207 | .join("\n"); |
@@ -406,28 +284,19 @@ mod tests { | |||
406 | ); | 284 | ); |
407 | } | 285 | } |
408 | 286 | ||
409 | fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> (Body, BodySourceMap) { | ||
410 | let mut collector = ExprCollector::new(DefWithBody::Function(function)); | ||
411 | collector.collect_fn_body(node); | ||
412 | collector.finish() | ||
413 | } | ||
414 | |||
415 | fn do_check_local_name(code: &str, expected_offset: u32) { | 287 | fn do_check_local_name(code: &str, expected_offset: u32) { |
416 | let (off, code) = extract_offset(code); | 288 | let (off, code) = extract_offset(code); |
417 | let file = SourceFile::parse(&code); | 289 | |
290 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&code); | ||
291 | let file = db.parse(file_id); | ||
418 | let expected_name = find_node_at_offset::<ast::Name>(file.syntax(), expected_offset.into()) | 292 | let expected_name = find_node_at_offset::<ast::Name>(file.syntax(), expected_offset.into()) |
419 | .expect("failed to find a name at the target offset"); | 293 | .expect("failed to find a name at the target offset"); |
420 | |||
421 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | ||
422 | let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); | 294 | let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); |
295 | let analyzer = SourceAnalyzer::new(&db, file_id, name_ref.syntax(), None); | ||
423 | 296 | ||
424 | let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; | 297 | let local_name_entry = analyzer.resolve_local_name(name_ref).unwrap(); |
425 | let (body, source_map) = collect_fn_body_syntax(irrelevant_function, fn_def); | 298 | let local_name = |
426 | let scopes = ExprScopes::new(Arc::new(body)); | 299 | local_name_entry.ptr().either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); |
427 | let scopes = | ||
428 | ScopesWithSourceMap { scopes: Arc::new(scopes), source_map: Arc::new(source_map) }; | ||
429 | let local_name_entry = scopes.resolve_local_name(name_ref).unwrap(); | ||
430 | let local_name = local_name_entry.ptr(); | ||
431 | assert_eq!(local_name.range(), expected_name.syntax().range()); | 300 | assert_eq!(local_name.range(), expected_name.syntax().range()); |
432 | } | 301 | } |
433 | 302 | ||
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 84fe94289..5625c2459 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -9,7 +9,7 @@ use ra_syntax::ast::{self, NameOwner, TypeParamsOwner}; | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::DefDatabase, | 11 | db::DefDatabase, |
12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock | 12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container |
13 | }; | 13 | }; |
14 | 14 | ||
15 | /// Data about a generic parameter (to a function, struct, impl, ...). | 15 | /// Data about a generic parameter (to a function, struct, impl, ...). |
@@ -27,6 +27,7 @@ pub struct GenericParams { | |||
27 | pub(crate) params: Vec<GenericParam>, | 27 | pub(crate) params: Vec<GenericParam>, |
28 | } | 28 | } |
29 | 29 | ||
30 | // FIXME: consts can have type parameters from their parents (i.e. associated consts of traits) | ||
30 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 31 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
31 | pub enum GenericDef { | 32 | pub enum GenericDef { |
32 | Function(Function), | 33 | Function(Function), |
@@ -45,18 +46,22 @@ impl GenericParams { | |||
45 | ) -> Arc<GenericParams> { | 46 | ) -> Arc<GenericParams> { |
46 | let mut generics = GenericParams::default(); | 47 | let mut generics = GenericParams::default(); |
47 | let parent = match def { | 48 | let parent = match def { |
48 | GenericDef::Function(it) => it.impl_block(db), | 49 | GenericDef::Function(it) => it.container(db).map(GenericDef::from), |
49 | GenericDef::TypeAlias(it) => it.impl_block(db), | 50 | GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), |
50 | GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None, | 51 | GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None, |
51 | GenericDef::ImplBlock(_) => None, | 52 | GenericDef::ImplBlock(_) => None, |
52 | }; | 53 | }; |
53 | generics.parent_params = parent.map(|p| p.generic_params(db)); | 54 | generics.parent_params = parent.map(|p| db.generic_params(p)); |
54 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; | 55 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; |
55 | match def { | 56 | match def { |
56 | GenericDef::Function(it) => generics.fill(&*it.source(db).1, start), | 57 | GenericDef::Function(it) => generics.fill(&*it.source(db).1, start), |
57 | GenericDef::Struct(it) => generics.fill(&*it.source(db).1, start), | 58 | GenericDef::Struct(it) => generics.fill(&*it.source(db).1, start), |
58 | GenericDef::Enum(it) => generics.fill(&*it.source(db).1, start), | 59 | GenericDef::Enum(it) => generics.fill(&*it.source(db).1, start), |
59 | GenericDef::Trait(it) => generics.fill(&*it.source(db).1, start), | 60 | GenericDef::Trait(it) => { |
61 | // traits get the Self type as an implicit first type parameter | ||
62 | generics.params.push(GenericParam { idx: start, name: Name::self_type() }); | ||
63 | generics.fill(&*it.source(db).1, start + 1); | ||
64 | } | ||
60 | GenericDef::TypeAlias(it) => generics.fill(&*it.source(db).1, start), | 65 | GenericDef::TypeAlias(it) => generics.fill(&*it.source(db).1, start), |
61 | GenericDef::ImplBlock(it) => generics.fill(&*it.source(db).1, start), | 66 | GenericDef::ImplBlock(it) => generics.fill(&*it.source(db).1, start), |
62 | } | 67 | } |
@@ -104,3 +109,25 @@ impl GenericParams { | |||
104 | vec | 109 | vec |
105 | } | 110 | } |
106 | } | 111 | } |
112 | |||
113 | impl From<Container> for GenericDef { | ||
114 | fn from(c: Container) -> Self { | ||
115 | match c { | ||
116 | Container::Trait(trait_) => trait_.into(), | ||
117 | Container::ImplBlock(impl_block) => impl_block.into(), | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | pub trait HasGenericParams { | ||
123 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>; | ||
124 | } | ||
125 | |||
126 | impl<T> HasGenericParams for T | ||
127 | where | ||
128 | T: Into<GenericDef>, | ||
129 | { | ||
130 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
131 | db.generic_params(self.into()) | ||
132 | } | ||
133 | } | ||
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index eb9939df7..141c9072f 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -3,40 +3,14 @@ use std::{ | |||
3 | sync::Arc, | 3 | sync::Arc, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | use ra_db::{LocationInterner, FileId}; | 6 | use ra_db::{FileId, salsa}; |
7 | use ra_syntax::{TreeArc, SourceFile, AstNode, ast}; | 7 | use ra_syntax::{TreeArc, SourceFile, AstNode, ast}; |
8 | use ra_arena::{RawId, ArenaId, impl_arena_id}; | ||
9 | use mbe::MacroRules; | 8 | use mbe::MacroRules; |
10 | 9 | ||
11 | use crate::{ | 10 | use crate::{ |
12 | Module, DefDatabase, AstId, FileAstId, | 11 | Module, DefDatabase, AstId, FileAstId, |
13 | }; | 12 | }; |
14 | 13 | ||
15 | #[derive(Debug, Default)] | ||
16 | pub struct HirInterner { | ||
17 | macros: LocationInterner<MacroCallLoc, MacroCallId>, | ||
18 | fns: LocationInterner<ItemLoc<ast::FnDef>, FunctionId>, | ||
19 | structs: LocationInterner<ItemLoc<ast::StructDef>, StructId>, | ||
20 | enums: LocationInterner<ItemLoc<ast::EnumDef>, EnumId>, | ||
21 | consts: LocationInterner<ItemLoc<ast::ConstDef>, ConstId>, | ||
22 | statics: LocationInterner<ItemLoc<ast::StaticDef>, StaticId>, | ||
23 | traits: LocationInterner<ItemLoc<ast::TraitDef>, TraitId>, | ||
24 | types: LocationInterner<ItemLoc<ast::TypeAliasDef>, TypeAliasId>, | ||
25 | } | ||
26 | |||
27 | impl HirInterner { | ||
28 | pub fn len(&self) -> usize { | ||
29 | self.macros.len() | ||
30 | + self.fns.len() | ||
31 | + self.structs.len() | ||
32 | + self.enums.len() | ||
33 | + self.consts.len() | ||
34 | + self.statics.len() | ||
35 | + self.traits.len() | ||
36 | + self.types.len() | ||
37 | } | ||
38 | } | ||
39 | |||
40 | /// hir makes heavy use of ids: integer (u32) handlers to various things. You | 14 | /// hir makes heavy use of ids: integer (u32) handlers to various things. You |
41 | /// can think of id as a pointer (but without a lifetime) or a file descriptor | 15 | /// can think of id as a pointer (but without a lifetime) or a file descriptor |
42 | /// (but for hir objects). | 16 | /// (but for hir objects). |
@@ -135,11 +109,24 @@ pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<A | |||
135 | Some(Arc::new(rules)) | 109 | Some(Arc::new(rules)) |
136 | } | 110 | } |
137 | 111 | ||
112 | macro_rules! impl_intern_key { | ||
113 | ($name:ident) => { | ||
114 | impl salsa::InternKey for $name { | ||
115 | fn from_intern_id(v: salsa::InternId) -> Self { | ||
116 | $name(v) | ||
117 | } | ||
118 | fn as_intern_id(&self) -> salsa::InternId { | ||
119 | self.0 | ||
120 | } | ||
121 | } | ||
122 | }; | ||
123 | } | ||
124 | |||
138 | /// `MacroCallId` identifies a particular macro invocation, like | 125 | /// `MacroCallId` identifies a particular macro invocation, like |
139 | /// `println!("Hello, {}", world)`. | 126 | /// `println!("Hello, {}", world)`. |
140 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 127 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
141 | pub struct MacroCallId(RawId); | 128 | pub struct MacroCallId(salsa::InternId); |
142 | impl_arena_id!(MacroCallId); | 129 | impl_intern_key!(MacroCallId); |
143 | 130 | ||
144 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 131 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
145 | pub struct MacroCallLoc { | 132 | pub struct MacroCallLoc { |
@@ -148,14 +135,14 @@ pub struct MacroCallLoc { | |||
148 | } | 135 | } |
149 | 136 | ||
150 | impl MacroCallId { | 137 | impl MacroCallId { |
151 | pub(crate) fn loc(self, db: &impl AsRef<HirInterner>) -> MacroCallLoc { | 138 | pub(crate) fn loc(self, db: &impl DefDatabase) -> MacroCallLoc { |
152 | db.as_ref().macros.id2loc(self) | 139 | db.lookup_intern_macro(self) |
153 | } | 140 | } |
154 | } | 141 | } |
155 | 142 | ||
156 | impl MacroCallLoc { | 143 | impl MacroCallLoc { |
157 | pub(crate) fn id(&self, db: &impl AsRef<HirInterner>) -> MacroCallId { | 144 | pub(crate) fn id(self, db: &impl DefDatabase) -> MacroCallId { |
158 | db.as_ref().macros.loc2id(&self) | 145 | db.intern_macro(self) |
159 | } | 146 | } |
160 | } | 147 | } |
161 | 148 | ||
@@ -204,8 +191,10 @@ impl<'a, DB: DefDatabase> LocationCtx<&'a DB> { | |||
204 | } | 191 | } |
205 | } | 192 | } |
206 | 193 | ||
207 | pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | 194 | pub(crate) trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { |
208 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; | 195 | fn intern(db: &impl DefDatabase, loc: ItemLoc<N>) -> Self; |
196 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<N>; | ||
197 | |||
209 | fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { | 198 | fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { |
210 | let items = ctx.db.ast_id_map(ctx.file_id); | 199 | let items = ctx.db.ast_id_map(ctx.file_id); |
211 | let item_id = items.ast_id(ast); | 200 | let item_id = items.ast_id(ast); |
@@ -213,80 +202,100 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
213 | } | 202 | } |
214 | fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self { | 203 | fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self { |
215 | let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; | 204 | let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; |
216 | Self::interner(ctx.db.as_ref()).loc2id(&loc) | 205 | Self::intern(ctx.db, loc) |
217 | } | 206 | } |
218 | fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) { | 207 | fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) { |
219 | let int = Self::interner(db.as_ref()); | 208 | let loc = self.lookup_intern(db); |
220 | let loc = int.id2loc(self); | ||
221 | let ast = loc.ast_id.to_node(db); | 209 | let ast = loc.ast_id.to_node(db); |
222 | (loc.ast_id.file_id(), ast) | 210 | (loc.ast_id.file_id(), ast) |
223 | } | 211 | } |
224 | fn module(self, db: &impl DefDatabase) -> Module { | 212 | fn module(self, db: &impl DefDatabase) -> Module { |
225 | let int = Self::interner(db.as_ref()); | 213 | let loc = self.lookup_intern(db); |
226 | let loc = int.id2loc(self); | ||
227 | loc.module | 214 | loc.module |
228 | } | 215 | } |
229 | } | 216 | } |
230 | 217 | ||
231 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 218 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
232 | pub(crate) struct FunctionId(RawId); | 219 | pub struct FunctionId(salsa::InternId); |
233 | impl_arena_id!(FunctionId); | 220 | impl_intern_key!(FunctionId); |
221 | |||
234 | impl AstItemDef<ast::FnDef> for FunctionId { | 222 | impl AstItemDef<ast::FnDef> for FunctionId { |
235 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::FnDef>, Self> { | 223 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::FnDef>) -> Self { |
236 | &interner.fns | 224 | db.intern_function(loc) |
225 | } | ||
226 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::FnDef> { | ||
227 | db.lookup_intern_function(self) | ||
237 | } | 228 | } |
238 | } | 229 | } |
239 | 230 | ||
240 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 231 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
241 | pub(crate) struct StructId(RawId); | 232 | pub struct StructId(salsa::InternId); |
242 | impl_arena_id!(StructId); | 233 | impl_intern_key!(StructId); |
243 | impl AstItemDef<ast::StructDef> for StructId { | 234 | impl AstItemDef<ast::StructDef> for StructId { |
244 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StructDef>, Self> { | 235 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::StructDef>) -> Self { |
245 | &interner.structs | 236 | db.intern_struct(loc) |
237 | } | ||
238 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::StructDef> { | ||
239 | db.lookup_intern_struct(self) | ||
246 | } | 240 | } |
247 | } | 241 | } |
248 | 242 | ||
249 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 243 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
250 | pub(crate) struct EnumId(RawId); | 244 | pub struct EnumId(salsa::InternId); |
251 | impl_arena_id!(EnumId); | 245 | impl_intern_key!(EnumId); |
252 | impl AstItemDef<ast::EnumDef> for EnumId { | 246 | impl AstItemDef<ast::EnumDef> for EnumId { |
253 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::EnumDef>, Self> { | 247 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::EnumDef>) -> Self { |
254 | &interner.enums | 248 | db.intern_enum(loc) |
249 | } | ||
250 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::EnumDef> { | ||
251 | db.lookup_intern_enum(self) | ||
255 | } | 252 | } |
256 | } | 253 | } |
257 | 254 | ||
258 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 255 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
259 | pub(crate) struct ConstId(RawId); | 256 | pub struct ConstId(salsa::InternId); |
260 | impl_arena_id!(ConstId); | 257 | impl_intern_key!(ConstId); |
261 | impl AstItemDef<ast::ConstDef> for ConstId { | 258 | impl AstItemDef<ast::ConstDef> for ConstId { |
262 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::ConstDef>, Self> { | 259 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::ConstDef>) -> Self { |
263 | &interner.consts | 260 | db.intern_const(loc) |
261 | } | ||
262 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::ConstDef> { | ||
263 | db.lookup_intern_const(self) | ||
264 | } | 264 | } |
265 | } | 265 | } |
266 | 266 | ||
267 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 267 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
268 | pub(crate) struct StaticId(RawId); | 268 | pub struct StaticId(salsa::InternId); |
269 | impl_arena_id!(StaticId); | 269 | impl_intern_key!(StaticId); |
270 | impl AstItemDef<ast::StaticDef> for StaticId { | 270 | impl AstItemDef<ast::StaticDef> for StaticId { |
271 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StaticDef>, Self> { | 271 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::StaticDef>) -> Self { |
272 | &interner.statics | 272 | db.intern_static(loc) |
273 | } | ||
274 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::StaticDef> { | ||
275 | db.lookup_intern_static(self) | ||
273 | } | 276 | } |
274 | } | 277 | } |
275 | 278 | ||
276 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 279 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
277 | pub(crate) struct TraitId(RawId); | 280 | pub struct TraitId(salsa::InternId); |
278 | impl_arena_id!(TraitId); | 281 | impl_intern_key!(TraitId); |
279 | impl AstItemDef<ast::TraitDef> for TraitId { | 282 | impl AstItemDef<ast::TraitDef> for TraitId { |
280 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TraitDef>, Self> { | 283 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::TraitDef>) -> Self { |
281 | &interner.traits | 284 | db.intern_trait(loc) |
285 | } | ||
286 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::TraitDef> { | ||
287 | db.lookup_intern_trait(self) | ||
282 | } | 288 | } |
283 | } | 289 | } |
284 | 290 | ||
285 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 291 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
286 | pub(crate) struct TypeAliasId(RawId); | 292 | pub struct TypeAliasId(salsa::InternId); |
287 | impl_arena_id!(TypeAliasId); | 293 | impl_intern_key!(TypeAliasId); |
288 | impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { | 294 | impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { |
289 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TypeAliasDef>, Self> { | 295 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self { |
290 | &interner.types | 296 | db.intern_type_alias(loc) |
297 | } | ||
298 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::TypeAliasDef> { | ||
299 | db.lookup_intern_type_alias(self) | ||
291 | } | 300 | } |
292 | } | 301 | } |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 40d368cd9..a8a466e43 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -9,16 +9,15 @@ use ra_syntax::{ | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | Const, TypeAlias, Function, HirFileId, | 11 | Const, TypeAlias, Function, HirFileId, |
12 | HirDatabase, DefDatabase, | 12 | HirDatabase, DefDatabase, TraitRef, |
13 | ModuleDef, Trait, Resolution, | ||
14 | type_ref::TypeRef, | 13 | type_ref::TypeRef, |
15 | ids::LocationCtx, | 14 | ids::LocationCtx, |
16 | resolve::Resolver, | 15 | resolve::Resolver, |
17 | ty::Ty, generics::GenericParams, | 16 | ty::Ty, |
17 | generics::HasGenericParams, | ||
18 | code_model_api::{Module, ModuleSource} | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | use crate::code_model_api::{Module, ModuleSource}; | ||
21 | |||
22 | #[derive(Debug, Default, PartialEq, Eq)] | 21 | #[derive(Debug, Default, PartialEq, Eq)] |
23 | pub struct ImplSourceMap { | 22 | pub struct ImplSourceMap { |
24 | map: ArenaMap<ImplId, AstPtr<ast::ImplBlock>>, | 23 | map: ArenaMap<ImplId, AstPtr<ast::ImplBlock>>, |
@@ -73,7 +72,7 @@ impl ImplBlock { | |||
73 | self.module | 72 | self.module |
74 | } | 73 | } |
75 | 74 | ||
76 | pub fn target_trait_ref(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 75 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
77 | db.impls_in_module(self.module).impls[self.impl_id].target_trait().cloned() | 76 | db.impls_in_module(self.module).impls[self.impl_id].target_trait().cloned() |
78 | } | 77 | } |
79 | 78 | ||
@@ -85,27 +84,16 @@ impl ImplBlock { | |||
85 | Ty::from_hir(db, &self.resolver(db), &self.target_type(db)) | 84 | Ty::from_hir(db, &self.resolver(db), &self.target_type(db)) |
86 | } | 85 | } |
87 | 86 | ||
88 | pub fn target_trait(&self, db: &impl HirDatabase) -> Option<Trait> { | 87 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { |
89 | if let Some(TypeRef::Path(path)) = self.target_trait_ref(db) { | 88 | let target_ty = self.target_ty(db); |
90 | let resolver = self.resolver(db); | 89 | TraitRef::from_hir(db, &self.resolver(db), &self.target_trait(db)?, Some(target_ty)) |
91 | if let Some(Resolution::Def(ModuleDef::Trait(tr))) = | ||
92 | resolver.resolve_path(db, &path).take_types() | ||
93 | { | ||
94 | return Some(tr); | ||
95 | } | ||
96 | } | ||
97 | None | ||
98 | } | 90 | } |
99 | 91 | ||
100 | pub fn items(&self, db: &impl DefDatabase) -> Vec<ImplItem> { | 92 | pub fn items(&self, db: &impl DefDatabase) -> Vec<ImplItem> { |
101 | db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() | 93 | db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() |
102 | } | 94 | } |
103 | 95 | ||
104 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { | 96 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { |
105 | db.generic_params((*self).into()) | ||
106 | } | ||
107 | |||
108 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | ||
109 | let r = self.module().resolver(db); | 97 | let r = self.module().resolver(db); |
110 | // add generic params, if present | 98 | // add generic params, if present |
111 | let p = self.generic_params(db); | 99 | let p = self.generic_params(db); |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index c19450f39..9292de1b5 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -17,6 +17,8 @@ macro_rules! impl_froms { | |||
17 | } | 17 | } |
18 | } | 18 | } |
19 | 19 | ||
20 | mod either; | ||
21 | |||
20 | pub mod db; | 22 | pub mod db; |
21 | #[macro_use] | 23 | #[macro_use] |
22 | pub mod mock; | 24 | pub mod mock; |
@@ -49,20 +51,24 @@ use crate::{ | |||
49 | db::{HirDatabase, DefDatabase}, | 51 | db::{HirDatabase, DefDatabase}, |
50 | name::{AsName, KnownName}, | 52 | name::{AsName, KnownName}, |
51 | source_id::{FileAstId, AstId}, | 53 | source_id::{FileAstId, AstId}, |
54 | resolve::Resolver, | ||
52 | }; | 55 | }; |
53 | 56 | ||
54 | pub use self::{ | 57 | pub use self::{ |
58 | either::Either, | ||
55 | path::{Path, PathKind}, | 59 | path::{Path, PathKind}, |
56 | name::Name, | 60 | name::Name, |
57 | source_id::{AstIdMap, ErasedFileAstId}, | 61 | source_id::{AstIdMap, ErasedFileAstId}, |
58 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, | 62 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc}, |
59 | nameres::{PerNs, Namespace, ImportId, ImportSource}, | 63 | nameres::{PerNs, Namespace, ImportId}, |
60 | ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, | 64 | ty::{Ty, ApplicationTy, TypeCtor, TraitRef, Substs, display::HirDisplay, CallableDef}, |
61 | impl_block::{ImplBlock, ImplItem}, | 65 | impl_block::{ImplBlock, ImplItem}, |
62 | docs::{Docs, Documentation}, | 66 | docs::{Docs, Documentation}, |
63 | adt::AdtDef, | 67 | adt::AdtDef, |
64 | expr::{ExprScopes, ScopesWithSourceMap, ScopeEntryWithSyntax}, | 68 | expr::ExprScopes, |
65 | resolve::{Resolver, Resolution}, | 69 | resolve::Resolution, |
70 | generics::{GenericParams, GenericParam, HasGenericParams}, | ||
71 | source_binder::{SourceAnalyzer, PathResolution, ScopeEntryWithSyntax}, | ||
66 | }; | 72 | }; |
67 | 73 | ||
68 | pub use self::code_model_api::{ | 74 | pub use self::code_model_api::{ |
@@ -73,5 +79,5 @@ pub use self::code_model_api::{ | |||
73 | Function, FnSignature, | 79 | Function, FnSignature, |
74 | StructField, FieldSource, | 80 | StructField, FieldSource, |
75 | Static, Const, ConstSignature, | 81 | Static, Const, ConstSignature, |
76 | Trait, TypeAlias, | 82 | Trait, TypeAlias, Container, |
77 | }; | 83 | }; |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index aeab6b180..fa5882dea 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -9,7 +9,7 @@ use relative_path::RelativePathBuf; | |||
9 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; | 9 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; |
10 | use rustc_hash::FxHashMap; | 10 | use rustc_hash::FxHashMap; |
11 | 11 | ||
12 | use crate::{db, HirInterner, diagnostics::DiagnosticSink}; | 12 | use crate::{db, diagnostics::DiagnosticSink}; |
13 | 13 | ||
14 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | 14 | pub const WORKSPACE: SourceRootId = SourceRootId(0); |
15 | 15 | ||
@@ -18,7 +18,6 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0); | |||
18 | pub struct MockDatabase { | 18 | pub struct MockDatabase { |
19 | events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, | 19 | events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, |
20 | runtime: salsa::Runtime<MockDatabase>, | 20 | runtime: salsa::Runtime<MockDatabase>, |
21 | interner: Arc<HirInterner>, | ||
22 | files: FxHashMap<String, FileId>, | 21 | files: FxHashMap<String, FileId>, |
23 | } | 22 | } |
24 | 23 | ||
@@ -195,7 +194,6 @@ impl Default for MockDatabase { | |||
195 | let mut db = MockDatabase { | 194 | let mut db = MockDatabase { |
196 | events: Default::default(), | 195 | events: Default::default(), |
197 | runtime: salsa::Runtime::default(), | 196 | runtime: salsa::Runtime::default(), |
198 | interner: Default::default(), | ||
199 | files: FxHashMap::default(), | 197 | files: FxHashMap::default(), |
200 | }; | 198 | }; |
201 | db.set_crate_graph(Default::default()); | 199 | db.set_crate_graph(Default::default()); |
@@ -208,19 +206,12 @@ impl salsa::ParallelDatabase for MockDatabase { | |||
208 | salsa::Snapshot::new(MockDatabase { | 206 | salsa::Snapshot::new(MockDatabase { |
209 | events: Default::default(), | 207 | events: Default::default(), |
210 | runtime: self.runtime.snapshot(self), | 208 | runtime: self.runtime.snapshot(self), |
211 | interner: Arc::clone(&self.interner), | ||
212 | // only the root database can be used to get file_id by path. | 209 | // only the root database can be used to get file_id by path. |
213 | files: FxHashMap::default(), | 210 | files: FxHashMap::default(), |
214 | }) | 211 | }) |
215 | } | 212 | } |
216 | } | 213 | } |
217 | 214 | ||
218 | impl AsRef<HirInterner> for MockDatabase { | ||
219 | fn as_ref(&self) -> &HirInterner { | ||
220 | &self.interner | ||
221 | } | ||
222 | } | ||
223 | |||
224 | impl MockDatabase { | 215 | impl MockDatabase { |
225 | pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<MockDatabase>> { | 216 | pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<MockDatabase>> { |
226 | *self.events.lock() = Some(Vec::new()); | 217 | *self.events.lock() = Some(Vec::new()); |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 4ae04514a..0eddfab12 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -75,7 +75,7 @@ pub(crate) use self::raw::{RawItems, ImportSourceMap}; | |||
75 | 75 | ||
76 | pub use self::{ | 76 | pub use self::{ |
77 | per_ns::{PerNs, Namespace}, | 77 | per_ns::{PerNs, Namespace}, |
78 | raw::{ImportId, ImportSource}, | 78 | raw::ImportId, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /// Contans all top-level defs from a macro-expanded crate | 81 | /// Contans all top-level defs from a macro-expanded crate |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index b7416ede6..43c97a0bf 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -12,7 +12,7 @@ use ra_syntax::{ | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, | 14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, |
15 | AstIdMap, FileAstId, | 15 | AstIdMap, FileAstId, Either, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | /// `RawItems` is a set of top-level items in a file (except for impls). | 18 | /// `RawItems` is a set of top-level items in a file (except for impls). |
@@ -34,28 +34,15 @@ pub struct ImportSourceMap { | |||
34 | map: ArenaMap<ImportId, ImportSourcePtr>, | 34 | map: ArenaMap<ImportId, ImportSourcePtr>, |
35 | } | 35 | } |
36 | 36 | ||
37 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 37 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; |
38 | enum ImportSourcePtr { | 38 | type ImportSource = Either<TreeArc<ast::UseTree>, TreeArc<ast::ExternCrateItem>>; |
39 | UseTree(AstPtr<ast::UseTree>), | ||
40 | ExternCrate(AstPtr<ast::ExternCrateItem>), | ||
41 | } | ||
42 | 39 | ||
43 | impl ImportSourcePtr { | 40 | impl ImportSourcePtr { |
44 | fn to_node(self, file: &SourceFile) -> ImportSource { | 41 | fn to_node(self, file: &SourceFile) -> ImportSource { |
45 | match self { | 42 | self.map(|ptr| ptr.to_node(file).to_owned(), |ptr| ptr.to_node(file).to_owned()) |
46 | ImportSourcePtr::UseTree(ptr) => ImportSource::UseTree(ptr.to_node(file).to_owned()), | ||
47 | ImportSourcePtr::ExternCrate(ptr) => { | ||
48 | ImportSource::ExternCrate(ptr.to_node(file).to_owned()) | ||
49 | } | ||
50 | } | ||
51 | } | 43 | } |
52 | } | 44 | } |
53 | 45 | ||
54 | pub enum ImportSource { | ||
55 | UseTree(TreeArc<ast::UseTree>), | ||
56 | ExternCrate(TreeArc<ast::ExternCrateItem>), | ||
57 | } | ||
58 | |||
59 | impl ImportSourceMap { | 46 | impl ImportSourceMap { |
60 | fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { | 47 | fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { |
61 | self.map.insert(import, ptr) | 48 | self.map.insert(import, ptr) |
@@ -281,11 +268,7 @@ impl RawItemsCollector { | |||
281 | Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { | 268 | Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { |
282 | let import_data = | 269 | let import_data = |
283 | ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false }; | 270 | ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false }; |
284 | self.push_import( | 271 | self.push_import(current_module, import_data, Either::A(AstPtr::new(use_tree))); |
285 | current_module, | ||
286 | import_data, | ||
287 | ImportSourcePtr::UseTree(AstPtr::new(use_tree)), | ||
288 | ); | ||
289 | }) | 272 | }) |
290 | } | 273 | } |
291 | 274 | ||
@@ -304,11 +287,7 @@ impl RawItemsCollector { | |||
304 | is_prelude: false, | 287 | is_prelude: false, |
305 | is_extern_crate: true, | 288 | is_extern_crate: true, |
306 | }; | 289 | }; |
307 | self.push_import( | 290 | self.push_import(current_module, import_data, Either::B(AstPtr::new(extern_crate))); |
308 | current_module, | ||
309 | import_data, | ||
310 | ImportSourcePtr::ExternCrate(AstPtr::new(extern_crate)), | ||
311 | ); | ||
312 | } | 291 | } |
313 | } | 292 | } |
314 | 293 | ||
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 2609585b1..685f4b8b1 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -9,13 +9,13 @@ use crate::{ | |||
9 | name::{Name, KnownName}, | 9 | name::{Name, KnownName}, |
10 | nameres::{PerNs, CrateDefMap, CrateModuleId}, | 10 | nameres::{PerNs, CrateDefMap, CrateModuleId}, |
11 | generics::GenericParams, | 11 | generics::GenericParams, |
12 | expr::{scope::{ExprScopes, ScopeId}, PatId, Body}, | 12 | expr::{scope::{ExprScopes, ScopeId}, PatId}, |
13 | impl_block::ImplBlock, | 13 | impl_block::ImplBlock, |
14 | path::Path, Trait | 14 | path::Path, Trait |
15 | }; | 15 | }; |
16 | 16 | ||
17 | #[derive(Debug, Clone, Default)] | 17 | #[derive(Debug, Clone, Default)] |
18 | pub struct Resolver { | 18 | pub(crate) struct Resolver { |
19 | scopes: Vec<Scope>, | 19 | scopes: Vec<Scope>, |
20 | } | 20 | } |
21 | 21 | ||
@@ -117,7 +117,7 @@ pub enum Resolution { | |||
117 | } | 117 | } |
118 | 118 | ||
119 | impl Resolver { | 119 | impl Resolver { |
120 | pub fn resolve_name(&self, db: &impl HirDatabase, name: &Name) -> PerNs<Resolution> { | 120 | pub(crate) fn resolve_name(&self, db: &impl HirDatabase, name: &Name) -> PerNs<Resolution> { |
121 | let mut resolution = PerNs::none(); | 121 | let mut resolution = PerNs::none(); |
122 | for scope in self.scopes.iter().rev() { | 122 | for scope in self.scopes.iter().rev() { |
123 | resolution = resolution.or(scope.resolve_name(db, name)); | 123 | resolution = resolution.or(scope.resolve_name(db, name)); |
@@ -154,12 +154,12 @@ impl Resolver { | |||
154 | 154 | ||
155 | /// Returns the fully resolved path if we were able to resolve it. | 155 | /// Returns the fully resolved path if we were able to resolve it. |
156 | /// otherwise returns `PerNs::none` | 156 | /// otherwise returns `PerNs::none` |
157 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> { | 157 | pub(crate) fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> { |
158 | // into_fully_resolved() returns the fully resolved path or PerNs::none() otherwise | 158 | // into_fully_resolved() returns the fully resolved path or PerNs::none() otherwise |
159 | self.resolve_path_segments(db, path).into_fully_resolved() | 159 | self.resolve_path_segments(db, path).into_fully_resolved() |
160 | } | 160 | } |
161 | 161 | ||
162 | pub fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<Resolution>> { | 162 | pub(crate) fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<Resolution>> { |
163 | let mut names = FxHashMap::default(); | 163 | let mut names = FxHashMap::default(); |
164 | for scope in self.scopes.iter().rev() { | 164 | for scope in self.scopes.iter().rev() { |
165 | scope.collect_names(db, &mut |name, res| { | 165 | scope.collect_names(db, &mut |name, res| { |
@@ -197,14 +197,6 @@ impl Resolver { | |||
197 | _ => None, | 197 | _ => None, |
198 | }) | 198 | }) |
199 | } | 199 | } |
200 | |||
201 | /// The body from which any `LocalBinding` resolutions in this resolver come. | ||
202 | pub fn body(&self) -> Option<Arc<Body>> { | ||
203 | self.scopes.iter().rev().find_map(|scope| match scope { | ||
204 | Scope::ExprScope(expr_scope) => Some(expr_scope.expr_scopes.body()), | ||
205 | _ => None, | ||
206 | }) | ||
207 | } | ||
208 | } | 200 | } |
209 | 201 | ||
210 | impl Resolver { | 202 | impl Resolver { |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 182ed4c91..bd035ced9 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -5,16 +5,21 @@ | |||
5 | /// | 5 | /// |
6 | /// So, this modules should not be used during hir construction, it exists | 6 | /// So, this modules should not be used during hir construction, it exists |
7 | /// purely for "IDE needs". | 7 | /// purely for "IDE needs". |
8 | use std::sync::Arc; | ||
9 | |||
10 | use rustc_hash::{FxHashSet, FxHashMap}; | ||
8 | use ra_db::{FileId, FilePosition}; | 11 | use ra_db::{FileId, FilePosition}; |
9 | use ra_syntax::{ | 12 | use ra_syntax::{ |
10 | SyntaxNode, | 13 | SyntaxNode, AstPtr, TextUnit, SyntaxNodePtr, TextRange, |
11 | ast::{self, AstNode, NameOwner}, | 14 | ast::{self, AstNode, NameOwner}, |
12 | algo::{find_node_at_offset, find_token_at_offset}, | 15 | algo::find_node_at_offset, |
16 | SyntaxKind::*, | ||
13 | }; | 17 | }; |
14 | 18 | ||
15 | use crate::{ | 19 | use crate::{ |
16 | HirDatabase, Function, Struct, Enum,Const,Static, | 20 | HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody, PerNs, Name, |
17 | AsName, Module, HirFileId, Crate, Trait, Resolver, | 21 | AsName, Module, HirFileId, Crate, Trait, Resolver, |
22 | expr::{BodySourceMap, scope::{ScopeId, ExprScopes}}, | ||
18 | ids::LocationCtx, | 23 | ids::LocationCtx, |
19 | expr, AstId | 24 | expr, AstId |
20 | }; | 25 | }; |
@@ -87,63 +92,6 @@ fn module_from_source( | |||
87 | ) | 92 | ) |
88 | } | 93 | } |
89 | 94 | ||
90 | pub fn const_from_source( | ||
91 | db: &impl HirDatabase, | ||
92 | file_id: FileId, | ||
93 | const_def: &ast::ConstDef, | ||
94 | ) -> Option<Const> { | ||
95 | let module = module_from_child_node(db, file_id, const_def.syntax())?; | ||
96 | let res = const_from_module(db, module, const_def); | ||
97 | Some(res) | ||
98 | } | ||
99 | |||
100 | pub fn const_from_module( | ||
101 | db: &impl HirDatabase, | ||
102 | module: Module, | ||
103 | const_def: &ast::ConstDef, | ||
104 | ) -> Const { | ||
105 | let (file_id, _) = module.definition_source(db); | ||
106 | let file_id = file_id.into(); | ||
107 | let ctx = LocationCtx::new(db, module, file_id); | ||
108 | Const { id: ctx.to_def(const_def) } | ||
109 | } | ||
110 | |||
111 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { | ||
112 | let file = db.parse(position.file_id); | ||
113 | let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), position.offset)?; | ||
114 | function_from_source(db, position.file_id, fn_def) | ||
115 | } | ||
116 | |||
117 | pub fn function_from_source( | ||
118 | db: &impl HirDatabase, | ||
119 | file_id: FileId, | ||
120 | fn_def: &ast::FnDef, | ||
121 | ) -> Option<Function> { | ||
122 | let module = module_from_child_node(db, file_id, fn_def.syntax())?; | ||
123 | let res = function_from_module(db, module, fn_def); | ||
124 | Some(res) | ||
125 | } | ||
126 | |||
127 | pub fn function_from_module( | ||
128 | db: &impl HirDatabase, | ||
129 | module: Module, | ||
130 | fn_def: &ast::FnDef, | ||
131 | ) -> Function { | ||
132 | let (file_id, _) = module.definition_source(db); | ||
133 | let file_id = file_id.into(); | ||
134 | let ctx = LocationCtx::new(db, module, file_id); | ||
135 | Function { id: ctx.to_def(fn_def) } | ||
136 | } | ||
137 | |||
138 | pub fn function_from_child_node( | ||
139 | db: &impl HirDatabase, | ||
140 | file_id: FileId, | ||
141 | node: &SyntaxNode, | ||
142 | ) -> Option<Function> { | ||
143 | let fn_def = node.ancestors().find_map(ast::FnDef::cast)?; | ||
144 | function_from_source(db, file_id, fn_def) | ||
145 | } | ||
146 | |||
147 | pub fn struct_from_module( | 95 | pub fn struct_from_module( |
148 | db: &impl HirDatabase, | 96 | db: &impl HirDatabase, |
149 | module: Module, | 97 | module: Module, |
@@ -155,27 +103,6 @@ pub fn struct_from_module( | |||
155 | Struct { id: ctx.to_def(struct_def) } | 103 | Struct { id: ctx.to_def(struct_def) } |
156 | } | 104 | } |
157 | 105 | ||
158 | pub fn static_from_source( | ||
159 | db: &impl HirDatabase, | ||
160 | file_id: FileId, | ||
161 | static_def: &ast::StaticDef, | ||
162 | ) -> Option<Static> { | ||
163 | let module = module_from_child_node(db, file_id, static_def.syntax())?; | ||
164 | let res = static_from_module(db, module, static_def); | ||
165 | Some(res) | ||
166 | } | ||
167 | |||
168 | pub fn static_from_module( | ||
169 | db: &impl HirDatabase, | ||
170 | module: Module, | ||
171 | static_def: &ast::StaticDef, | ||
172 | ) -> Static { | ||
173 | let (file_id, _) = module.definition_source(db); | ||
174 | let file_id = file_id.into(); | ||
175 | let ctx = LocationCtx::new(db, module, file_id); | ||
176 | Static { id: ctx.to_def(static_def) } | ||
177 | } | ||
178 | |||
179 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { | 106 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { |
180 | let (file_id, _) = module.definition_source(db); | 107 | let (file_id, _) = module.definition_source(db); |
181 | let file_id = file_id.into(); | 108 | let file_id = file_id.into(); |
@@ -194,48 +121,6 @@ pub fn trait_from_module( | |||
194 | Trait { id: ctx.to_def(trait_def) } | 121 | Trait { id: ctx.to_def(trait_def) } |
195 | } | 122 | } |
196 | 123 | ||
197 | pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver { | ||
198 | let file_id = position.file_id; | ||
199 | let file = db.parse(file_id); | ||
200 | find_token_at_offset(file.syntax(), position.offset) | ||
201 | .find_map(|token| { | ||
202 | token.parent().ancestors().find_map(|node| { | ||
203 | if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() { | ||
204 | if let Some(func) = function_from_child_node(db, file_id, node) { | ||
205 | let scopes = func.scopes(db); | ||
206 | let scope = scopes.scope_for_offset(position.offset); | ||
207 | Some(expr::resolver_for_scope(func.body(db), db, scope)) | ||
208 | } else { | ||
209 | // FIXME const/static/array length | ||
210 | None | ||
211 | } | ||
212 | } else { | ||
213 | try_get_resolver_for_node(db, file_id, node) | ||
214 | } | ||
215 | }) | ||
216 | }) | ||
217 | .unwrap_or_default() | ||
218 | } | ||
219 | |||
220 | pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> Resolver { | ||
221 | node.ancestors() | ||
222 | .find_map(|node| { | ||
223 | if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() { | ||
224 | if let Some(func) = function_from_child_node(db, file_id, node) { | ||
225 | let scopes = func.scopes(db); | ||
226 | let scope = scopes.scope_for(&node); | ||
227 | Some(expr::resolver_for_scope(func.body(db), db, scope)) | ||
228 | } else { | ||
229 | // FIXME const/static/array length | ||
230 | None | ||
231 | } | ||
232 | } else { | ||
233 | try_get_resolver_for_node(db, file_id, node) | ||
234 | } | ||
235 | }) | ||
236 | .unwrap_or_default() | ||
237 | } | ||
238 | |||
239 | fn try_get_resolver_for_node( | 124 | fn try_get_resolver_for_node( |
240 | db: &impl HirDatabase, | 125 | db: &impl HirDatabase, |
241 | file_id: FileId, | 126 | file_id: FileId, |
@@ -251,10 +136,281 @@ fn try_get_resolver_for_node( | |||
251 | } else if let Some(e) = ast::EnumDef::cast(node) { | 136 | } else if let Some(e) = ast::EnumDef::cast(node) { |
252 | let module = module_from_child_node(db, file_id, e.syntax())?; | 137 | let module = module_from_child_node(db, file_id, e.syntax())?; |
253 | Some(enum_from_module(db, module, e).resolver(db)) | 138 | Some(enum_from_module(db, module, e).resolver(db)) |
254 | } else if let Some(f) = ast::FnDef::cast(node) { | 139 | } else if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { |
255 | function_from_source(db, file_id, f).map(|f| f.resolver(db)) | 140 | Some(def_with_body_from_child_node(db, file_id, node)?.resolver(db)) |
256 | } else { | 141 | } else { |
257 | // FIXME add missing cases | 142 | // FIXME add missing cases |
258 | None | 143 | None |
259 | } | 144 | } |
260 | } | 145 | } |
146 | |||
147 | fn def_with_body_from_child_node( | ||
148 | db: &impl HirDatabase, | ||
149 | file_id: FileId, | ||
150 | node: &SyntaxNode, | ||
151 | ) -> Option<DefWithBody> { | ||
152 | let module = module_from_child_node(db, file_id, node)?; | ||
153 | let ctx = LocationCtx::new(db, module, file_id.into()); | ||
154 | node.ancestors().find_map(|node| { | ||
155 | if let Some(def) = ast::FnDef::cast(node) { | ||
156 | return Some(Function { id: ctx.to_def(def) }.into()); | ||
157 | } | ||
158 | if let Some(def) = ast::ConstDef::cast(node) { | ||
159 | return Some(Const { id: ctx.to_def(def) }.into()); | ||
160 | } | ||
161 | if let Some(def) = ast::StaticDef::cast(node) { | ||
162 | return Some(Static { id: ctx.to_def(def) }.into()); | ||
163 | } | ||
164 | None | ||
165 | }) | ||
166 | } | ||
167 | |||
168 | /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of | ||
169 | /// original source files. It should not be used inside the HIR itself. | ||
170 | #[derive(Debug)] | ||
171 | pub struct SourceAnalyzer { | ||
172 | resolver: Resolver, | ||
173 | body_source_map: Option<Arc<BodySourceMap>>, | ||
174 | infer: Option<Arc<crate::ty::InferenceResult>>, | ||
175 | scopes: Option<Arc<crate::expr::ExprScopes>>, | ||
176 | } | ||
177 | |||
178 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
179 | pub enum PathResolution { | ||
180 | /// An item | ||
181 | Def(crate::ModuleDef), | ||
182 | /// A local binding (only value namespace) | ||
183 | LocalBinding(Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>), | ||
184 | /// A generic parameter | ||
185 | GenericParam(u32), | ||
186 | SelfType(crate::ImplBlock), | ||
187 | AssocItem(crate::ImplItem), | ||
188 | } | ||
189 | |||
190 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
191 | pub struct ScopeEntryWithSyntax { | ||
192 | pub(crate) name: Name, | ||
193 | pub(crate) ptr: Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>, | ||
194 | } | ||
195 | |||
196 | impl ScopeEntryWithSyntax { | ||
197 | pub fn name(&self) -> &Name { | ||
198 | &self.name | ||
199 | } | ||
200 | |||
201 | pub fn ptr(&self) -> Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>> { | ||
202 | self.ptr | ||
203 | } | ||
204 | } | ||
205 | |||
206 | #[derive(Debug)] | ||
207 | pub struct ReferenceDescriptor { | ||
208 | pub range: TextRange, | ||
209 | pub name: String, | ||
210 | } | ||
211 | |||
212 | impl SourceAnalyzer { | ||
213 | pub fn new( | ||
214 | db: &impl HirDatabase, | ||
215 | file_id: FileId, | ||
216 | node: &SyntaxNode, | ||
217 | offset: Option<TextUnit>, | ||
218 | ) -> SourceAnalyzer { | ||
219 | let def_with_body = def_with_body_from_child_node(db, file_id, node); | ||
220 | if let Some(def) = def_with_body { | ||
221 | let source_map = def.body_source_map(db); | ||
222 | let scopes = db.expr_scopes(def); | ||
223 | let scope = match offset { | ||
224 | None => scope_for(&scopes, &source_map, &node), | ||
225 | Some(offset) => scope_for_offset(&scopes, &source_map, offset), | ||
226 | }; | ||
227 | let resolver = expr::resolver_for_scope(def.body(db), db, scope); | ||
228 | SourceAnalyzer { | ||
229 | resolver, | ||
230 | body_source_map: Some(source_map), | ||
231 | infer: Some(def.infer(db)), | ||
232 | scopes: Some(scopes), | ||
233 | } | ||
234 | } else { | ||
235 | SourceAnalyzer { | ||
236 | resolver: node | ||
237 | .ancestors() | ||
238 | .find_map(|node| try_get_resolver_for_node(db, file_id, node)) | ||
239 | .unwrap_or_default(), | ||
240 | body_source_map: None, | ||
241 | infer: None, | ||
242 | scopes: None, | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | pub fn type_of(&self, _db: &impl HirDatabase, expr: &ast::Expr) -> Option<crate::Ty> { | ||
248 | let expr_id = self.body_source_map.as_ref()?.node_expr(expr)?; | ||
249 | Some(self.infer.as_ref()?[expr_id].clone()) | ||
250 | } | ||
251 | |||
252 | pub fn type_of_pat(&self, _db: &impl HirDatabase, pat: &ast::Pat) -> Option<crate::Ty> { | ||
253 | let pat_id = self.body_source_map.as_ref()?.node_pat(pat)?; | ||
254 | Some(self.infer.as_ref()?[pat_id].clone()) | ||
255 | } | ||
256 | |||
257 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | ||
258 | let expr_id = self.body_source_map.as_ref()?.node_expr(call.into())?; | ||
259 | self.infer.as_ref()?.method_resolution(expr_id) | ||
260 | } | ||
261 | |||
262 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> { | ||
263 | let expr_id = self.body_source_map.as_ref()?.node_expr(field.into())?; | ||
264 | self.infer.as_ref()?.field_resolution(expr_id) | ||
265 | } | ||
266 | |||
267 | pub fn resolve_hir_path( | ||
268 | &self, | ||
269 | db: &impl HirDatabase, | ||
270 | path: &crate::Path, | ||
271 | ) -> PerNs<crate::Resolution> { | ||
272 | self.resolver.resolve_path(db, path) | ||
273 | } | ||
274 | |||
275 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { | ||
276 | if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { | ||
277 | let expr_id = self.body_source_map.as_ref()?.node_expr(path_expr.into())?; | ||
278 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { | ||
279 | return Some(PathResolution::AssocItem(assoc)); | ||
280 | } | ||
281 | } | ||
282 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { | ||
283 | let pat_id = self.body_source_map.as_ref()?.node_pat(path_pat.into())?; | ||
284 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { | ||
285 | return Some(PathResolution::AssocItem(assoc)); | ||
286 | } | ||
287 | } | ||
288 | let hir_path = crate::Path::from_ast(path)?; | ||
289 | let res = self.resolver.resolve_path(db, &hir_path); | ||
290 | let res = res.clone().take_types().or_else(|| res.take_values())?; | ||
291 | let res = match res { | ||
292 | crate::Resolution::Def(it) => PathResolution::Def(it), | ||
293 | crate::Resolution::LocalBinding(it) => { | ||
294 | PathResolution::LocalBinding(self.body_source_map.as_ref()?.pat_syntax(it)?) | ||
295 | } | ||
296 | crate::Resolution::GenericParam(it) => PathResolution::GenericParam(it), | ||
297 | crate::Resolution::SelfType(it) => PathResolution::SelfType(it), | ||
298 | }; | ||
299 | Some(res) | ||
300 | } | ||
301 | |||
302 | pub fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> { | ||
303 | let mut shadowed = FxHashSet::default(); | ||
304 | let name = name_ref.as_name(); | ||
305 | let source_map = self.body_source_map.as_ref()?; | ||
306 | let scopes = self.scopes.as_ref()?; | ||
307 | let scope = scope_for(scopes, source_map, name_ref.syntax()); | ||
308 | let ret = scopes | ||
309 | .scope_chain(scope) | ||
310 | .flat_map(|scope| scopes.entries(scope).iter()) | ||
311 | .filter(|entry| shadowed.insert(entry.name())) | ||
312 | .filter(|entry| entry.name() == &name) | ||
313 | .nth(0); | ||
314 | ret.and_then(|entry| { | ||
315 | Some(ScopeEntryWithSyntax { | ||
316 | name: entry.name().clone(), | ||
317 | ptr: source_map.pat_syntax(entry.pat())?, | ||
318 | }) | ||
319 | }) | ||
320 | } | ||
321 | |||
322 | pub fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<crate::Resolution>> { | ||
323 | self.resolver.all_names(db) | ||
324 | } | ||
325 | |||
326 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | ||
327 | // FIXME: at least, this should work with any DefWithBody, but ideally | ||
328 | // this should be hir-based altogether | ||
329 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | ||
330 | let ptr = Either::A(AstPtr::new(pat.into())); | ||
331 | fn_def | ||
332 | .syntax() | ||
333 | .descendants() | ||
334 | .filter_map(ast::NameRef::cast) | ||
335 | .filter(|name_ref| match self.resolve_local_name(*name_ref) { | ||
336 | None => false, | ||
337 | Some(entry) => entry.ptr() == ptr, | ||
338 | }) | ||
339 | .map(|name_ref| ReferenceDescriptor { | ||
340 | name: name_ref.text().to_string(), | ||
341 | range: name_ref.syntax().range(), | ||
342 | }) | ||
343 | .collect() | ||
344 | } | ||
345 | |||
346 | #[cfg(test)] | ||
347 | pub(crate) fn body_source_map(&self) -> Arc<BodySourceMap> { | ||
348 | self.body_source_map.clone().unwrap() | ||
349 | } | ||
350 | |||
351 | #[cfg(test)] | ||
352 | pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { | ||
353 | self.infer.clone().unwrap() | ||
354 | } | ||
355 | |||
356 | #[cfg(test)] | ||
357 | pub(crate) fn scopes(&self) -> Arc<ExprScopes> { | ||
358 | self.scopes.clone().unwrap() | ||
359 | } | ||
360 | } | ||
361 | |||
362 | fn scope_for( | ||
363 | scopes: &ExprScopes, | ||
364 | source_map: &BodySourceMap, | ||
365 | node: &SyntaxNode, | ||
366 | ) -> Option<ScopeId> { | ||
367 | node.ancestors() | ||
368 | .map(SyntaxNodePtr::new) | ||
369 | .filter_map(|ptr| source_map.syntax_expr(ptr)) | ||
370 | .find_map(|it| scopes.scope_for(it)) | ||
371 | } | ||
372 | |||
373 | fn scope_for_offset( | ||
374 | scopes: &ExprScopes, | ||
375 | source_map: &BodySourceMap, | ||
376 | offset: TextUnit, | ||
377 | ) -> Option<ScopeId> { | ||
378 | scopes | ||
379 | .scope_by_expr() | ||
380 | .iter() | ||
381 | .filter_map(|(id, scope)| Some((source_map.expr_syntax(*id)?, scope))) | ||
382 | // find containing scope | ||
383 | .min_by_key(|(ptr, _scope)| { | ||
384 | (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len()) | ||
385 | }) | ||
386 | .map(|(ptr, scope)| adjust(scopes, source_map, ptr, offset).unwrap_or(*scope)) | ||
387 | } | ||
388 | |||
389 | // XXX: during completion, cursor might be outside of any particular | ||
390 | // expression. Try to figure out the correct scope... | ||
391 | fn adjust( | ||
392 | scopes: &ExprScopes, | ||
393 | source_map: &BodySourceMap, | ||
394 | ptr: SyntaxNodePtr, | ||
395 | offset: TextUnit, | ||
396 | ) -> Option<ScopeId> { | ||
397 | let r = ptr.range(); | ||
398 | let child_scopes = scopes | ||
399 | .scope_by_expr() | ||
400 | .iter() | ||
401 | .filter_map(|(id, scope)| Some((source_map.expr_syntax(*id)?, scope))) | ||
402 | .map(|(ptr, scope)| (ptr.range(), scope)) | ||
403 | .filter(|(range, _)| range.start() <= offset && range.is_subrange(&r) && *range != r); | ||
404 | |||
405 | child_scopes | ||
406 | .max_by(|(r1, _), (r2, _)| { | ||
407 | if r2.is_subrange(&r1) { | ||
408 | std::cmp::Ordering::Greater | ||
409 | } else if r1.is_subrange(&r2) { | ||
410 | std::cmp::Ordering::Less | ||
411 | } else { | ||
412 | r1.start().cmp(&r2.start()) | ||
413 | } | ||
414 | }) | ||
415 | .map(|(_ptr, scope)| *scope) | ||
416 | } | ||
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs index 725bdd5cb..15f0977b7 100644 --- a/crates/ra_hir/src/traits.rs +++ b/crates/ra_hir/src/traits.rs | |||
@@ -1,10 +1,11 @@ | |||
1 | //! HIR for trait definitions. | 1 | //! HIR for trait definitions. |
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | use rustc_hash::FxHashMap; | ||
4 | 5 | ||
5 | use ra_syntax::ast::{self, NameOwner}; | 6 | use ra_syntax::ast::{self, NameOwner}; |
6 | 7 | ||
7 | use crate::{Function, Const, TypeAlias, Name, DefDatabase, Trait, ids::LocationCtx, name::AsName}; | 8 | use crate::{Function, Const, TypeAlias, Name, DefDatabase, Trait, ids::LocationCtx, name::AsName, Module}; |
8 | 9 | ||
9 | #[derive(Debug, Clone, PartialEq, Eq)] | 10 | #[derive(Debug, Clone, PartialEq, Eq)] |
10 | pub struct TraitData { | 11 | pub struct TraitData { |
@@ -49,4 +50,34 @@ pub enum TraitItem { | |||
49 | TypeAlias(TypeAlias), | 50 | TypeAlias(TypeAlias), |
50 | // Existential | 51 | // Existential |
51 | } | 52 | } |
53 | // FIXME: not every function, ... is actually a trait item. maybe we should make | ||
54 | // sure that you can only turn actual trait items into TraitItems. This would | ||
55 | // require not implementing From, and instead having some checked way of | ||
56 | // casting them. | ||
52 | impl_froms!(TraitItem: Function, Const, TypeAlias); | 57 | impl_froms!(TraitItem: Function, Const, TypeAlias); |
58 | |||
59 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
60 | pub struct TraitItemsIndex { | ||
61 | traits_by_def: FxHashMap<TraitItem, Trait>, | ||
62 | } | ||
63 | |||
64 | impl TraitItemsIndex { | ||
65 | pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { | ||
66 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; | ||
67 | for decl in module.declarations(db) { | ||
68 | match decl { | ||
69 | crate::ModuleDef::Trait(tr) => { | ||
70 | for item in tr.trait_data(db).items() { | ||
71 | index.traits_by_def.insert(*item, tr); | ||
72 |