aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock158
-rw-r--r--crates/ra_cli/Cargo.toml5
-rw-r--r--crates/ra_hir/src/db.rs80
-rw-r--r--crates/ra_hir/src/ids.rs18
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/mock.rs1
-rw-r--r--crates/ra_hir/src/nameres.rs4
-rw-r--r--crates/ra_hir/src/nameres/collector.rs17
-rw-r--r--crates/ra_hir/src/ty/traits.rs2
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs412
-rw-r--r--crates/ra_ide_api/src/db.rs1
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs35
-rw-r--r--crates/ra_prof/Cargo.toml1
-rw-r--r--crates/ra_prof/src/lib.rs33
-rw-r--r--docs/dev/README.md19
-rw-r--r--editors/code/.vscode/launch.json1
-rw-r--r--editors/code/package.json1
-rw-r--r--editors/code/src/commands/cargo_watch.ts66
-rw-r--r--editors/code/src/test/fixtures/rust-diagnostics/clippy/trivially_copy_pass_by_ref.json110
-rw-r--r--editors/code/src/test/fixtures/rust-diagnostics/error/E0053.json42
-rw-r--r--editors/code/src/test/fixtures/rust-diagnostics/error/E0061.json114
-rw-r--r--editors/code/src/test/fixtures/rust-diagnostics/warning/unused_variables.json72
-rw-r--r--editors/code/src/test/index.ts22
-rw-r--r--editors/code/src/test/rust_diagnostics.test.ts162
-rw-r--r--editors/code/src/test/vscode_diagnostics.test.ts182
-rw-r--r--editors/code/src/utils/rust_diagnostics.ts14
-rw-r--r--editors/code/src/utils/vscode_diagnostics.ts73
27 files changed, 1278 insertions, 369 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1465268b2..4f691f39e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -41,11 +41,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
41 41
42[[package]] 42[[package]]
43name = "backtrace" 43name = "backtrace"
44version = "0.3.30" 44version = "0.2.3"
45source = "registry+https://github.com/rust-lang/crates.io-index" 45source = "registry+https://github.com/rust-lang/crates.io-index"
46dependencies = [ 46dependencies = [
47 "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 47 "backtrace-sys 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
48 "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", 48 "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
49 "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
50 "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
51 "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
52 "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
53 "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
54]
55
56[[package]]
57name = "backtrace"
58version = "0.3.32"
59source = "registry+https://github.com/rust-lang/crates.io-index"
60dependencies = [
61 "backtrace-sys 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
49 "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 62 "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
50 "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 63 "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
51 "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 64 "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -53,7 +66,7 @@ dependencies = [
53 66
54[[package]] 67[[package]]
55name = "backtrace-sys" 68name = "backtrace-sys"
56version = "0.1.28" 69version = "0.1.29"
57source = "registry+https://github.com/rust-lang/crates.io-index" 70source = "registry+https://github.com/rust-lang/crates.io-index"
58dependencies = [ 71dependencies = [
59 "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", 72 "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -94,7 +107,7 @@ dependencies = [
94 "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 107 "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
95 "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 108 "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
96 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 109 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
97 "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 110 "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
98] 111]
99 112
100[[package]] 113[[package]]
@@ -122,8 +135,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
122dependencies = [ 135dependencies = [
123 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 136 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
124 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 137 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
125 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 138 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
126 "serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 139 "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
127 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", 140 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
128] 141]
129 142
@@ -194,12 +207,13 @@ dependencies = [
194 207
195[[package]] 208[[package]]
196name = "chrono" 209name = "chrono"
197version = "0.4.6" 210version = "0.4.7"
198source = "registry+https://github.com/rust-lang/crates.io-index" 211source = "registry+https://github.com/rust-lang/crates.io-index"
199dependencies = [ 212dependencies = [
213 "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
200 "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", 214 "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
201 "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 215 "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
202 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 216 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
203 "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 217 "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
204] 218]
205 219
@@ -264,6 +278,15 @@ dependencies = [
264] 278]
265 279
266[[package]] 280[[package]]
281name = "cpuprofiler"
282version = "0.0.3"
283source = "registry+https://github.com/rust-lang/crates.io-index"
284dependencies = [
285 "error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
286 "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
287]
288
289[[package]]
267name = "crossbeam-channel" 290name = "crossbeam-channel"
268version = "0.3.8" 291version = "0.3.8"
269source = "registry+https://github.com/rust-lang/crates.io-index" 292source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -312,13 +335,22 @@ dependencies = [
312] 335]
313 336
314[[package]] 337[[package]]
338name = "dbghelp-sys"
339version = "0.2.0"
340source = "registry+https://github.com/rust-lang/crates.io-index"
341dependencies = [
342 "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
343 "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
344]
345
346[[package]]
315name = "derive-new" 347name = "derive-new"
316version = "0.5.6" 348version = "0.5.6"
317source = "registry+https://github.com/rust-lang/crates.io-index" 349source = "registry+https://github.com/rust-lang/crates.io-index"
318dependencies = [ 350dependencies = [
319 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 351 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
320 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 352 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
321 "syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)", 353 "syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
322] 354]
323 355
324[[package]] 356[[package]]
@@ -336,7 +368,7 @@ name = "digest"
336version = "0.8.0" 368version = "0.8.0"
337source = "registry+https://github.com/rust-lang/crates.io-index" 369source = "registry+https://github.com/rust-lang/crates.io-index"
338dependencies = [ 370dependencies = [
339 "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 371 "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
340] 372]
341 373
342[[package]] 374[[package]]
@@ -377,10 +409,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
377 409
378[[package]] 410[[package]]
379name = "error-chain" 411name = "error-chain"
412version = "0.5.0"
413source = "registry+https://github.com/rust-lang/crates.io-index"
414dependencies = [
415 "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
416]
417
418[[package]]
419name = "error-chain"
380version = "0.12.1" 420version = "0.12.1"
381source = "registry+https://github.com/rust-lang/crates.io-index" 421source = "registry+https://github.com/rust-lang/crates.io-index"
382dependencies = [ 422dependencies = [
383 "backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)", 423 "backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
384 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 424 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
385] 425]
386 426
@@ -389,7 +429,7 @@ name = "failure"
389version = "0.1.5" 429version = "0.1.5"
390source = "registry+https://github.com/rust-lang/crates.io-index" 430source = "registry+https://github.com/rust-lang/crates.io-index"
391dependencies = [ 431dependencies = [
392 "backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)", 432 "backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
393 "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 433 "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
394] 434]
395 435
@@ -400,7 +440,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
400dependencies = [ 440dependencies = [
401 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 441 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
402 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 442 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
403 "syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)", 443 "syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
404 "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", 444 "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
405] 445]
406 446
@@ -429,7 +469,7 @@ name = "flexi_logger"
429version = "0.13.2" 469version = "0.13.2"
430source = "registry+https://github.com/rust-lang/crates.io-index" 470source = "registry+https://github.com/rust-lang/crates.io-index"
431dependencies = [ 471dependencies = [
432 "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 472 "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
433 "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 473 "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
434 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 474 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
435 "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 475 "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -493,13 +533,13 @@ dependencies = [
493 "flexi_logger 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", 533 "flexi_logger 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
494 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 534 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
495 "lsp-types 0.57.2 (registry+https://github.com/rust-lang/crates.io-index)", 535 "lsp-types 0.57.2 (registry+https://github.com/rust-lang/crates.io-index)",
496 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 536 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
497 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", 537 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
498] 538]
499 539
500[[package]] 540[[package]]
501name = "generic-array" 541name = "generic-array"
502version = "0.12.0" 542version = "0.12.3"
503source = "registry+https://github.com/rust-lang/crates.io-index" 543source = "registry+https://github.com/rust-lang/crates.io-index"
504dependencies = [ 544dependencies = [
505 "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 545 "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -578,7 +618,7 @@ name = "insta"
578version = "0.8.1" 618version = "0.8.1"
579source = "registry+https://github.com/rust-lang/crates.io-index" 619source = "registry+https://github.com/rust-lang/crates.io-index"
580dependencies = [ 620dependencies = [
581 "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 621 "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
582 "ci_info 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 622 "ci_info 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
583 "console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", 623 "console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
584 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 624 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -587,7 +627,7 @@ dependencies = [
587 "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 627 "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
588 "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 628 "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
589 "ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 629 "ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
590 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 630 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
591 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", 631 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
592 "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", 632 "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
593 "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", 633 "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -672,6 +712,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
672 712
673[[package]] 713[[package]]
674name = "lazy_static" 714name = "lazy_static"
715version = "0.2.11"
716source = "registry+https://github.com/rust-lang/crates.io-index"
717
718[[package]]
719name = "lazy_static"
675version = "1.3.0" 720version = "1.3.0"
676source = "registry+https://github.com/rust-lang/crates.io-index" 721source = "registry+https://github.com/rust-lang/crates.io-index"
677 722
@@ -714,8 +759,8 @@ dependencies = [
714 "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 759 "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
715 "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 760 "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
716 "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 761 "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
717 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 762 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
718 "serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 763 "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
719 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", 764 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
720 "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 765 "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
721 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 766 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -820,7 +865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
820dependencies = [ 865dependencies = [
821 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 866 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
822 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 867 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
823 "syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)", 868 "syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
824] 869]
825 870
826[[package]] 871[[package]]
@@ -936,7 +981,7 @@ dependencies = [
936 "pest_meta 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 981 "pest_meta 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
937 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 982 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
938 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 983 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
939 "syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)", 984 "syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
940] 985]
941 986
942[[package]] 987[[package]]
@@ -1142,7 +1187,7 @@ dependencies = [
1142 "ra_vfs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 1187 "ra_vfs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
1143 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1188 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1144 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1189 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1145 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1190 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1146 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", 1191 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
1147 "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)", 1192 "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
1148 "test_utils 0.1.0", 1193 "test_utils 0.1.0",
@@ -1175,7 +1220,8 @@ dependencies = [
1175name = "ra_prof" 1220name = "ra_prof"
1176version = "0.1.0" 1221version = "0.1.0"
1177dependencies = [ 1222dependencies = [
1178 "backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)", 1223 "backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
1224 "cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
1179 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1225 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1180 "once_cell 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1226 "once_cell 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1181] 1227]
@@ -1190,7 +1236,7 @@ dependencies = [
1190 "ra_db 0.1.0", 1236 "ra_db 0.1.0",
1191 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1237 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1192 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1238 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1193 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1239 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1194 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", 1240 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
1195 "test_utils 0.1.0", 1241 "test_utils 0.1.0",
1196 "walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1242 "walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1205,7 +1251,7 @@ dependencies = [
1205 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1251 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1206 "ra_parser 0.1.0", 1252 "ra_parser 0.1.0",
1207 "ra_text_edit 0.1.0", 1253 "ra_text_edit 0.1.0",
1208 "rowan 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 1254 "rowan 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
1209 "smol_str 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1255 "smol_str 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
1210 "test_utils 0.1.0", 1256 "test_utils 0.1.0",
1211 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1257 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1432,16 +1478,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1432dependencies = [ 1478dependencies = [
1433 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1479 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1434 "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1480 "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1435 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1481 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1436] 1482]
1437 1483
1438[[package]] 1484[[package]]
1439name = "rowan" 1485name = "rowan"
1440version = "0.5.4" 1486version = "0.5.5"
1441source = "registry+https://github.com/rust-lang/crates.io-index" 1487source = "registry+https://github.com/rust-lang/crates.io-index"
1442dependencies = [ 1488dependencies = [
1443 "colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1489 "colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
1444 "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1490 "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1491 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1445 "smol_str 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1492 "smol_str 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
1446 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1493 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
1447] 1494]
@@ -1496,7 +1543,7 @@ dependencies = [
1496 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1543 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
1497 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1544 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1498 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 1545 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1499 "syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)", 1546 "syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
1500] 1547]
1501 1548
1502[[package]] 1549[[package]]
@@ -1523,7 +1570,7 @@ version = "0.9.0"
1523source = "registry+https://github.com/rust-lang/crates.io-index" 1570source = "registry+https://github.com/rust-lang/crates.io-index"
1524dependencies = [ 1571dependencies = [
1525 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1572 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
1526 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1573 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1527] 1574]
1528 1575
1529[[package]] 1576[[package]]
@@ -1533,20 +1580,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1533 1580
1534[[package]] 1581[[package]]
1535name = "serde" 1582name = "serde"
1536version = "1.0.92" 1583version = "1.0.93"
1537source = "registry+https://github.com/rust-lang/crates.io-index" 1584source = "registry+https://github.com/rust-lang/crates.io-index"
1538dependencies = [ 1585dependencies = [
1539 "serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1586 "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1540] 1587]
1541 1588
1542[[package]] 1589[[package]]
1543name = "serde_derive" 1590name = "serde_derive"
1544version = "1.0.92" 1591version = "1.0.93"
1545source = "registry+https://github.com/rust-lang/crates.io-index" 1592source = "registry+https://github.com/rust-lang/crates.io-index"
1546dependencies = [ 1593dependencies = [
1547 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1594 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1548 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 1595 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1549 "syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)", 1596 "syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
1550] 1597]
1551 1598
1552[[package]] 1599[[package]]
@@ -1556,7 +1603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1556dependencies = [ 1603dependencies = [
1557 "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1604 "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1558 "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1605 "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
1559 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1606 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1560] 1607]
1561 1608
1562[[package]] 1609[[package]]
@@ -1566,7 +1613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1566dependencies = [ 1613dependencies = [
1567 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1614 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1568 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1615 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
1569 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1616 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1570 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1617 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
1571] 1618]
1572 1619
@@ -1604,7 +1651,7 @@ name = "smol_str"
1604version = "0.1.11" 1651version = "0.1.11"
1605source = "registry+https://github.com/rust-lang/crates.io-index" 1652source = "registry+https://github.com/rust-lang/crates.io-index"
1606dependencies = [ 1653dependencies = [
1607 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1654 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1608] 1655]
1609 1656
1610[[package]] 1657[[package]]
@@ -1630,7 +1677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1630 1677
1631[[package]] 1678[[package]]
1632name = "syn" 1679name = "syn"
1633version = "0.15.36" 1680version = "0.15.38"
1634source = "registry+https://github.com/rust-lang/crates.io-index" 1681source = "registry+https://github.com/rust-lang/crates.io-index"
1635dependencies = [ 1682dependencies = [
1636 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1683 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1645,7 +1692,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1645dependencies = [ 1692dependencies = [
1646 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1693 "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1647 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 1694 "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1648 "syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)", 1695 "syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
1649 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1696 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1650] 1697]
1651 1698
@@ -1667,7 +1714,7 @@ name = "tera"
1667version = "0.11.20" 1714version = "0.11.20"
1668source = "registry+https://github.com/rust-lang/crates.io-index" 1715source = "registry+https://github.com/rust-lang/crates.io-index"
1669dependencies = [ 1716dependencies = [
1670 "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1717 "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1671 "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 1718 "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
1672 "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1719 "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
1673 "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1720 "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1675,7 +1722,7 @@ dependencies = [
1675 "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1722 "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
1676 "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1723 "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1677 "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 1724 "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
1678 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1725 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1679 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", 1726 "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
1680 "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1727 "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
1681 "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1728 "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1726,7 +1773,7 @@ name = "text_unit"
1726version = "0.1.9" 1773version = "0.1.9"
1727source = "registry+https://github.com/rust-lang/crates.io-index" 1774source = "registry+https://github.com/rust-lang/crates.io-index"
1728dependencies = [ 1775dependencies = [
1729 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1776 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1730] 1777]
1731 1778
1732[[package]] 1779[[package]]
@@ -1884,7 +1931,7 @@ name = "url_serde"
1884version = "0.2.0" 1931version = "0.2.0"
1885source = "registry+https://github.com/rust-lang/crates.io-index" 1932source = "registry+https://github.com/rust-lang/crates.io-index"
1886dependencies = [ 1933dependencies = [
1887 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1934 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1888 "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1935 "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1889] 1936]
1890 1937
@@ -1899,7 +1946,7 @@ version = "0.7.4"
1899source = "registry+https://github.com/rust-lang/crates.io-index" 1946source = "registry+https://github.com/rust-lang/crates.io-index"
1900dependencies = [ 1947dependencies = [
1901 "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1948 "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1902 "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", 1949 "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
1903] 1950]
1904 1951
1905[[package]] 1952[[package]]
@@ -1987,8 +2034,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1987"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" 2034"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
1988"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" 2035"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
1989"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" 2036"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
1990"checksum backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)" = "ada4c783bb7e7443c14e0480f429ae2cc99da95065aeab7ee1b81ada0419404f" 2037"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f"
1991"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" 2038"checksum backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "18b50f5258d1a9ad8396d2d345827875de4261b158124d4c819d9b351454fae5"
2039"checksum backtrace-sys 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "12cb9f1eef1d1fc869ad5a26c9fa48516339a15e54a227a25460fc304815fdb3"
1992"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 2040"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
1993"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" 2041"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
1994"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" 2042"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
@@ -2005,18 +2053,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2005"checksum chalk-macros 0.1.1 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>" 2053"checksum chalk-macros 0.1.1 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>"
2006"checksum chalk-rust-ir 0.1.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>" 2054"checksum chalk-rust-ir 0.1.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>"
2007"checksum chalk-solve 0.1.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>" 2055"checksum chalk-solve 0.1.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>"
2008"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" 2056"checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe"
2009"checksum ci_info 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e5e881307a989a3a5e20d52a32cc05950e3c2178cccfcc9428271a6cde09f902" 2057"checksum ci_info 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e5e881307a989a3a5e20d52a32cc05950e3c2178cccfcc9428271a6cde09f902"
2010"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" 2058"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
2011"checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" 2059"checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9"
2012"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 2060"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
2013"checksum colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "370c83b49aedf022ee27942e8ae1d9de1cf40dc9653ee6550e4455d08f6406f9" 2061"checksum colosseum 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "370c83b49aedf022ee27942e8ae1d9de1cf40dc9653ee6550e4455d08f6406f9"
2014"checksum console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ca57c2c14b8a2bf3105bc9d15574aad80babf6a9c44b1058034cdf8bd169628" 2062"checksum console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ca57c2c14b8a2bf3105bc9d15574aad80babf6a9c44b1058034cdf8bd169628"
2063"checksum cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "33f07976bb6821459632d7a18d97ccca005cb5c552f251f822c7c1781c1d7035"
2015"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" 2064"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
2016"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" 2065"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
2017"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" 2066"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4"
2018"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" 2067"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
2019"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" 2068"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
2069"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
2020"checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c" 2070"checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c"
2021"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" 2071"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
2022"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" 2072"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
@@ -2028,6 +2078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2028"checksum ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc01d68e08ca384955a3aeba9217102ca1aa85b6e168639bf27739f1d749d87" 2078"checksum ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc01d68e08ca384955a3aeba9217102ca1aa85b6e168639bf27739f1d749d87"
2029"checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd" 2079"checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd"
2030"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" 2080"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
2081"checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143"
2031"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" 2082"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
2032"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" 2083"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
2033"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" 2084"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
@@ -2041,7 +2092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2041"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 2092"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
2042"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 2093"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
2043"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 2094"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
2044"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" 2095"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
2045"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 2096"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
2046"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" 2097"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
2047"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 2098"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
@@ -2062,6 +2113,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2062"checksum join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc7a5290e8c2606ce2be49f456d50f69173cb96d1541e4f66e34ac8b331a98f" 2113"checksum join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc7a5290e8c2606ce2be49f456d50f69173cb96d1541e4f66e34ac8b331a98f"
2063"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 2114"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
2064"checksum lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4fd87be4a815fd373e02773983940f0d75fb26fde8c098e9e45f7af03154c0" 2115"checksum lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4fd87be4a815fd373e02773983940f0d75fb26fde8c098e9e45f7af03154c0"
2116"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
2065"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" 2117"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
2066"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" 2118"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
2067"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319" 2119"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319"
@@ -2121,7 +2173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2121"checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c" 2173"checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c"
2122"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 2174"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
2123"checksum ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "17f52a24414403f81528b67488cf8edc4eda977d3af1646bb6b106a600ead78f" 2175"checksum ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "17f52a24414403f81528b67488cf8edc4eda977d3af1646bb6b106a600ead78f"
2124"checksum rowan 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "695dbacb8b8e077caf0cdeb65b0fe0c27bd99a9b7bf5f6467681c4c94cbe6133" 2176"checksum rowan 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "500ba7550373d42593a5228085bad391517378fa31ad2a84defe100dd8259fef"
2125"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" 2177"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
2126"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" 2178"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
2127"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 2179"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
@@ -2133,8 +2185,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2133"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 2185"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
2134"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 2186"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
2135"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 2187"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
2136"checksum serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be" 2188"checksum serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)" = "960e29cf7004b3b6e65fc5002981400eb3ccc017a08a2406940823e58e7179a9"
2137"checksum serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "46a3223d0c9ba936b61c0d2e3e559e3217dbfb8d65d06d26e8b3c25de38bae3e" 2189"checksum serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)" = "c4cce6663696bd38272e90bf34a0267e1226156c33f52d3f3915a2dd5d802085"
2138"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" 2190"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
2139"checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582" 2191"checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582"
2140"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" 2192"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
@@ -2145,7 +2197,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2145"checksum stacker 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb79482f57cf598af52094ec4cc3b3c42499d3ce5bd426f2ac41515b7e57404b" 2197"checksum stacker 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb79482f57cf598af52094ec4cc3b3c42499d3ce5bd426f2ac41515b7e57404b"
2146"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 2198"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
2147"checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" 2199"checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
2148"checksum syn 0.15.36 (registry+https://github.com/rust-lang/crates.io-index)" = "8b4f551a91e2e3848aeef8751d0d4eec9489b6474c720fd4c55958d8d31a430c" 2200"checksum syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)" = "37ea458a750f59ab679b47fef9b6722c586c5742f4cfe18a120bbc807e5e01fd"
2149"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" 2201"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
2150"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef" 2202"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef"
2151"checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3" 2203"checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3"
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml
index 301145b5d..b10873cd8 100644
--- a/crates/ra_cli/Cargo.toml
+++ b/crates/ra_cli/Cargo.toml
@@ -16,4 +16,7 @@ ra_ide_api = { path = "../ra_ide_api" }
16ra_batch = { path = "../ra_batch" } 16ra_batch = { path = "../ra_batch" }
17ra_hir = { path = "../ra_hir" } 17ra_hir = { path = "../ra_hir" }
18ra_db = { path = "../ra_db" } 18ra_db = { path = "../ra_db" }
19ra_prof = { path = "../ra_prof" } 19
20[dependencies.ra_prof]
21path = "../ra_prof"
22# features = [ "cpuprofiler" ]
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index d8832a9de..8f4de1c85 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -20,13 +20,41 @@ use crate::{
20 lang_item::{LangItems, LangItemTarget}, type_alias::TypeAliasData, 20 lang_item::{LangItems, LangItemTarget}, type_alias::TypeAliasData,
21}; 21};
22 22
23// This database has access to source code, so queries here are not really 23/// We store all interned things in the single QueryGroup.
24// incremental. 24///
25#[salsa::query_group(AstDatabaseStorage)] 25/// This is done mainly to allow both "volatile" `AstDatabase` and "stable"
26pub trait AstDatabase: SourceDatabase { 26/// `DefDatabase` to access macros, without adding hard dependencies between the
27/// two.
28#[salsa::query_group(InternDatabaseStorage)]
29pub trait InternDatabase: SourceDatabase {
27 #[salsa::interned] 30 #[salsa::interned]
28 fn intern_macro(&self, macro_call: MacroCallLoc) -> ids::MacroCallId; 31 fn intern_macro(&self, macro_call: MacroCallLoc) -> ids::MacroCallId;
32 #[salsa::interned]
33 fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId;
34 #[salsa::interned]
35 fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId;
36 #[salsa::interned]
37 fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId;
38 #[salsa::interned]
39 fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId;
40 #[salsa::interned]
41 fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId;
42 #[salsa::interned]
43 fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId;
44 #[salsa::interned]
45 fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId;
29 46
47 // Interned IDs for Chalk integration
48 #[salsa::interned]
49 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId;
50 #[salsa::interned]
51 fn intern_impl_block(&self, impl_block: ImplBlock) -> ids::GlobalImplId;
52}
53
54/// This database has access to source code, so queries here are not really
55/// incremental.
56#[salsa::query_group(AstDatabaseStorage)]
57pub trait AstDatabase: InternDatabase {
30 #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)] 58 #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)]
31 fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; 59 fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>;
32 #[salsa::transparent] 60 #[salsa::transparent]
@@ -40,7 +68,6 @@ pub trait AstDatabase: SourceDatabase {
40 68
41 #[salsa::invoke(crate::ids::macro_def_query)] 69 #[salsa::invoke(crate::ids::macro_def_query)]
42 fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; 70 fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>;
43
44 #[salsa::invoke(crate::ids::macro_arg_query)] 71 #[salsa::invoke(crate::ids::macro_arg_query)]
45 fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option<Arc<tt::Subtree>>; 72 fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option<Arc<tt::Subtree>>;
46 73
@@ -51,28 +78,7 @@ pub trait AstDatabase: SourceDatabase {
51// This database uses `AstDatabase` internally, 78// This database uses `AstDatabase` internally,
52#[salsa::query_group(DefDatabaseStorage)] 79#[salsa::query_group(DefDatabaseStorage)]
53#[salsa::requires(AstDatabase)] 80#[salsa::requires(AstDatabase)]
54pub trait DefDatabase: SourceDatabase { 81pub trait DefDatabase: InternDatabase {
55 #[salsa::interned]
56 fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId;
57 #[salsa::interned]
58 fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId;
59 #[salsa::interned]
60 fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId;
61 #[salsa::interned]
62 fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId;
63 #[salsa::interned]
64 fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId;
65 #[salsa::interned]
66 fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId;
67 #[salsa::interned]
68 fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId;
69
70 // Interned IDs for Chalk integration
71 #[salsa::interned]
72 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId;
73 #[salsa::interned]
74 fn intern_impl_block(&self, impl_block: ImplBlock) -> ids::GlobalImplId;
75
76 #[salsa::invoke(crate::adt::StructData::struct_data_query)] 82 #[salsa::invoke(crate::adt::StructData::struct_data_query)]
77 fn struct_data(&self, s: Struct) -> Arc<StructData>; 83 fn struct_data(&self, s: Struct) -> Arc<StructData>;
78 84
@@ -181,6 +187,26 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
181 #[salsa::volatile] 187 #[salsa::volatile]
182 fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>; 188 fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>;
183 189
190 #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)]
191 fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>;
192
193 #[salsa::invoke(crate::ty::traits::chalk::trait_datum_query)]
194 fn trait_datum(
195 &self,
196 krate: Crate,
197 trait_id: chalk_ir::TraitId,
198 ) -> Arc<chalk_rust_ir::TraitDatum>;
199
200 #[salsa::invoke(crate::ty::traits::chalk::struct_datum_query)]
201 fn struct_datum(
202 &self,
203 krate: Crate,
204 struct_id: chalk_ir::StructId,
205 ) -> Arc<chalk_rust_ir::StructDatum>;
206
207 #[salsa::invoke(crate::ty::traits::chalk::impl_datum_query)]
208 fn impl_datum(&self, krate: Crate, impl_id: chalk_ir::ImplId) -> Arc<chalk_rust_ir::ImplDatum>;
209
184 #[salsa::invoke(crate::ty::traits::implements_query)] 210 #[salsa::invoke(crate::ty::traits::implements_query)]
185 fn implements( 211 fn implements(
186 &self, 212 &self,
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 033af1632..b7215ac03 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -9,7 +9,7 @@ use ra_prof::profile;
9use mbe::MacroRules; 9use mbe::MacroRules;
10 10
11use crate::{ 11use crate::{
12 Module, DefDatabase, AstId, FileAstId, AstDatabase, Source, 12 Module, DefDatabase, AstId, FileAstId, AstDatabase, Source, InternDatabase,
13}; 13};
14 14
15/// hir makes heavy use of ids: integer (u32) handlers to various things. You 15/// hir makes heavy use of ids: integer (u32) handlers to various things. You
@@ -37,7 +37,7 @@ pub struct HirFileId(HirFileIdRepr);
37impl HirFileId { 37impl HirFileId {
38 /// For macro-expansion files, returns the file original source file the 38 /// For macro-expansion files, returns the file original source file the
39 /// expansion originated from. 39 /// expansion originated from.
40 pub fn original_file(self, db: &impl AstDatabase) -> FileId { 40 pub fn original_file(self, db: &impl InternDatabase) -> FileId {
41 match self.0 { 41 match self.0 {
42 HirFileIdRepr::File(file_id) => file_id, 42 HirFileIdRepr::File(file_id) => file_id,
43 HirFileIdRepr::Macro(macro_file) => { 43 HirFileIdRepr::Macro(macro_file) => {
@@ -187,7 +187,7 @@ pub struct MacroCallLoc {
187} 187}
188 188
189impl MacroCallId { 189impl MacroCallId {
190 pub(crate) fn loc(self, db: &impl AstDatabase) -> MacroCallLoc { 190 pub(crate) fn loc(self, db: &impl InternDatabase) -> MacroCallLoc {
191 db.lookup_intern_macro(self) 191 db.lookup_intern_macro(self)
192 } 192 }
193 193
@@ -198,7 +198,7 @@ impl MacroCallId {
198} 198}
199 199
200impl MacroCallLoc { 200impl MacroCallLoc {
201 pub(crate) fn id(self, db: &impl AstDatabase) -> MacroCallId { 201 pub(crate) fn id(self, db: &impl InternDatabase) -> MacroCallId {
202 db.intern_macro(self) 202 db.intern_macro(self)
203 } 203 }
204} 204}
@@ -235,10 +235,13 @@ pub(crate) struct LocationCtx<DB> {
235 file_id: HirFileId, 235 file_id: HirFileId,
236} 236}
237 237
238impl<'a, DB: DefDatabase + AstDatabase> LocationCtx<&'a DB> { 238impl<'a, DB: DefDatabase> LocationCtx<&'a DB> {
239 pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { 239 pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> {
240 LocationCtx { db, module, file_id } 240 LocationCtx { db, module, file_id }
241 } 241 }
242}
243
244impl<'a, DB: DefDatabase + AstDatabase> LocationCtx<&'a DB> {
242 pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF 245 pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF
243 where 246 where
244 N: AstNode, 247 N: AstNode,
@@ -257,10 +260,7 @@ pub(crate) trait AstItemDef<N: AstNode>: salsa::InternKey + Clone {
257 let item_id = items.ast_id(ast); 260 let item_id = items.ast_id(ast);
258 Self::from_ast_id(ctx, item_id) 261 Self::from_ast_id(ctx, item_id)
259 } 262 }
260 fn from_ast_id( 263 fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self {
261 ctx: LocationCtx<&(impl AstDatabase + DefDatabase)>,
262 ast_id: FileAstId<N>,
263 ) -> Self {
264 let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; 264 let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) };
265 Self::intern(ctx.db, loc) 265 Self::intern(ctx.db, loc)
266 } 266 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index f07a36926..5afd846f5 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -47,7 +47,7 @@ mod code_model;
47mod marks; 47mod marks;
48 48
49use crate::{ 49use crate::{
50 db::{AstDatabase, DefDatabase, HirDatabase}, 50 db::{InternDatabase, AstDatabase, DefDatabase, HirDatabase},
51 name::{AsName, KnownName}, 51 name::{AsName, KnownName},
52 source_id::{FileAstId, AstId}, 52 source_id::{FileAstId, AstId},
53 resolve::Resolver, 53 resolve::Resolver,
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 5d38ac76c..c57dfbf01 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -15,6 +15,7 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0);
15 15
16#[salsa::database( 16#[salsa::database(
17 ra_db::SourceDatabaseStorage, 17 ra_db::SourceDatabaseStorage,
18 db::InternDatabaseStorage,
18 db::AstDatabaseStorage, 19 db::AstDatabaseStorage,
19 db::DefDatabaseStorage, 20 db::DefDatabaseStorage,
20 db::HirDatabaseStorage 21 db::HirDatabaseStorage
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 3532faf01..f4ca454e4 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -231,7 +231,9 @@ fn or(left: ItemOrMacro, right: ItemOrMacro) -> ItemOrMacro {
231 231
232impl CrateDefMap { 232impl CrateDefMap {
233 pub(crate) fn crate_def_map_query( 233 pub(crate) fn crate_def_map_query(
234 db: &(impl DefDatabase + AstDatabase), 234 // Note that this doesn't have `+ AstDatabase`!
235 // This gurantess that `CrateDefMap` is stable across reparses.
236 db: &impl DefDatabase,
235 krate: Crate, 237 krate: Crate,
236 ) -> Arc<CrateDefMap> { 238 ) -> Arc<CrateDefMap> {
237 let _p = profile("crate_def_map_query"); 239 let _p = profile("crate_def_map_query");
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index b74dc33b1..ef4d1ed70 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -7,7 +7,7 @@ use ra_syntax::ast;
7 7
8use crate::{ 8use crate::{
9 Function, Module, Struct, Union, Enum, Const, Static, Trait, TypeAlias, MacroDef, 9 Function, Module, Struct, Union, Enum, Const, Static, Trait, TypeAlias, MacroDef,
10 DefDatabase, HirFileId, Name, Path, AstDatabase, 10 DefDatabase, HirFileId, Name, Path,
11 KnownName, AstId, 11 KnownName, AstId,
12 nameres::{ 12 nameres::{
13 Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, 13 Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode,
@@ -19,10 +19,7 @@ use crate::{
19 either::Either, 19 either::Either,
20}; 20};
21 21
22pub(super) fn collect_defs( 22pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
23 db: &(impl DefDatabase + AstDatabase),
24 mut def_map: CrateDefMap,
25) -> CrateDefMap {
26 // populate external prelude 23 // populate external prelude
27 for dep in def_map.krate.dependencies(db) { 24 for dep in def_map.krate.dependencies(db) {
28 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); 25 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate);
@@ -95,7 +92,7 @@ struct DefCollector<DB> {
95 92
96impl<'a, DB> DefCollector<&'a DB> 93impl<'a, DB> DefCollector<&'a DB>
97where 94where
98 DB: DefDatabase + AstDatabase, 95 DB: DefDatabase,
99{ 96{
100 fn collect(&mut self) { 97 fn collect(&mut self) {
101 let crate_graph = self.db.crate_graph(); 98 let crate_graph = self.db.crate_graph();
@@ -465,7 +462,7 @@ where
465 ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } 462 ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items }
466 .collect(raw_items.items()); 463 .collect(raw_items.items());
467 } else { 464 } else {
468 log::error!("Too deep macro expansion: {}", macro_call_id.debug_dump(self.db)); 465 log::error!("Too deep macro expansion: {:?}", macro_call_id);
469 self.def_map.poison_macros.insert(macro_def_id); 466 self.def_map.poison_macros.insert(macro_def_id);
470 } 467 }
471 468
@@ -487,7 +484,7 @@ struct ModCollector<'a, D> {
487 484
488impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> 485impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>>
489where 486where
490 DB: DefDatabase + AstDatabase, 487 DB: DefDatabase,
491{ 488{
492 fn collect(&mut self, items: &[raw::RawItem]) { 489 fn collect(&mut self, items: &[raw::RawItem]) {
493 for item in items { 490 for item in items {
@@ -632,7 +629,7 @@ fn is_macro_rules(path: &Path) -> bool {
632} 629}
633 630
634fn resolve_submodule( 631fn resolve_submodule(
635 db: &(impl DefDatabase + AstDatabase), 632 db: &impl DefDatabase,
636 file_id: HirFileId, 633 file_id: HirFileId,
637 name: &Name, 634 name: &Name,
638 is_root: bool, 635 is_root: bool,
@@ -675,7 +672,7 @@ mod tests {
675 use rustc_hash::FxHashSet; 672 use rustc_hash::FxHashSet;
676 673
677 fn do_collect_defs( 674 fn do_collect_defs(
678 db: &(impl DefDatabase + AstDatabase), 675 db: &impl DefDatabase,
679 def_map: CrateDefMap, 676 def_map: CrateDefMap,
680 monitor: MacroStackMonitor, 677 monitor: MacroStackMonitor,
681 ) -> CrateDefMap { 678 ) -> CrateDefMap {
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index 9a6349d4b..69c03a36c 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/traits.rs
@@ -12,7 +12,7 @@ use super::{TraitRef, Ty, Canonical, ProjectionTy};
12 12
13use self::chalk::{ToChalk, from_chalk}; 13use self::chalk::{ToChalk, from_chalk};
14 14
15mod chalk; 15pub(crate) mod chalk;
16 16
17pub(crate) type Solver = chalk_solve::Solver; 17pub(crate) type Solver = chalk_solve::Solver;
18 18
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 5105588ee..4ceb8b70b 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -10,7 +10,7 @@ use test_utils::tested_by;
10use ra_db::salsa::{InternId, InternKey}; 10use ra_db::salsa::{InternId, InternKey};
11 11
12use crate::{ 12use crate::{
13 Trait, HasGenericParams, ImplBlock, 13 Trait, HasGenericParams, ImplBlock, Crate,
14 db::HirDatabase, 14 db::HirDatabase,
15 ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy}, 15 ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef, ProjectionTy},
16 ty::display::HirDisplay, 16 ty::display::HirDisplay,
@@ -256,204 +256,16 @@ where
256 DB: HirDatabase, 256 DB: HirDatabase,
257{ 257{
258 fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> { 258 fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum> {
259 debug!("associated_ty_data {:?}", id); 259 self.db.associated_ty_data(id)
260 let type_alias: TypeAlias = from_chalk(self.db, id);
261 let trait_ = match type_alias.container(self.db) {
262 Some(crate::Container::Trait(t)) => t,
263 _ => panic!("associated type not in trait"),
264 };
265 let generic_params = type_alias.generic_params(self.db);
266 let parameter_kinds = generic_params
267 .params_including_parent()
268 .into_iter()
269 .map(|p| chalk_ir::ParameterKind::Ty(lalrpop_intern::intern(&p.name.to_string())))
270 .collect();
271 let datum = AssociatedTyDatum {
272 trait_id: trait_.to_chalk(self.db),
273 id,
274 name: lalrpop_intern::intern(&type_alias.name(self.db).to_string()),
275 parameter_kinds,
276 // FIXME add bounds and where clauses
277 bounds: vec![],
278 where_clauses: vec![],
279 };
280 Arc::new(datum)
281 } 260 }
282 fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> { 261 fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum> {
283 debug!("trait_datum {:?}", trait_id); 262 self.db.trait_datum(self.krate, trait_id)
284 if trait_id == UNKNOWN_TRAIT {
285 let trait_datum_bound = chalk_rust_ir::TraitDatumBound {
286 trait_ref: chalk_ir::TraitRef {
287 trait_id: UNKNOWN_TRAIT,
288 parameters: vec![chalk_ir::Ty::BoundVar(0).cast()],
289 },
290 associated_ty_ids: Vec::new(),
291 where_clauses: Vec::new(),
292 flags: chalk_rust_ir::TraitFlags {
293 auto: false,
294 marker: false,
295 upstream: true,
296 fundamental: false,
297 },
298 };
299 return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) });
300 }
301 let trait_: Trait = from_chalk(self.db, trait_id);
302 debug!("trait {:?} = {:?}", trait_id, trait_.name(self.db));
303 let generic_params = trait_.generic_params(self.db);
304 let bound_vars = Substs::bound_vars(&generic_params);
305 let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db);
306 let flags = chalk_rust_ir::TraitFlags {
307 auto: trait_.is_auto(self.db),
308 upstream: trait_.module(self.db).krate(self.db) != Some(self.krate),
309 // FIXME set these flags correctly
310 marker: false,
311 fundamental: false,
312 };
313 let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars);
314 let associated_ty_ids = trait_
315 .items(self.db)
316 .into_iter()
317 .filter_map(|trait_item| match trait_item {
318 crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias),
319 _ => None,
320 })
321 .map(|type_alias| type_alias.to_chalk(self.db))
322 .collect();
323 let trait_datum_bound =
324 chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids };
325 let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) };
326 Arc::new(trait_datum)
327 } 263 }
328 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> { 264 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> {
329 debug!("struct_datum {:?}", struct_id); 265 self.db.struct_datum(self.krate, struct_id)
330 let type_ctor = from_chalk(self.db, struct_id);
331 debug!("struct {:?} = {:?}", struct_id, type_ctor);
332 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor
333 // FIXME extract this to a method on Ty
334 let (num_params, where_clauses, upstream) = match type_ctor {
335 TypeCtor::Bool
336 | TypeCtor::Char
337 | TypeCtor::Int(_)
338 | TypeCtor::Float(_)
339 | TypeCtor::Never
340 | TypeCtor::Str => (0, vec![], true),
341 TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => {
342 (1, vec![], true)
343 }
344 TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true),
345 TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true),
346 TypeCtor::FnDef(callable) => {
347 tested_by!(trait_resolution_on_fn_type);
348 let krate = match callable {
349 CallableDef::Function(f) => f.module(self.db).krate(self.db),
350 CallableDef::Struct(s) => s.module(self.db).krate(self.db),
351 CallableDef::EnumVariant(v) => {
352 v.parent_enum(self.db).module(self.db).krate(self.db)
353 }
354 };
355 let generic_def: GenericDef = match callable {
356 CallableDef::Function(f) => f.into(),
357 CallableDef::Struct(s) => s.into(),
358 CallableDef::EnumVariant(v) => v.parent_enum(self.db).into(),
359 };
360 let generic_params = generic_def.generic_params(self.db);
361 let bound_vars = Substs::bound_vars(&generic_params);
362 let where_clauses = convert_where_clauses(self.db, generic_def, &bound_vars);
363 (
364 generic_params.count_params_including_parent(),
365 where_clauses,
366 krate != Some(self.krate),
367 )
368 }
369 TypeCtor::Adt(adt) => {
370 let generic_params = adt.generic_params(self.db);
371 let bound_vars = Substs::bound_vars(&generic_params);
372 let where_clauses = convert_where_clauses(self.db, adt.into(), &bound_vars);
373 (
374 generic_params.count_params_including_parent(),
375 where_clauses,
376 adt.krate(self.db) != Some(self.krate),
377 )
378 }
379 };
380 let flags = chalk_rust_ir::StructFlags {
381 upstream,
382 // FIXME set fundamental flag correctly
383 fundamental: false,
384 };
385 let self_ty = chalk_ir::ApplicationTy {
386 name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()),
387 parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(),
388 };
389 let struct_datum_bound = chalk_rust_ir::StructDatumBound {
390 self_ty,
391 fields: Vec::new(), // FIXME add fields (only relevant for auto traits)
392 where_clauses,
393 flags,
394 };
395 let struct_datum = StructDatum { binders: make_binders(struct_datum_bound, num_params) };
396 Arc::new(struct_datum)
397 } 266 }
398 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { 267 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
399 debug!("impl_datum {:?}", impl_id); 268 self.db.impl_datum(self.krate, impl_id)
400 let impl_block: ImplBlock = from_chalk(self.db, impl_id);
401 let generic_params = impl_block.generic_params(self.db);
402 let bound_vars = Substs::bound_vars(&generic_params);
403 let trait_ref = impl_block
404 .target_trait_ref(self.db)
405 .expect("FIXME handle unresolved impl block trait ref")
406 .subst(&bound_vars);
407 let impl_type = if impl_block.module().krate(self.db) == Some(self.krate) {
408 chalk_rust_ir::ImplType::Local
409 } else {
410 chalk_rust_ir::ImplType::External
411 };
412 let where_clauses = convert_where_clauses(self.db, impl_block.into(), &bound_vars);
413 let negative = impl_block.is_negative(self.db);
414 debug!(
415 "impl {:?}: {}{} where {:?}",
416 impl_id,
417 if negative { "!" } else { "" },
418 trait_ref.display(self.db),
419 where_clauses
420 );
421 let trait_ = trait_ref.trait_;
422 let trait_ref = trait_ref.to_chalk(self.db);
423 let associated_ty_values = impl_block
424 .items(self.db)
425 .into_iter()
426 .filter_map(|item| match item {
427 ImplItem::TypeAlias(t) => Some(t),
428 _ => None,
429 })
430 .filter_map(|t| {
431 let assoc_ty = trait_.associated_type_by_name(self.db, t.name(self.db))?;
432 let ty = self.db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars);
433 Some(chalk_rust_ir::AssociatedTyValue {
434 impl_id,
435 associated_ty_id: assoc_ty.to_chalk(self.db),
436 value: chalk_ir::Binders {
437 value: chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(self.db) },
438 binders: vec![], // we don't support GATs yet
439 },
440 })
441 })
442 .collect();
443
444 let impl_datum_bound = chalk_rust_ir::ImplDatumBound {
445 trait_ref: if negative {
446 chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref)
447 } else {
448 chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref)
449 },
450 where_clauses,
451 associated_ty_values,
452 impl_type,
453 };
454 debug!("impl_datum: {:?}", impl_datum_bound);
455 let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) };
456 Arc::new(impl_datum)
457 } 269 }
458 fn impls_for_trait(&self, trait_id: chalk_ir::TraitId) -> Vec<ImplId> { 270 fn impls_for_trait(&self, trait_id: chalk_ir::TraitId) -> Vec<ImplId> {
459 debug!("impls_for_trait {:?}", trait_id); 271 debug!("impls_for_trait {:?}", trait_id);
@@ -503,6 +315,220 @@ where
503 } 315 }
504} 316}
505 317
318pub(crate) fn associated_ty_data_query(
319 db: &impl HirDatabase,
320 id: TypeId,
321) -> Arc<AssociatedTyDatum> {
322 debug!("associated_ty_data {:?}", id);
323 let type_alias: TypeAlias = from_chalk(db, id);
324 let trait_ = match type_alias.container(db) {
325 Some(crate::Container::Trait(t)) => t,
326 _ => panic!("associated type not in trait"),
327 };
328 let generic_params = type_alias.generic_params(db);
329 let parameter_kinds = generic_params
330 .params_including_parent()
331 .into_iter()
332 .map(|p| chalk_ir::ParameterKind::Ty(lalrpop_intern::intern(&p.name.to_string())))
333 .collect();
334 let datum = AssociatedTyDatum {
335 trait_id: trait_.to_chalk(db),
336 id,
337 name: lalrpop_intern::intern(&type_alias.name(db).to_string()),
338 parameter_kinds,
339 // FIXME add bounds and where clauses
340 bounds: vec![],
341 where_clauses: vec![],
342 };
343 Arc::new(datum)
344}
345
346pub(crate) fn trait_datum_query(
347 db: &impl HirDatabase,
348 krate: Crate,
349 trait_id: chalk_ir::TraitId,
350) -> Arc<TraitDatum> {
351 debug!("trait_datum {:?}", trait_id);
352 if trait_id == UNKNOWN_TRAIT {
353 let trait_datum_bound = chalk_rust_ir::TraitDatumBound {
354 trait_ref: chalk_ir::TraitRef {
355 trait_id: UNKNOWN_TRAIT,
356 parameters: vec![chalk_ir::Ty::BoundVar(0).cast()],
357 },
358 associated_ty_ids: Vec::new(),
359 where_clauses: Vec::new(),
360 flags: chalk_rust_ir::TraitFlags {
361 auto: false,
362 marker: false,
363 upstream: true,
364 fundamental: false,
365 },
366 };
367 return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) });
368 }
369 let trait_: Trait = from_chalk(db, trait_id);
370 debug!("trait {:?} = {:?}", trait_id, trait_.name(db));
371 let generic_params = trait_.generic_params(db);
372 let bound_vars = Substs::bound_vars(&generic_params);
373 let trait_ref = trait_.trait_ref(db).subst(&bound_vars).to_chalk(db);
374 let flags = chalk_rust_ir::TraitFlags {
375 auto: trait_.is_auto(db),
376 upstream: trait_.module(db).krate(db) != Some(krate),
377 // FIXME set these flags correctly
378 marker: false,
379 fundamental: false,
380 };
381 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
382 let associated_ty_ids = trait_
383 .items(db)
384 .into_iter()
385 .filter_map(|trait_item| match trait_item {
386 crate::traits::TraitItem::TypeAlias(type_alias) => Some(type_alias),
387 _ => None,
388 })
389 .map(|type_alias| type_alias.to_chalk(db))
390 .collect();
391 let trait_datum_bound =
392 chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids };
393 let trait_datum = TraitDatum { binders: make_binders(trait_datum_bound, bound_vars.len()) };
394 Arc::new(trait_datum)
395}
396
397pub(crate) fn struct_datum_query(
398 db: &impl HirDatabase,
399 krate: Crate,
400 struct_id: chalk_ir::StructId,
401) -> Arc<StructDatum> {
402 debug!("struct_datum {:?}", struct_id);
403 let type_ctor = from_chalk(db, struct_id);
404 debug!("struct {:?} = {:?}", struct_id, type_ctor);
405 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor
406 // FIXME extract this to a method on Ty
407 let (num_params, where_clauses, upstream) = match type_ctor {
408 TypeCtor::Bool
409 | TypeCtor::Char
410 | TypeCtor::Int(_)
411 | TypeCtor::Float(_)
412 | TypeCtor::Never
413 | TypeCtor::Str => (0, vec![], true),
414 TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => {
415 (1, vec![], true)
416 }
417 TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true),
418 TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true),
419 TypeCtor::FnDef(callable) => {
420 tested_by!(trait_resolution_on_fn_type);
421 let upstream = match callable {
422 CallableDef::Function(f) => f.module(db).krate(db),
423 CallableDef::Struct(s) => s.module(db).krate(db),
424 CallableDef::EnumVariant(v) => v.parent_enum(db).module(db).krate(db),
425 } != Some(krate);
426 let generic_def: GenericDef = match callable {
427 CallableDef::Function(f) => f.into(),
428 CallableDef::Struct(s) => s.into(),
429 CallableDef::EnumVariant(v) => v.parent_enum(db).into(),
430 };
431 let generic_params = generic_def.generic_params(db);
432 let bound_vars = Substs::bound_vars(&generic_params);
433 let where_clauses = convert_where_clauses(db, generic_def, &bound_vars);
434 (generic_params.count_params_including_parent(), where_clauses, upstream)
435 }
436 TypeCtor::Adt(adt) => {
437 let generic_params = adt.generic_params(db);
438 let bound_vars = Substs::bound_vars(&generic_params);
439 let where_clauses = convert_where_clauses(db, adt.into(), &bound_vars);
440 (
441 generic_params.count_params_including_parent(),
442 where_clauses,
443 adt.krate(db) != Some(krate),
444 )
445 }
446 };
447 let flags = chalk_rust_ir::StructFlags {
448 upstream,
449 // FIXME set fundamental flag correctly
450 fundamental: false,
451 };
452 let self_ty = chalk_ir::ApplicationTy {
453 name: TypeName::TypeKindId(type_ctor.to_chalk(db).into()),
454 parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(),
455 };
456 let struct_datum_bound = chalk_rust_ir::StructDatumBound {
457 self_ty,
458 fields: Vec::new(), // FIXME add fields (only relevant for auto traits)
459 where_clauses,
460 flags,
461 };
462 let struct_datum = StructDatum { binders: make_binders(struct_datum_bound, num_params) };
463 Arc::new(struct_datum)
464}
465
466pub(crate) fn impl_datum_query(
467 db: &impl HirDatabase,
468 krate: Crate,
469 impl_id: ImplId,
470) -> Arc<ImplDatum> {
471 let _p = ra_prof::profile("impl_datum");
472 debug!("impl_datum {:?}", impl_id);
473 let impl_block: ImplBlock = from_chalk(db, impl_id);
474 let generic_params = impl_block.generic_params(db);
475 let bound_vars = Substs::bound_vars(&generic_params);
476 let trait_ref = impl_block
477 .target_trait_ref(db)
478 .expect("FIXME handle unresolved impl block trait ref")
479 .subst(&bound_vars);
480 let impl_type = if impl_block.module().krate(db) == Some(krate) {
481 chalk_rust_ir::ImplType::Local
482 } else {
483 chalk_rust_ir::ImplType::External
484 };
485 let where_clauses = convert_where_clauses(db, impl_block.into(), &bound_vars);
486 let negative = impl_block.is_negative(db);
487 debug!(
488 "impl {:?}: {}{} where {:?}",
489 impl_id,
490 if negative { "!" } else { "" },
491 trait_ref.display(db),
492 where_clauses
493 );
494 let trait_ = trait_ref.trait_;
495 let trait_ref = trait_ref.to_chalk(db);
496 let associated_ty_values = impl_block
497 .items(db)
498 .into_iter()
499 .filter_map(|item| match item {
500 ImplItem::TypeAlias(t) => Some(t),
501 _ => None,
502 })
503 .filter_map(|t| {
504 let assoc_ty = trait_.associated_type_by_name(db, t.name(db))?;
505 let ty = db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars);
506 Some(chalk_rust_ir::AssociatedTyValue {
507 impl_id,
508 associated_ty_id: assoc_ty.to_chalk(db),
509 value: chalk_ir::Binders {
510 value: chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) },
511 binders: vec![], // we don't support GATs yet
512 },
513 })
514 })
515 .collect();
516
517 let impl_datum_bound = chalk_rust_ir::ImplDatumBound {
518 trait_ref: if negative {
519 chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref)
520 } else {
521 chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref)
522 },
523 where_clauses,
524 associated_ty_values,
525 impl_type,
526 };
527 debug!("impl_datum: {:?}", impl_datum_bound);
528 let impl_datum = ImplDatum { binders: make_binders(impl_datum_bound, bound_vars.len()) };
529 Arc::new(impl_datum)
530}
531
506fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T { 532fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T {
507 T::from_intern_id(InternId::from(chalk_id.index)) 533 T::from_intern_id(InternId::from(chalk_id.index))
508} 534}
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index 82b061419..cb7d30c43 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -14,6 +14,7 @@ use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};
14 ra_db::SourceDatabaseStorage, 14 ra_db::SourceDatabaseStorage,
15 LineIndexDatabaseStorage, 15 LineIndexDatabaseStorage,
16 symbol_index::SymbolsDatabaseStorage, 16 symbol_index::SymbolsDatabaseStorage,
17 hir::db::InternDatabaseStorage,
17 hir::db::AstDatabaseStorage, 18 hir::db::AstDatabaseStorage,
18 hir::db::DefDatabaseStorage, 19 hir::db::DefDatabaseStorage,
19 hir::db::HirDatabaseStorage 20 hir::db::HirDatabaseStorage
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 6373240d5..47222cd0a 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -621,17 +621,32 @@ pub fn handle_formatting(
621 621
622 let output = rustfmt.wait_with_output()?; 622 let output = rustfmt.wait_with_output()?;
623 let captured_stdout = String::from_utf8(output.stdout)?; 623 let captured_stdout = String::from_utf8(output.stdout)?;
624
624 if !output.status.success() { 625 if !output.status.success() {
625 return Err(LspError::new( 626 match output.status.code() {
626 -32900, 627 Some(1) => {
627 format!( 628 // While `rustfmt` doesn't have a specific exit code for parse errors this is the
628 r#"rustfmt exited with: 629 // likely cause exiting with 1. Most Language Servers swallow parse errors on
629 Status: {} 630 // formatting because otherwise an error is surfaced to the user on top of the
630 stdout: {}"#, 631 // syntax error diagnostics they're already receiving. This is especially jarring
631 output.status, captured_stdout, 632 // if they have format on save enabled.
632 ), 633 log::info!("rustfmt exited with status 1, assuming parse error and ignoring");
633 ) 634 return Ok(None);
634 .into()); 635 }
636 _ => {
637 // Something else happened - e.g. `rustfmt` is missing or caught a signal
638 return Err(LspError::new(
639 -32900,
640 format!(
641 r#"rustfmt exited with:
642 Status: {}
643 stdout: {}"#,
644 output.status, captured_stdout,
645 ),
646 )
647 .into());
648 }
649 }
635 } 650 }
636 651
637 Ok(Some(vec![TextEdit { 652 Ok(Some(vec![TextEdit {
diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml
index d55af18f5..787e18385 100644
--- a/crates/ra_prof/Cargo.toml
+++ b/crates/ra_prof/Cargo.toml
@@ -9,3 +9,4 @@ publish = false
9once_cell = "0.2.0" 9once_cell = "0.2.0"
10itertools = "0.8.0" 10itertools = "0.8.0"
11backtrace = "0.3.28" 11backtrace = "0.3.28"
12cpuprofiler = { version = "0.0.3", optional = true }
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs
index de67b4031..1e8d780ab 100644
--- a/crates/ra_prof/src/lib.rs
+++ b/crates/ra_prof/src/lib.rs
@@ -255,6 +255,39 @@ impl Drop for Scope {
255 } 255 }
256} 256}
257 257
258/// A wrapper around https://github.com/AtheMathmo/cpuprofiler
259///
260/// It can be used to capture sampling profiles of sections of code.
261/// It is not exactly out-of-the-box, as it relies on gperftools.
262/// See the docs for the crate for more!
263#[derive(Debug)]
264pub struct CpuProfiler {
265 _private: (),
266}
267
268pub fn cpu_profiler() -> CpuProfiler {
269 #[cfg(feature = "cpuprofiler")]
270 {
271 cpuprofiler::PROFILER.lock().unwrap().start("./out.profile").unwrap();
272 }
273
274 #[cfg(not(feature = "cpuprofiler"))]
275 {
276 eprintln!("cpuprofiler feature is disabled")
277 }
278
279 CpuProfiler { _private: () }
280}
281
282impl Drop for CpuProfiler {
283 fn drop(&mut self) {
284 #[cfg(feature = "cpuprofiler")]
285 {
286 cpuprofiler::PROFILER.lock().unwrap().stop().unwrap();
287 }
288 }
289}
290
258#[cfg(test)] 291#[cfg(test)]
259mod tests { 292mod tests {
260 use super::*; 293 use super::*;
diff --git a/docs/dev/README.md b/docs/dev/README.md
index 3dc37e86e..0a148ed32 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -97,6 +97,25 @@ To work on the VS Code extension, launch code inside `editors/code` and use `F5`
97to launch/debug. To automatically apply formatter and linter suggestions, use 97to launch/debug. To automatically apply formatter and linter suggestions, use
98`npm run fix`. 98`npm run fix`.
99 99
100Tests are located inside `src/test` and are named `*.test.ts`. They use the
101[Mocha](https://mochajs.org) test framework and the builtin Node
102[assert](https://nodejs.org/api/assert.html) module. Unlike normal Node tests
103they must be hosted inside a VS Code instance. This can be done in one of two
104ways:
105
1061. When `F5` debugging in VS Code select the `Extension Tests` configuration
107 from the drop-down at the top of the Debug View. This will launch a temporary
108 instance of VS Code. The test results will appear in the "Debug Console" tab
109 of the primary VS Code instance.
110
1112. Run `npm test` from the command line. Although this is initiated from the
112 command line it is not headless; it will also launch a temporary instance of
113 VS Code.
114
115Due to the requirements of running the tests inside VS Code they are **not run
116on CI**. When making changes to the extension please ensure the tests are not
117broken locally before opening a Pull Request.
118
100# Logging 119# Logging
101 120
102Logging is done by both rust-analyzer and VS Code, so it might be tricky to 121Logging is done by both rust-analyzer and VS Code, so it might be tricky to
diff --git a/editors/code/.vscode/launch.json b/editors/code/.vscode/launch.json
index b9d14dddd..c3578f476 100644
--- a/editors/code/.vscode/launch.json
+++ b/editors/code/.vscode/launch.json
@@ -20,6 +20,7 @@
20 "request": "launch", 20 "request": "launch",
21 "runtimeExecutable": "${execPath}", 21 "runtimeExecutable": "${execPath}",
22 "args": [ 22 "args": [
23 "${workspaceFolder}/src/test/",
23 "--extensionDevelopmentPath=${workspaceFolder}", 24 "--extensionDevelopmentPath=${workspaceFolder}",
24 "--extensionTestsPath=${workspaceFolder}/out/test" 25 "--extensionTestsPath=${workspaceFolder}/out/test"
25 ], 26 ],
diff --git a/editors/code/package.json b/editors/code/package.json
index ac2ba82e3..6e2dd0494 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -23,6 +23,7 @@
23 "postinstall": "node ./node_modules/vscode/bin/install", 23 "postinstall": "node ./node_modules/vscode/bin/install",
24 "fix": "prettier **/*.{json,ts} --write && tslint --project . --fix", 24 "fix": "prettier **/*.{json,ts} --write && tslint --project . --fix",
25 "lint": "tslint --project .", 25 "lint": "tslint --project .",
26 "test": "node node_modules/vscode/bin/test",
26 "prettier": "prettier **/*.{json,ts}", 27 "prettier": "prettier **/*.{json,ts}",
27 "travis": "npm run compile && npm run lint && npm run prettier -- --list-different" 28 "travis": "npm run compile && npm run lint && npm run prettier -- --list-different"
28 }, 29 },
diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts
index 126a8b1b3..1ec5f8d5f 100644
--- a/editors/code/src/commands/cargo_watch.ts
+++ b/editors/code/src/commands/cargo_watch.ts
@@ -2,12 +2,17 @@ import * as child_process from 'child_process';
2import * as fs from 'fs'; 2import * as fs from 'fs';
3import * as path from 'path'; 3import * as path from 'path';
4import * as vscode from 'vscode'; 4import * as vscode from 'vscode';
5
5import { Server } from '../server'; 6import { Server } from '../server';
6import { terminate } from '../utils/processes'; 7import { terminate } from '../utils/processes';
7import { 8import {
8 mapRustDiagnosticToVsCode, 9 mapRustDiagnosticToVsCode,
9 RustDiagnostic 10 RustDiagnostic
10} from '../utils/rust_diagnostics'; 11} from '../utils/rust_diagnostics';
12import {
13 areCodeActionsEqual,
14 areDiagnosticsEqual
15} from '../utils/vscode_diagnostics';
11import { LineBuffer } from './line_buffer'; 16import { LineBuffer } from './line_buffer';
12import { StatusDisplay } from './watch_status'; 17import { StatusDisplay } from './watch_status';
13 18
@@ -184,67 +189,6 @@ export class CargoWatchProvider
184 this.statusDisplay.hide(); 189 this.statusDisplay.hide();
185 } 190 }
186 191
187 function areDiagnosticsEqual(
188 left: vscode.Diagnostic,
189 right: vscode.Diagnostic
190 ): boolean {
191 return (
192 left.source === right.source &&
193 left.severity === right.severity &&
194 left.range.isEqual(right.range) &&
195 left.message === right.message
196 );
197 }
198
199 function areCodeActionsEqual(
200 left: vscode.CodeAction,
201 right: vscode.CodeAction
202 ): boolean {
203 if (
204 left.kind !== right.kind ||
205 left.title !== right.title ||
206 !left.edit ||
207 !right.edit
208 ) {
209 return false;
210 }
211
212 const leftEditEntries = left.edit.entries();
213 const rightEditEntries = right.edit.entries();
214
215 if (leftEditEntries.length !== rightEditEntries.length) {
216 return false;
217 }
218
219 for (let i = 0; i < leftEditEntries.length; i++) {
220 const [leftUri, leftEdits] = leftEditEntries[i];
221 const [rightUri, rightEdits] = rightEditEntries[i];
222
223 if (leftUri.toString() !== rightUri.toString()) {
224 return false;
225 }
226
227 if (leftEdits.length !== rightEdits.length) {
228 return false;
229 }
230
231 for (let j = 0; j < leftEdits.length; j++) {
232 const leftEdit = leftEdits[j];
233 const rightEdit = rightEdits[j];
234
235 if (!leftEdit.range.isEqual(rightEdit.range)) {
236 return false;
237 }
238
239 if (leftEdit.newText !== rightEdit.newText) {
240 return false;
241 }
242 }
243 }
244
245 return true;
246 }
247
248 interface CargoArtifact { 192 interface CargoArtifact {
249 reason: string; 193 reason: string;
250 package_id: string; 194 package_id: string;
diff --git a/editors/code/src/test/fixtures/rust-diagnostics/clippy/trivially_copy_pass_by_ref.json b/editors/code/src/test/fixtures/rust-diagnostics/clippy/trivially_copy_pass_by_ref.json
new file mode 100644
index 000000000..d874e99bc
--- /dev/null
+++ b/editors/code/src/test/fixtures/rust-diagnostics/clippy/trivially_copy_pass_by_ref.json
@@ -0,0 +1,110 @@
1{
2 "message": "this argument is passed by reference, but would be more efficient if passed by value",
3 "code": {
4 "code": "clippy::trivially_copy_pass_by_ref",
5 "explanation": null
6 },
7 "level": "warning",
8 "spans": [
9 {
10 "file_name": "compiler/mir/tagset.rs",
11 "byte_start": 941,
12 "byte_end": 946,
13 "line_start": 42,
14 "line_end": 42,
15 "column_start": 24,
16 "column_end": 29,
17 "is_primary": true,
18 "text": [
19 {
20 "text": " pub fn is_disjoint(&self, other: Self) -> bool {",
21 "highlight_start": 24,
22 "highlight_end": 29
23 }
24 ],
25 "label": null,
26 "suggested_replacement": null,
27 "suggestion_applicability": null,
28 "expansion": null
29 }
30 ],
31 "children": [
32 {
33 "message": "lint level defined here",
34 "code": null,
35 "level": "note",
36 "spans": [
37 {
38 "file_name": "compiler/lib.rs",
39 "byte_start": 8,
40 "byte_end": 19,
41 "line_start": 1,
42 "line_end": 1,
43 "column_start": 9,
44 "column_end": 20,
45 "is_primary": true,
46 "text": [
47 {
48 "text": "#![warn(clippy::all)]",
49 "highlight_start": 9,
50 "highlight_end": 20
51 }
52 ],
53 "label": null,
54 "suggested_replacement": null,
55 "suggestion_applicability": null,
56 "expansion": null
57 }
58 ],
59 "children": [],
60 "rendered": null
61 },
62 {
63 "message": "#[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]",
64 "code": null,
65 "level": "note",
66 "spans": [],
67 "children": [],
68 "rendered": null
69 },
70 {
71 "message": "for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref",
72 "code": null,
73 "level": "help",
74 "spans": [],
75 "children": [],
76 "rendered": null
77 },
78 {
79 "message": "consider passing by value instead",
80 "code": null,
81 "level": "help",
82 "spans": [
83 {
84 "file_name": "compiler/mir/tagset.rs",
85 "byte_start": 941,
86 "byte_end": 946,
87 "line_start": 42,
88 "line_end": 42,
89 "column_start": 24,
90 "column_end": 29,
91 "is_primary": true,
92 "text": [
93 {
94 "text": " pub fn is_disjoint(&self, other: Self) -> bool {",
95 "highlight_start": 24,
96 "highlight_end": 29
97 }
98 ],
99 "label": null,
100 "suggested_replacement": "self",
101 "suggestion_applicability": "Unspecified",
102 "expansion": null
103 }
104 ],
105 "children": [],
106 "rendered": null
107 }
108 ],
109 "rendered": "warning: this argument is passed by reference, but would be more efficient if passed by value\n --> compiler/mir/tagset.rs:42:24\n |\n42 | pub fn is_disjoint(&self, other: Self) -> bool {\n | ^^^^^ help: consider passing by value instead: `self`\n |\nnote: lint level defined here\n --> compiler/lib.rs:1:9\n |\n1 | #![warn(clippy::all)]\n | ^^^^^^^^^^^\n = note: #[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]\n = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref\n\n"
110}
diff --git a/editors/code/src/test/fixtures/rust-diagnostics/error/E0053.json b/editors/code/src/test/fixtures/rust-diagnostics/error/E0053.json
new file mode 100644
index 000000000..ea5c976d1
--- /dev/null
+++ b/editors/code/src/test/fixtures/rust-diagnostics/error/E0053.json
@@ -0,0 +1,42 @@
1{
2 "message": "method `next` has an incompatible type for trait",
3 "code": {
4 "code": "E0053",
5 "explanation": "\nThe parameters of any trait method must match between a trait implementation\nand the trait definition.\n\nHere are a couple examples of this error:\n\n```compile_fail,E0053\ntrait Foo {\n fn foo(x: u16);\n fn bar(&self);\n}\n\nstruct Bar;\n\nimpl Foo for Bar {\n // error, expected u16, found i16\n fn foo(x: i16) { }\n\n // error, types differ in mutability\n fn bar(&mut self) { }\n}\n```\n"
6 },
7 "level": "error",
8 "spans": [
9 {
10 "file_name": "compiler/ty/list_iter.rs",
11 "byte_start": 1307,
12 "byte_end": 1350,
13 "line_start": 52,
14 "line_end": 52,
15 "column_start": 5,
16 "column_end": 48,
17 "is_primary": true,
18 "text": [
19 {
20 "text": " fn next(&self) -> Option<&'list ty::Ref<M>> {",
21 "highlight_start": 5,
22 "highlight_end": 48
23 }
24 ],
25 "label": "types differ in mutability",
26 "suggested_replacement": null,
27 "suggestion_applicability": null,
28 "expansion": null
29 }
30 ],
31 "children": [
32 {
33 "message": "expected type `fn(&mut ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&ty::Ref<M>>`\n found type `fn(&ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&'list ty::Ref<M>>`",
34 "code": null,
35 "level": "note",
36 "spans": [],
37 "children": [],
38 "rendered": null
39 }
40 ],
41 "rendered": "error[E0053]: method `next` has an incompatible type for trait\n --> compiler/ty/list_iter.rs:52:5\n |\n52 | fn next(&self) -> Option<&'list ty::Ref<M>> {\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability\n |\n = note: expected type `fn(&mut ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&ty::Ref<M>>`\n found type `fn(&ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&'list ty::Ref<M>>`\n\n"
42}
diff --git a/editors/code/src/test/fixtures/rust-diagnostics/error/E0061.json b/editors/code/src/test/fixtures/rust-diagnostics/error/E0061.json
new file mode 100644
index 000000000..3154d1098
--- /dev/null
+++ b/editors/code/src/test/fixtures/rust-diagnostics/error/E0061.json
@@ -0,0 +1,114 @@
1{
2 "message": "this function takes 2 parameters but 3 parameters were supplied",
3 "code": {
4 "code": "E0061",
5 "explanation": "\nThe number of arguments passed to a function must match the number of arguments\nspecified in the function signature.\n\nFor example, a function like:\n\n```\nfn f(a: u16, b: &str) {}\n```\n\nMust always be called with exactly two arguments, e.g., `f(2, \"test\")`.\n\nNote that Rust does not have a notion of optional function arguments or\nvariadic functions (except for its C-FFI).\n"
6 },
7 "level": "error",
8 "spans": [
9 {
10 "file_name": "compiler/ty/select.rs",
11 "byte_start": 8787,
12 "byte_end": 9241,
13 "line_start": 219,
14 "line_end": 231,
15 "column_start": 5,
16 "column_end": 6,
17 "is_primary": false,
18 "text": [
19 {
20 "text": " pub fn add_evidence(",
21 "highlight_start": 5,
22 "highlight_end": 25
23 },
24 {
25 "text": " &mut self,",
26 "highlight_start": 1,
27 "highlight_end": 19
28 },
29 {
30 "text": " target_poly: &ty::Ref<ty::Poly>,",
31 "highlight_start": 1,
32 "highlight_end": 41
33 },
34 {
35 "text": " evidence_poly: &ty::Ref<ty::Poly>,",
36 "highlight_start": 1,
37 "highlight_end": 43
38 },
39 {
40 "text": " ) {",
41 "highlight_start": 1,
42 "highlight_end": 8
43 },
44 {
45 "text": " match target_poly {",
46 "highlight_start": 1,
47 "highlight_end": 28
48 },
49 {
50 "text": " ty::Ref::Var(tvar, _) => self.add_var_evidence(tvar, evidence_poly),",
51 "highlight_start": 1,
52 "highlight_end": 81
53 },
54 {
55 "text": " ty::Ref::Fixed(target_ty) => {",
56 "highlight_start": 1,
57 "highlight_end": 43
58 },
59 {
60 "text": " let evidence_ty = evidence_poly.resolve_to_ty();",
61 "highlight_start": 1,
62 "highlight_end": 65
63 },
64 {
65 "text": " self.add_evidence_ty(target_ty, evidence_poly, evidence_ty)",
66 "highlight_start": 1,
67 "highlight_end": 76
68 },
69 {
70 "text": " }",
71 "highlight_start": 1,
72 "highlight_end": 14
73 },
74 {
75 "text": " }",
76 "highlight_start": 1,
77 "highlight_end": 10
78 },
79 {
80 "text": " }",
81 "highlight_start": 1,
82 "highlight_end": 6
83 }
84 ],
85 "label": "defined here",
86 "suggested_replacement": null,
87 "suggestion_applicability": null,
88 "expansion": null
89 },
90 {
91 "file_name": "compiler/ty/select.rs",
92 "byte_start": 4045,
93 "byte_end": 4057,
94 "line_start": 104,
95 "line_end": 104,
96 "column_start": 18,
97 "column_end": 30,
98 "is_primary": true,
99 "text": [
100 {
101 "text": " self.add_evidence(target_fixed, evidence_fixed, false);",
102 "highlight_start": 18,
103 "highlight_end": 30
104 }
105 ],
106 "label": "expected 2 parameters",
107 "suggested_replacement": null,
108 "suggestion_applicability": null,
109 "expansion": null
110 }
111 ],
112 "children": [],
113 "rendered": "error[E0061]: this function takes 2 parameters but 3 parameters were supplied\n --> compiler/ty/select.rs:104:18\n |\n104 | self.add_evidence(target_fixed, evidence_fixed, false);\n | ^^^^^^^^^^^^ expected 2 parameters\n...\n219 | / pub fn add_evidence(\n220 | | &mut self,\n221 | | target_poly: &ty::Ref<ty::Poly>,\n222 | | evidence_poly: &ty::Ref<ty::Poly>,\n... |\n230 | | }\n231 | | }\n | |_____- defined here\n\n"
114}
diff --git a/editors/code/src/test/fixtures/rust-diagnostics/warning/unused_variables.json b/editors/code/src/test/fixtures/rust-diagnostics/warning/unused_variables.json
new file mode 100644
index 000000000..d1e2be722
--- /dev/null
+++ b/editors/code/src/test/fixtures/rust-diagnostics/warning/unused_variables.json
@@ -0,0 +1,72 @@
1{
2 "message": "unused variable: `foo`",
3 "code": {
4 "code": "unused_variables",
5 "explanation": null
6 },
7 "level": "warning",
8 "spans": [
9 {
10 "file_name": "driver/subcommand/repl.rs",
11 "byte_start": 9228,
12 "byte_end": 9231,
13 "line_start": 291,
14 "line_end": 291,
15 "column_start": 9,
16 "column_end": 12,
17 "is_primary": true,
18 "text": [
19 {
20 "text": " let foo = 42;",
21 "highlight_start": 9,
22 "highlight_end": 12
23 }
24 ],
25 "label": null,
26 "suggested_replacement": null,
27 "suggestion_applicability": null,
28 "expansion": null
29 }
30 ],
31 "children": [
32 {
33 "message": "#[warn(unused_variables)] on by default",
34 "code": null,
35 "level": "note",
36 "spans": [],
37 "children": [],
38 "rendered": null
39 },
40 {
41 "message": "consider prefixing with an underscore",
42 "code": null,
43 "level": "help",
44 "spans": [
45 {
46 "file_name": "driver/subcommand/repl.rs",
47 "byte_start": 9228,
48 "byte_end": 9231,
49 "line_start": 291,
50 "line_end": 291,
51 "column_start": 9,
52 "column_end": 12,
53 "is_primary": true,
54 "text": [
55 {
56 "text": " let foo = 42;",
57 "highlight_start": 9,
58 "highlight_end": 12
59 }
60 ],
61 "label": null,
62 "suggested_replacement": "_foo",
63 "suggestion_applicability": "MachineApplicable",
64 "expansion": null
65 }
66 ],
67 "children": [],
68 "rendered": null
69 }
70 ],
71 "rendered": "warning: unused variable: `foo`\n --> driver/subcommand/repl.rs:291:9\n |\n291 | let foo = 42;\n | ^^^ help: consider prefixing with an underscore: `_foo`\n |\n = note: #[warn(unused_variables)] on by default\n\n"
72}
diff --git a/editors/code/src/test/index.ts b/editors/code/src/test/index.ts
new file mode 100644
index 000000000..6e565c254
--- /dev/null
+++ b/editors/code/src/test/index.ts
@@ -0,0 +1,22 @@
1//
2// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
3//
4// This file is providing the test runner to use when running extension tests.
5// By default the test runner in use is Mocha based.
6//
7// You can provide your own test runner if you want to override it by exporting
8// a function run(testRoot: string, clb: (error:Error) => void) that the extension
9// host can call to run the tests. The test runner is expected to use console.log
10// to report the results back to the caller. When the tests are finished, return
11// a possible error to the callback or null if none.
12
13import * as testRunner from 'vscode/lib/testrunner';
14
15// You can directly control Mocha options by uncommenting the following lines
16// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
17testRunner.configure({
18 ui: 'bdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
19 useColors: true // colored output from test results
20});
21
22module.exports = testRunner;
diff --git a/editors/code/src/test/rust_diagnostics.test.ts b/editors/code/src/test/rust_diagnostics.test.ts
new file mode 100644
index 000000000..f27c58fe2
--- /dev/null
+++ b/editors/code/src/test/rust_diagnostics.test.ts
@@ -0,0 +1,162 @@
1import * as assert from 'assert';
2import * as fs from 'fs';
3import * as vscode from 'vscode';
4
5import {
6 MappedRustDiagnostic,
7 mapRustDiagnosticToVsCode,
8 RustDiagnostic
9} from '../utils/rust_diagnostics';
10
11function loadDiagnosticFixture(name: string): RustDiagnostic {
12 const jsonText = fs
13 .readFileSync(
14 // We're actually in our JavaScript output directory, climb out
15 `${__dirname}/../../src/test/fixtures/rust-diagnostics/${name}.json`
16 )
17 .toString();
18
19 return JSON.parse(jsonText);
20}
21
22function mapFixtureToVsCode(name: string): MappedRustDiagnostic {
23 const rd = loadDiagnosticFixture(name);
24 const mapResult = mapRustDiagnosticToVsCode(rd);
25
26 if (!mapResult) {
27 return assert.fail('Mapping unexpectedly failed');
28 }
29 return mapResult;
30}
31
32describe('mapRustDiagnosticToVsCode', () => {
33 it('should map an incompatible type for trait error', () => {
34 const { diagnostic, codeActions } = mapFixtureToVsCode('error/E0053');
35
36 assert.strictEqual(
37 diagnostic.severity,
38 vscode.DiagnosticSeverity.Error
39 );
40 assert.strictEqual(diagnostic.source, 'rustc');
41 assert.strictEqual(
42 diagnostic.message,
43 [
44 `method \`next\` has an incompatible type for trait`,
45 `expected type \`fn(&mut ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&ty::Ref<M>>\``,
46 ` found type \`fn(&ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&'list ty::Ref<M>>\``
47 ].join('\n')
48 );
49 assert.strictEqual(diagnostic.code, 'E0053');
50 assert.strictEqual(diagnostic.tags, undefined);
51
52 // No related information
53 assert.deepStrictEqual(diagnostic.relatedInformation, []);
54
55 // There are no code actions available
56 assert.strictEqual(codeActions.length, 0);
57 });
58
59 it('should map an unused variable warning', () => {
60 const { diagnostic, codeActions } = mapFixtureToVsCode(
61 'warning/unused_variables'
62 );
63
64 assert.strictEqual(
65 diagnostic.severity,
66 vscode.DiagnosticSeverity.Warning
67 );
68 assert.strictEqual(
69 diagnostic.message,
70 [
71 'unused variable: `foo`',
72 '#[warn(unused_variables)] on by default'
73 ].join('\n')
74 );
75 assert.strictEqual(diagnostic.code, 'unused_variables');
76 assert.strictEqual(diagnostic.source, 'rustc');
77 assert.deepStrictEqual(diagnostic.tags, [
78 vscode.DiagnosticTag.Unnecessary
79 ]);
80
81 // No related information
82 assert.deepStrictEqual(diagnostic.relatedInformation, []);
83
84 // One code action available to prefix the variable
85 assert.strictEqual(codeActions.length, 1);
86 const [codeAction] = codeActions;
87 assert.strictEqual(
88 codeAction.title,
89 'consider prefixing with an underscore: `_foo`'
90 );
91 assert(codeAction.isPreferred);
92 });
93
94 it('should map a wrong number of parameters error', () => {
95 const { diagnostic, codeActions } = mapFixtureToVsCode('error/E0061');
96
97 assert.strictEqual(
98 diagnostic.severity,
99 vscode.DiagnosticSeverity.Error
100 );
101 assert.strictEqual(
102 diagnostic.message,
103 'this function takes 2 parameters but 3 parameters were supplied'
104 );
105 assert.strictEqual(diagnostic.code, 'E0061');
106 assert.strictEqual(diagnostic.source, 'rustc');
107 assert.strictEqual(diagnostic.tags, undefined);
108
109 // One related information for the original definition
110 const relatedInformation = diagnostic.relatedInformation;
111 if (!relatedInformation) {
112 return assert.fail('Related information unexpectedly undefined');
113 }
114 assert.strictEqual(relatedInformation.length, 1);
115 const [related] = relatedInformation;
116 assert.strictEqual(related.message, 'defined here');
117
118 // There are no actions available
119 assert.strictEqual(codeActions.length, 0);
120 });
121
122 it('should map a Clippy copy pass by ref warning', () => {
123 const { diagnostic, codeActions } = mapFixtureToVsCode(
124 'clippy/trivially_copy_pass_by_ref'
125 );
126
127 assert.strictEqual(
128 diagnostic.severity,
129 vscode.DiagnosticSeverity.Warning
130 );
131 assert.strictEqual(diagnostic.source, 'clippy');
132 assert.strictEqual(
133 diagnostic.message,
134 [
135 'this argument is passed by reference, but would be more efficient if passed by value',
136 '#[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]',
137 'for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref'
138 ].join('\n')
139 );
140 assert.strictEqual(diagnostic.code, 'trivially_copy_pass_by_ref');
141 assert.strictEqual(diagnostic.tags, undefined);
142
143 // One related information for the lint definition
144 const relatedInformation = diagnostic.relatedInformation;
145 if (!relatedInformation) {
146 return assert.fail('Related information unexpectedly undefined');
147 }
148 assert.strictEqual(relatedInformation.length, 1);
149 const [related] = relatedInformation;
150 assert.strictEqual(related.message, 'lint level defined here');
151
152 // One code action available to pass by value
153 assert.strictEqual(codeActions.length, 1);
154 const [codeAction] = codeActions;
155 assert.strictEqual(
156 codeAction.title,
157 'consider passing by value instead: `self`'
158 );
159 // Clippy does not mark this as machine applicable
160 assert.strictEqual(codeAction.isPreferred, false);
161 });
162});
diff --git a/editors/code/src/test/vscode_diagnostics.test.ts b/editors/code/src/test/vscode_diagnostics.test.ts
new file mode 100644
index 000000000..9c5d812fa
--- /dev/null
+++ b/editors/code/src/test/vscode_diagnostics.test.ts
@@ -0,0 +1,182 @@
1import * as assert from 'assert';
2import * as vscode from 'vscode';
3
4import {
5 areCodeActionsEqual,
6 areDiagnosticsEqual
7} from '../utils/vscode_diagnostics';
8
9const uri = vscode.Uri.file('/file/1');
10
11const range1 = new vscode.Range(
12 new vscode.Position(1, 2),
13 new vscode.Position(3, 4)
14);
15
16const range2 = new vscode.Range(
17 new vscode.Position(5, 6),
18 new vscode.Position(7, 8)
19);
20
21describe('areDiagnosticsEqual', () => {
22 it('should treat identical diagnostics as equal', () => {
23 const diagnostic1 = new vscode.Diagnostic(
24 range1,
25 'Hello, world!',
26 vscode.DiagnosticSeverity.Error
27 );
28
29 const diagnostic2 = new vscode.Diagnostic(
30 range1,
31 'Hello, world!',
32 vscode.DiagnosticSeverity.Error
33 );
34
35 assert(areDiagnosticsEqual(diagnostic1, diagnostic2));
36 });
37
38 it('should treat diagnostics with different sources as inequal', () => {
39 const diagnostic1 = new vscode.Diagnostic(
40 range1,
41 'Hello, world!',
42 vscode.DiagnosticSeverity.Error
43 );
44 diagnostic1.source = 'rustc';
45
46 const diagnostic2 = new vscode.Diagnostic(
47 range1,
48 'Hello, world!',
49 vscode.DiagnosticSeverity.Error
50 );
51 diagnostic2.source = 'clippy';
52
53 assert(!areDiagnosticsEqual(diagnostic1, diagnostic2));
54 });
55
56 it('should treat diagnostics with different ranges as inequal', () => {
57 const diagnostic1 = new vscode.Diagnostic(
58 range1,
59 'Hello, world!',
60 vscode.DiagnosticSeverity.Error
61 );
62
63 const diagnostic2 = new vscode.Diagnostic(
64 range2,
65 'Hello, world!',
66 vscode.DiagnosticSeverity.Error
67 );
68
69 assert(!areDiagnosticsEqual(diagnostic1, diagnostic2));
70 });
71
72 it('should treat diagnostics with different messages as inequal', () => {
73 const diagnostic1 = new vscode.Diagnostic(
74 range1,
75 'Hello, world!',
76 vscode.DiagnosticSeverity.Error
77 );
78
79 const diagnostic2 = new vscode.Diagnostic(
80 range1,
81 'Goodbye!, world!',
82 vscode.DiagnosticSeverity.Error
83 );
84
85 assert(!areDiagnosticsEqual(diagnostic1, diagnostic2));
86 });
87
88 it('should treat diagnostics with different severities as inequal', () => {
89 const diagnostic1 = new vscode.Diagnostic(
90 range1,
91 'Hello, world!',
92 vscode.DiagnosticSeverity.Warning
93 );
94
95 const diagnostic2 = new vscode.Diagnostic(
96 range1,
97 'Hello, world!',
98 vscode.DiagnosticSeverity.Error
99 );
100
101 assert(!areDiagnosticsEqual(diagnostic1, diagnostic2));
102 });
103});
104
105describe('areCodeActionsEqual', () => {
106 it('should treat identical actions as equal', () => {
107 const codeAction1 = new vscode.CodeAction(
108 'Fix me!',
109 vscode.CodeActionKind.QuickFix
110 );
111
112 const codeAction2 = new vscode.CodeAction(
113 'Fix me!',
114 vscode.CodeActionKind.QuickFix
115 );
116
117 const edit = new vscode.WorkspaceEdit();
118 edit.replace(uri, range1, 'Replace with this');
119 codeAction1.edit = edit;
120 codeAction2.edit = edit;
121
122 assert(areCodeActionsEqual(codeAction1, codeAction2));
123 });
124
125 it('should treat actions with different types as inequal', () => {
126 const codeAction1 = new vscode.CodeAction(
127 'Fix me!',
128 vscode.CodeActionKind.Refactor
129 );
130
131 const codeAction2 = new vscode.CodeAction(
132 'Fix me!',
133 vscode.CodeActionKind.QuickFix
134 );
135
136 const edit = new vscode.WorkspaceEdit();
137 edit.replace(uri, range1, 'Replace with this');
138 codeAction1.edit = edit;
139 codeAction2.edit = edit;
140
141 assert(!areCodeActionsEqual(codeAction1, codeAction2));
142 });
143
144 it('should treat actions with different titles as inequal', () => {
145 const codeAction1 = new vscode.CodeAction(
146 'Fix me!',
147 vscode.CodeActionKind.Refactor
148 );
149
150 const codeAction2 = new vscode.CodeAction(
151 'Do something different!',
152 vscode.CodeActionKind.Refactor
153 );
154
155 const edit = new vscode.WorkspaceEdit();
156 edit.replace(uri, range1, 'Replace with this');
157 codeAction1.edit = edit;
158 codeAction2.edit = edit;
159
160 assert(!areCodeActionsEqual(codeAction1, codeAction2));
161 });
162
163 it('should treat actions with different edits as inequal', () => {
164 const codeAction1 = new vscode.CodeAction(
165 'Fix me!',
166 vscode.CodeActionKind.Refactor
167 );
168 const edit1 = new vscode.WorkspaceEdit();
169 edit1.replace(uri, range1, 'Replace with this');
170 codeAction1.edit = edit1;
171
172 const codeAction2 = new vscode.CodeAction(
173 'Fix me!',
174 vscode.CodeActionKind.Refactor
175 );
176 const edit2 = new vscode.WorkspaceEdit();
177 edit2.replace(uri, range1, 'Replace with this other thing');
178 codeAction2.edit = edit2;
179
180 assert(!areCodeActionsEqual(codeAction1, codeAction2));
181 });
182});
diff --git a/editors/code/src/utils/rust_diagnostics.ts b/editors/code/src/utils/rust_diagnostics.ts
index ed049c95e..3c524cb37 100644
--- a/editors/code/src/utils/rust_diagnostics.ts
+++ b/editors/code/src/utils/rust_diagnostics.ts
@@ -187,8 +187,18 @@ export function mapRustDiagnosticToVsCode(
187 187
188 const vd = new vscode.Diagnostic(location.range, rd.message, severity); 188 const vd = new vscode.Diagnostic(location.range, rd.message, severity);
189 189
190 vd.source = 'rustc'; 190 let source = 'rustc';
191 vd.code = rd.code ? rd.code.code : undefined; 191 let code = rd.code && rd.code.code;
192 if (code) {
193 // See if this is an RFC #2103 scoped lint (e.g. from Clippy)
194 const scopedCode = code.split('::');
195 if (scopedCode.length === 2) {
196 [source, code] = scopedCode;
197 }
198 }
199
200 vd.source = source;
201 vd.code = code;
192 vd.relatedInformation = []; 202 vd.relatedInformation = [];
193 203
194 for (const secondarySpan of secondarySpans) { 204 for (const secondarySpan of secondarySpans) {
diff --git a/editors/code/src/utils/vscode_diagnostics.ts b/editors/code/src/utils/vscode_diagnostics.ts
new file mode 100644
index 000000000..9d763c8d6
--- /dev/null
+++ b/editors/code/src/utils/vscode_diagnostics.ts
@@ -0,0 +1,73 @@
1import * as vscode from 'vscode';
2
3/** Compares two `vscode.Diagnostic`s for equality */
4export function areDiagnosticsEqual(
5 left: vscode.Diagnostic,
6 right: vscode.Diagnostic
7): boolean {
8 return (
9 left.source === right.source &&
10 left.severity === right.severity &&
11 left.range.isEqual(right.range) &&
12 left.message === right.message
13 );
14}
15
16/** Compares two `vscode.TextEdit`s for equality */
17function areTextEditsEqual(
18 left: vscode.TextEdit,
19 right: vscode.TextEdit
20): boolean {
21 if (!left.range.isEqual(right.range)) {
22 return false;
23 }
24
25 if (left.newText !== right.newText) {
26 return false;
27 }
28
29 return true;
30}
31
32/** Compares two `vscode.CodeAction`s for equality */
33export function areCodeActionsEqual(
34 left: vscode.CodeAction,
35 right: vscode.CodeAction
36): boolean {
37 if (
38 left.kind !== right.kind ||
39 left.title !== right.title ||
40 !left.edit ||
41 !right.edit
42 ) {
43 return false;
44 }
45
46 const leftEditEntries = left.edit.entries();
47 const rightEditEntries = right.edit.entries();
48
49 if (leftEditEntries.length !== rightEditEntries.length) {
50 return false;
51 }
52
53 for (let i = 0; i < leftEditEntries.length; i++) {
54 const [leftUri, leftEdits] = leftEditEntries[i];
55 const [rightUri, rightEdits] = rightEditEntries[i];
56
57 if (leftUri.toString() !== rightUri.toString()) {
58 return false;
59 }
60
61 if (leftEdits.length !== rightEdits.length) {
62 return false;
63 }
64
65 for (let j = 0; j < leftEdits.length; j++) {
66 if (!areTextEditsEqual(leftEdits[j], rightEdits[j])) {
67 return false;
68 }
69 }
70 }
71
72 return true;
73}