aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock296
-rw-r--r--crates/ra_analysis/Cargo.toml2
-rw-r--r--crates/ra_analysis/src/db.rs117
-rw-r--r--crates/ra_analysis/src/db/imp.rs153
-rw-r--r--crates/ra_analysis/src/db/mod.rs85
-rw-r--r--crates/ra_analysis/src/descriptors.rs10
-rw-r--r--crates/ra_analysis/src/imp.rs55
-rw-r--r--crates/ra_analysis/src/lib.rs9
-rw-r--r--crates/ra_analysis/src/module_map.rs163
-rw-r--r--crates/ra_analysis/src/queries.rs39
-rw-r--r--crates/ra_analysis/src/roots.rs70
-rw-r--r--crates/ra_analysis/src/symbol_index.rs9
-rw-r--r--crates/ra_analysis/tests/tests.rs2
-rw-r--r--crates/ra_editor/src/line_index.rs2
-rw-r--r--crates/ra_editor/src/symbols.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs4
-rw-r--r--crates/ra_lsp_server/src/main_loop/mod.rs4
-rw-r--r--crates/ra_lsp_server/src/server_world.rs1
-rw-r--r--crates/ra_syntax/src/lib.rs2
-rw-r--r--crates/salsa/Cargo.toml8
-rw-r--r--crates/salsa/src/lib.rs293
-rw-r--r--crates/salsa/tests/integration.rs170
22 files changed, 432 insertions, 1064 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 62feeb539..707257a31 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -15,6 +15,11 @@ dependencies = [
15] 15]
16 16
17[[package]] 17[[package]]
18name = "arrayref"
19version = "0.3.5"
20source = "registry+https://github.com/rust-lang/crates.io-index"
21
22[[package]]
18name = "arrayvec" 23name = "arrayvec"
19version = "0.4.7" 24version = "0.4.7"
20source = "registry+https://github.com/rust-lang/crates.io-index" 25source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -68,6 +73,20 @@ version = "1.0.4"
68source = "registry+https://github.com/rust-lang/crates.io-index" 73source = "registry+https://github.com/rust-lang/crates.io-index"
69 74
70[[package]] 75[[package]]
76name = "block-buffer"
77version = "0.3.3"
78source = "registry+https://github.com/rust-lang/crates.io-index"
79dependencies = [
80 "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
81 "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
82]
83
84[[package]]
85name = "byte-tools"
86version = "0.2.0"
87source = "registry+https://github.com/rust-lang/crates.io-index"
88
89[[package]]
71name = "byteorder" 90name = "byteorder"
72version = "1.2.6" 91version = "1.2.6"
73source = "registry+https://github.com/rust-lang/crates.io-index" 92source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -79,9 +98,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
79dependencies = [ 98dependencies = [
80 "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 99 "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
81 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 100 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
82 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 101 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
83 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 102 "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
84 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", 103 "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
85] 104]
86 105
87[[package]] 106[[package]]
@@ -188,6 +207,16 @@ version = "0.5.0"
188source = "registry+https://github.com/rust-lang/crates.io-index" 207source = "registry+https://github.com/rust-lang/crates.io-index"
189 208
190[[package]] 209[[package]]
210name = "derive-new"
211version = "0.5.5"
212source = "registry+https://github.com/rust-lang/crates.io-index"
213dependencies = [
214 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
215 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
216 "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
217]
218
219[[package]]
191name = "deunicode" 220name = "deunicode"
192version = "0.4.3" 221version = "0.4.3"
193source = "registry+https://github.com/rust-lang/crates.io-index" 222source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -198,6 +227,14 @@ version = "2.0.0"
198source = "registry+https://github.com/rust-lang/crates.io-index" 227source = "registry+https://github.com/rust-lang/crates.io-index"
199 228
200[[package]] 229[[package]]
230name = "digest"
231version = "0.7.6"
232source = "registry+https://github.com/rust-lang/crates.io-index"
233dependencies = [
234 "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
235]
236
237[[package]]
201name = "drop_bomb" 238name = "drop_bomb"
202version = "0.1.4" 239version = "0.1.4"
203source = "registry+https://github.com/rust-lang/crates.io-index" 240source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -229,13 +266,18 @@ name = "failure_derive"
229version = "0.1.2" 266version = "0.1.2"
230source = "registry+https://github.com/rust-lang/crates.io-index" 267source = "registry+https://github.com/rust-lang/crates.io-index"
231dependencies = [ 268dependencies = [
232 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 269 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
233 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 270 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
234 "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", 271 "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
235 "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 272 "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
236] 273]
237 274
238[[package]] 275[[package]]
276name = "fake-simd"
277version = "0.1.2"
278source = "registry+https://github.com/rust-lang/crates.io-index"
279
280[[package]]
239name = "flexi_logger" 281name = "flexi_logger"
240version = "0.9.2" 282version = "0.9.2"
241source = "registry+https://github.com/rust-lang/crates.io-index" 283source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -277,9 +319,17 @@ dependencies = [
277 "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 319 "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
278 "languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)", 320 "languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
279 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 321 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
280 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 322 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
281 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 323 "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
282 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", 324 "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
325]
326
327[[package]]
328name = "generic-array"
329version = "0.9.0"
330source = "registry+https://github.com/rust-lang/crates.io-index"
331dependencies = [
332 "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
283] 333]
284 334
285[[package]] 335[[package]]
@@ -312,7 +362,7 @@ dependencies = [
312 362
313[[package]] 363[[package]]
314name = "im" 364name = "im"
315version = "12.1.0" 365version = "12.2.0"
316source = "registry+https://github.com/rust-lang/crates.io-index" 366source = "registry+https://github.com/rust-lang/crates.io-index"
317dependencies = [ 367dependencies = [
318 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 368 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -320,6 +370,11 @@ dependencies = [
320] 370]
321 371
322[[package]] 372[[package]]
373name = "indexmap"
374version = "1.0.1"
375source = "registry+https://github.com/rust-lang/crates.io-index"
376
377[[package]]
323name = "itertools" 378name = "itertools"
324version = "0.7.8" 379version = "0.7.8"
325source = "registry+https://github.com/rust-lang/crates.io-index" 380source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -343,11 +398,11 @@ version = "0.51.0"
343source = "registry+https://github.com/rust-lang/crates.io-index" 398source = "registry+https://github.com/rust-lang/crates.io-index"
344dependencies = [ 399dependencies = [
345 "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 400 "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
346 "num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 401 "num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
347 "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 402 "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
348 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 403 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
349 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 404 "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
350 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", 405 "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
351 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 406 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
352 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 407 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
353] 408]
@@ -383,6 +438,11 @@ dependencies = [
383] 438]
384 439
385[[package]] 440[[package]]
441name = "maplit"
442version = "1.0.1"
443source = "registry+https://github.com/rust-lang/crates.io-index"
444
445[[package]]
386name = "matches" 446name = "matches"
387version = "0.1.8" 447version = "0.1.8"
388source = "registry+https://github.com/rust-lang/crates.io-index" 448source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -418,13 +478,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
418 478
419[[package]] 479[[package]]
420name = "num-derive" 480name = "num-derive"
421version = "0.2.2" 481version = "0.2.3"
422source = "registry+https://github.com/rust-lang/crates.io-index" 482source = "registry+https://github.com/rust-lang/crates.io-index"
423dependencies = [ 483dependencies = [
424 "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 484 "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
425 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 485 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
426 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 486 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
427 "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", 487 "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)",
428] 488]
429 489
430[[package]] 490[[package]]
@@ -492,38 +552,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
492 552
493[[package]] 553[[package]]
494name = "pest" 554name = "pest"
495version = "1.0.6" 555version = "2.0.1"
496source = "registry+https://github.com/rust-lang/crates.io-index" 556source = "registry+https://github.com/rust-lang/crates.io-index"
557dependencies = [
558 "ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
559]
497 560
498[[package]] 561[[package]]
499name = "pest_derive" 562name = "pest_derive"
500version = "1.0.8" 563version = "2.0.1"
501source = "registry+https://github.com/rust-lang/crates.io-index" 564source = "registry+https://github.com/rust-lang/crates.io-index"
502dependencies = [ 565dependencies = [
503 "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 566 "pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
504 "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 567 "pest_generator 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
505 "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
506] 568]
507 569
508[[package]] 570[[package]]
509name = "proc-macro2" 571name = "pest_generator"
510version = "0.4.19" 572version = "2.0.0"
511source = "registry+https://github.com/rust-lang/crates.io-index" 573source = "registry+https://github.com/rust-lang/crates.io-index"
512dependencies = [ 574dependencies = [
513 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 575 "pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
576 "pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
577 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
578 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
579 "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
514] 580]
515 581
516[[package]] 582[[package]]
517name = "quote" 583name = "pest_meta"
518version = "0.3.15" 584version = "2.0.3"
585source = "registry+https://github.com/rust-lang/crates.io-index"
586dependencies = [
587 "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
588 "pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
589 "sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
590]
591
592[[package]]
593name = "proc-macro2"
594version = "0.4.20"
519source = "registry+https://github.com/rust-lang/crates.io-index" 595source = "registry+https://github.com/rust-lang/crates.io-index"
596dependencies = [
597 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
598]
520 599
521[[package]] 600[[package]]
522name = "quote" 601name = "quote"
523version = "0.6.8" 602version = "0.6.8"
524source = "registry+https://github.com/rust-lang/crates.io-index" 603source = "registry+https://github.com/rust-lang/crates.io-index"
525dependencies = [ 604dependencies = [
526 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 605 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
527] 606]
528 607
529[[package]] 608[[package]]
@@ -532,7 +611,7 @@ version = "0.1.0"
532dependencies = [ 611dependencies = [
533 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 612 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
534 "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 613 "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
535 "im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 614 "im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
536 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 615 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
537 "once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 616 "once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
538 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 617 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -541,7 +620,7 @@ dependencies = [
541 "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 620 "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
542 "relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 621 "relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
543 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 622 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
544 "salsa 0.1.0", 623 "salsa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
545 "test_utils 0.1.0", 624 "test_utils 0.1.0",
546] 625]
547 626
@@ -579,7 +658,7 @@ dependencies = [
579 "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 658 "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
580 "flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", 659 "flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
581 "gen_lsp_server 0.1.0", 660 "gen_lsp_server 0.1.0",
582 "im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 661 "im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
583 "languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)", 662 "languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
584 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 663 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
585 "ra_analysis 0.1.0", 664 "ra_analysis 0.1.0",
@@ -588,10 +667,10 @@ dependencies = [
588 "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 667 "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
589 "relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 668 "relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
590 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 669 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
591 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 670 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
592 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 671 "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
593 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", 672 "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
594 "smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 673 "smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
595 "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 674 "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
596 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 675 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
597 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 676 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -629,13 +708,21 @@ dependencies = [
629 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 708 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
630 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 709 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
631 "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 710 "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
632 "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 711 "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
633 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 712 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
634] 713]
635 714
636[[package]] 715[[package]]
637name = "rand_core" 716name = "rand_core"
638version = "0.2.1" 717version = "0.2.2"
718source = "registry+https://github.com/rust-lang/crates.io-index"
719dependencies = [
720 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
721]
722
723[[package]]
724name = "rand_core"
725version = "0.3.0"
639source = "registry+https://github.com/rust-lang/crates.io-index" 726source = "registry+https://github.com/rust-lang/crates.io-index"
640 727
641[[package]] 728[[package]]
@@ -712,7 +799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
712dependencies = [ 799dependencies = [
713 "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 800 "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
714 "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 801 "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
715 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 802 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
716] 803]
717 804
718[[package]] 805[[package]]
@@ -721,7 +808,7 @@ version = "0.1.0"
721source = "registry+https://github.com/rust-lang/crates.io-index" 808source = "registry+https://github.com/rust-lang/crates.io-index"
722dependencies = [ 809dependencies = [
723 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 810 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
724 "smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 811 "smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
725 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 812 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
726] 813]
727 814
@@ -758,10 +845,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
758 845
759[[package]] 846[[package]]
760name = "salsa" 847name = "salsa"
761version = "0.1.0" 848version = "0.5.0"
849source = "registry+https://github.com/rust-lang/crates.io-index"
762dependencies = [ 850dependencies = [
763 "im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 851 "derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
852 "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
853 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
764 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 854 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
855 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
856 "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
765] 857]
766 858
767[[package]] 859[[package]]
@@ -783,7 +875,7 @@ version = "0.9.0"
783source = "registry+https://github.com/rust-lang/crates.io-index" 875source = "registry+https://github.com/rust-lang/crates.io-index"
784dependencies = [ 876dependencies = [
785 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 877 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
786 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 878 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
787] 879]
788 880
789[[package]] 881[[package]]
@@ -793,30 +885,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
793 885
794[[package]] 886[[package]]
795name = "serde" 887name = "serde"
796version = "1.0.79" 888version = "1.0.80"
797source = "registry+https://github.com/rust-lang/crates.io-index" 889source = "registry+https://github.com/rust-lang/crates.io-index"
798dependencies = [ 890dependencies = [
799 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 891 "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
800] 892]
801 893
802[[package]] 894[[package]]
803name = "serde_derive" 895name = "serde_derive"
804version = "1.0.79" 896version = "1.0.80"
805source = "registry+https://github.com/rust-lang/crates.io-index" 897source = "registry+https://github.com/rust-lang/crates.io-index"
806dependencies = [ 898dependencies = [
807 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 899 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
808 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 900 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
809 "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)", 901 "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)",
810] 902]
811 903
812[[package]] 904[[package]]
813name = "serde_json" 905name = "serde_json"
814version = "1.0.31" 906version = "1.0.32"
815source = "registry+https://github.com/rust-lang/crates.io-index" 907source = "registry+https://github.com/rust-lang/crates.io-index"
816dependencies = [ 908dependencies = [
817 "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 909 "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
818 "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 910 "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
819 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 911 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
912]
913
914[[package]]
915name = "sha-1"
916version = "0.7.0"
917source = "registry+https://github.com/rust-lang/crates.io-index"
918dependencies = [
919 "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
920 "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
921 "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
922 "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
820] 923]
821 924
822[[package]] 925[[package]]
@@ -837,10 +940,10 @@ dependencies = [
837 940
838[[package]] 941[[package]]
839name = "smol_str" 942name = "smol_str"
840version = "0.1.6" 943version = "0.1.7"
841source = "registry+https://github.com/rust-lang/crates.io-index" 944source = "registry+https://github.com/rust-lang/crates.io-index"
842dependencies = [ 945dependencies = [
843 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 946 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
844] 947]
845 948
846[[package]] 949[[package]]
@@ -860,48 +963,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
860 963
861[[package]] 964[[package]]
862name = "syn" 965name = "syn"
863version = "0.11.11"
864source = "registry+https://github.com/rust-lang/crates.io-index"
865dependencies = [
866 "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
867 "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
868 "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
869]
870
871[[package]]
872name = "syn"
873version = "0.14.9" 966version = "0.14.9"
874source = "registry+https://github.com/rust-lang/crates.io-index" 967source = "registry+https://github.com/rust-lang/crates.io-index"
875dependencies = [ 968dependencies = [
876 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 969 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
877 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 970 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
878 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 971 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
879] 972]
880 973
881[[package]] 974[[package]]
882name = "syn" 975name = "syn"
883version = "0.15.7" 976version = "0.15.11"
884source = "registry+https://github.com/rust-lang/crates.io-index" 977source = "registry+https://github.com/rust-lang/crates.io-index"
885dependencies = [ 978dependencies = [
886 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 979 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
887 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 980 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
888 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 981 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
889] 982]
890 983
891[[package]] 984[[package]]
892name = "synom"
893version = "0.11.3"
894source = "registry+https://github.com/rust-lang/crates.io-index"
895dependencies = [
896 "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
897]
898
899[[package]]
900name = "synstructure" 985name = "synstructure"
901version = "0.9.0" 986version = "0.9.0"
902source = "registry+https://github.com/rust-lang/crates.io-index" 987source = "registry+https://github.com/rust-lang/crates.io-index"
903dependencies = [ 988dependencies = [
904 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 989 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
905 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 990 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
906 "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", 991 "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
907 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 992 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -918,7 +1003,7 @@ dependencies = [
918 1003
919[[package]] 1004[[package]]
920name = "tera" 1005name = "tera"
921version = "0.11.16" 1006version = "0.11.17"
922source = "registry+https://github.com/rust-lang/crates.io-index" 1007source = "registry+https://github.com/rust-lang/crates.io-index"
923dependencies = [ 1008dependencies = [
924 "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1009 "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -926,11 +1011,11 @@ dependencies = [
926 "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1011 "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
927 "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1012 "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
928 "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1013 "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
929 "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1014 "pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
930 "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", 1015 "pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
931 "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 1016 "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
932 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 1017 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
933 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", 1018 "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
934 "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1019 "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
935 "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1020 "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
936 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1021 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -960,7 +1045,7 @@ name = "text_unit"
960version = "0.1.4" 1045version = "0.1.4"
961source = "registry+https://github.com/rust-lang/crates.io-index" 1046source = "registry+https://github.com/rust-lang/crates.io-index"
962dependencies = [ 1047dependencies = [
963 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 1048 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
964] 1049]
965 1050
966[[package]] 1051[[package]]
@@ -998,7 +1083,7 @@ dependencies = [
998 "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1083 "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
999 "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 1084 "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
1000 "ron 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1085 "ron 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1001 "tera 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)", 1086 "tera 0.11.17 (registry+https://github.com/rust-lang/crates.io-index)",
1002 "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 1087 "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
1003] 1088]
1004 1089
@@ -1008,6 +1093,11 @@ version = "1.10.0"
1008source = "registry+https://github.com/rust-lang/crates.io-index" 1093source = "registry+https://github.com/rust-lang/crates.io-index"
1009 1094
1010[[package]] 1095[[package]]
1096name = "ucd-trie"
1097version = "0.1.1"
1098source = "registry+https://github.com/rust-lang/crates.io-index"
1099
1100[[package]]
1011name = "ucd-util" 1101name = "ucd-util"
1012version = "0.1.1" 1102version = "0.1.1"
1013source = "registry+https://github.com/rust-lang/crates.io-index" 1103source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1081,11 +1171,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1081 1171
1082[[package]] 1172[[package]]
1083name = "unicode-xid" 1173name = "unicode-xid"
1084version = "0.0.4"
1085source = "registry+https://github.com/rust-lang/crates.io-index"
1086
1087[[package]]
1088name = "unicode-xid"
1089version = "0.1.0" 1174version = "0.1.0"
1090source = "registry+https://github.com/rust-lang/crates.io-index" 1175source = "registry+https://github.com/rust-lang/crates.io-index"
1091 1176
@@ -1112,7 +1197,7 @@ name = "url_serde"
1112version = "0.2.0" 1197version = "0.2.0"
1113source = "registry+https://github.com/rust-lang/crates.io-index" 1198source = "registry+https://github.com/rust-lang/crates.io-index"
1114dependencies = [ 1199dependencies = [
1115 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 1200 "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
1116 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1201 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
1117] 1202]
1118 1203
@@ -1176,12 +1261,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1176[metadata] 1261[metadata]
1177"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" 1262"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
1178"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 1263"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
1264"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
1179"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" 1265"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
1180"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" 1266"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
1181"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" 1267"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
1182"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" 1268"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
1183"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" 1269"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
1184"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" 1270"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
1271"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
1272"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
1185"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" 1273"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
1186"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1" 1274"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1"
1187"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" 1275"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
@@ -1195,22 +1283,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1195"checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416" 1283"checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416"
1196"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" 1284"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
1197"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" 1285"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
1286"checksum derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "899ec79626c14e00ccc9729b4d750bbe67fe76a8f436824c16e0233bbd9d7daa"
1198"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" 1287"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
1199"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" 1288"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
1289"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
1200"checksum drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f" 1290"checksum drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f"
1201"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" 1291"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
1202"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" 1292"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
1203"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9" 1293"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9"
1204"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" 1294"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
1295"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
1205"checksum flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2103a4bd3f67bf8b3e89fe0695cd13ac23c9968a2a81f2ccf2d95f1bb4e5a520" 1296"checksum flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2103a4bd3f67bf8b3e89fe0695cd13ac23c9968a2a81f2ccf2d95f1bb4e5a520"
1206"checksum fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9b0408ab57c1bf7c634b2ac6a165d14f642dc3335a43203090a7f8c78b54577b" 1297"checksum fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9b0408ab57c1bf7c634b2ac6a165d14f642dc3335a43203090a7f8c78b54577b"
1207"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 1298"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
1208"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 1299"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
1300"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
1209"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 1301"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
1210"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" 1302"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
1211"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" 1303"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
1212"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1304"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
1213"checksum im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90742b94a13db9b161eeab35f89bc9723634eb72bfd124f3ebb025734fdfef18" 1305"checksum im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9c7f9bb8aee47fc16d535a705f7867a9fc83bb822e5e1043bb98e77ffeed3c"
1306"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
1214"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" 1307"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
1215"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" 1308"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
1216"checksum join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7bddc885f3fd69dd4b5d747c2efe6dd2c36d795ea9938281ed50910e32c95e31" 1309"checksum join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7bddc885f3fd69dd4b5d747c2efe6dd2c36d795ea9938281ed50910e32c95e31"
@@ -1219,12 +1312,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1219"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" 1312"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
1220"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" 1313"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a"
1221"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" 1314"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
1315"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
1222"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1316"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
1223"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" 1317"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
1224"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" 1318"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
1225"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" 1319"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
1226"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" 1320"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
1227"checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7" 1321"checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d"
1228"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" 1322"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
1229"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" 1323"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
1230"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" 1324"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
@@ -1233,14 +1327,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1233"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" 1327"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
1234"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" 1328"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
1235"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1329"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
1236"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" 1330"checksum pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c3abb0d36ede865dcc689fd3bee2ff39094eff6e57a814f4a53c3c6108088353"
1237"checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" 1331"checksum pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b76f477146419bc539a63f4ef40e902166cb43b3e51cecc71d9136fd12c567e7"
1238"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" 1332"checksum pest_generator 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebee4e9680be4fd162e6f3394ae4192a6b60b1e4d17d845e631f0c68d1a3386"
1239"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 1333"checksum pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f6d5f6f0e6082578c86af197d780dc38328e3f768cec06aac9bc46d714e8221"
1334"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
1240"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" 1335"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
1241"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" 1336"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
1242"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" 1337"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
1243"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" 1338"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
1339"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
1244"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa" 1340"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa"
1245"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" 1341"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
1246"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" 1342"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
@@ -1256,32 +1352,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1256"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1352"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
1257"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" 1353"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
1258"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" 1354"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
1355"checksum salsa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8301c563959d6d50fe0a34817f0d9ff08fe12eda7456e01e2bbde1588ea30602"
1259"checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c" 1356"checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c"
1260"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 1357"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
1261"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1358"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
1262"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1359"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
1263"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" 1360"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
1264"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe" 1361"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
1265"checksum serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "bb47a3d5c84320222f66d7db21157c4a7407755de41798f9b4c1c40593397b1a" 1362"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
1363"checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
1266"checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" 1364"checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
1267"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" 1365"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
1268"checksum smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "248055d41f4c53f8ee7048e8a578a5190d0cca306630718091e4d481735e44b9" 1366"checksum smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ed6f19b800d76574926e458d5f8e2dbea86c2b58c08d33a982448f09ac8d0c"
1269"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" 1367"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
1270"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" 1368"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
1271"checksum superslice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50b13d42370e0f5fc62eafdd5c2d20065eaf5458dab215ff3e20e63eea96b30" 1369"checksum superslice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50b13d42370e0f5fc62eafdd5c2d20065eaf5458dab215ff3e20e63eea96b30"
1272"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
1273"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" 1370"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
1274"checksum syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)" = "455a6ec9b368f8c479b0ae5494d13b22dc00990d2f00d68c9dc6a2dc4f17f210" 1371"checksum syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b036b7b35e846707c0e55c2c9441fa47867c0f87fca416921db3261b1d8c741a"
1275"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
1276"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" 1372"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
1277"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" 1373"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
1278"checksum tera 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4f79f17fe555fffe4838a082a63636883ee13022888dc7bdc99edad8e0a411cd" 1374"checksum tera 0.11.17 (registry+https://github.com/rust-lang/crates.io-index)" = "2829d259c4699fbbe8acb353d231e6da31ff4301c52244413ed29ff6093da412"
1279"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" 1375"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
1280"checksum text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc86da66d0b9aa8d359b0ec31b4342c6bc52637eadef05b91b098551a9f8e9" 1376"checksum text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc86da66d0b9aa8d359b0ec31b4342c6bc52637eadef05b91b098551a9f8e9"
1281"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" 1377"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
1282"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 1378"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
1283"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" 1379"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
1284"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" 1380"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
1381"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
1285"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" 1382"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
1286"checksum unic-char-property 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce36d3f7ce754afdbccccf8ff0dd0134e50fb44aaae579f96218856e9e5dbd1e" 1383"checksum unic-char-property 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce36d3f7ce754afdbccccf8ff0dd0134e50fb44aaae579f96218856e9e5dbd1e"
1287"checksum unic-char-range 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab85fab42ad1b26cafc03bf891f69cb4d6e15f491030e89a0122197baa8ae8" 1384"checksum unic-char-range 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab85fab42ad1b26cafc03bf891f69cb4d6e15f491030e89a0122197baa8ae8"
@@ -1293,7 +1390,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1293"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" 1390"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
1294"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" 1391"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
1295"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" 1392"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
1296"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
1297"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1393"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
1298"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 1394"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
1299"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" 1395"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml
index 28d95c581..17b04182f 100644
--- a/crates/ra_analysis/Cargo.toml
+++ b/crates/ra_analysis/Cargo.toml
@@ -15,7 +15,7 @@ fst = "0.3.1"
15im = "12.0.0" 15im = "12.0.0"
16ra_syntax = { path = "../ra_syntax" } 16ra_syntax = { path = "../ra_syntax" }
17ra_editor = { path = "../ra_editor" } 17ra_editor = { path = "../ra_editor" }
18salsa = { path = "../salsa" } 18salsa = "0.5.0"
19rustc-hash = "1.0" 19rustc-hash = "1.0"
20 20
21[dev-dependencies] 21[dev-dependencies]
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs
new file mode 100644
index 000000000..c69577233
--- /dev/null
+++ b/crates/ra_analysis/src/db.rs
@@ -0,0 +1,117 @@
1use std::{
2 fmt,
3 sync::Arc,
4 hash::{Hash, Hasher},
5};
6use salsa;
7use rustc_hash::FxHashSet;
8use ra_syntax::File;
9use ra_editor::{LineIndex};
10use crate::{
11 symbol_index::SymbolIndex,
12 module_map::{ModulesDatabase, ModuleTreeQuery, ModuleDescriptorQuery},
13 FileId, FileResolverImp,
14};
15
16#[derive(Default)]
17pub(crate) struct RootDatabase {
18 runtime: salsa::runtime::Runtime<RootDatabase>,
19}
20
21impl fmt::Debug for RootDatabase {
22 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
23 fmt.write_str("RootDatabase { ... }")
24 }
25}
26
27impl salsa::Database for RootDatabase {
28 fn salsa_runtime(&self) -> &salsa::runtime::Runtime<RootDatabase> {
29 &self.runtime
30 }
31}
32
33impl salsa::ParallelDatabase for RootDatabase {
34 fn fork(&self) -> Self {
35 RootDatabase {
36 runtime: self.runtime.fork(),
37 }
38 }
39}
40
41impl Clone for RootDatabase {
42 fn clone(&self) -> RootDatabase {
43 salsa::ParallelDatabase::fork(self)
44 }
45}
46
47salsa::database_storage! {
48 pub(crate) struct RootDatabaseStorage for RootDatabase {
49 impl FilesDatabase {
50 fn file_text() for FileTextQuery;
51 fn file_set() for FileSetQuery;
52 }
53 impl SyntaxDatabase {
54 fn file_syntax() for FileSyntaxQuery;
55 fn file_lines() for FileLinesQuery;
56 fn file_symbols() for FileSymbolsQuery;
57 }
58 impl ModulesDatabase {
59 fn module_tree() for ModuleTreeQuery;
60 fn module_descriptor() for ModuleDescriptorQuery;
61 }
62 }
63}
64
65salsa::query_group! {
66 pub(crate) trait FilesDatabase: salsa::Database {
67 fn file_text(file_id: FileId) -> Arc<String> {
68 type FileTextQuery;
69 storage input;
70 }
71 fn file_set(key: ()) -> Arc<FileSet> {
72 type FileSetQuery;
73 storage input;
74 }
75 }
76}
77
78#[derive(Default, Debug, PartialEq, Eq)]
79pub(crate) struct FileSet {
80 pub(crate) files: FxHashSet<FileId>,
81 pub(crate) resolver: FileResolverImp,
82}
83
84impl Hash for FileSet {
85 fn hash<H: Hasher>(&self, hasher: &mut H) {
86 let mut files = self.files.iter().cloned().collect::<Vec<_>>();
87 files.sort();
88 files.hash(hasher);
89 }
90}
91
92salsa::query_group! {
93 pub(crate) trait SyntaxDatabase: FilesDatabase {
94 fn file_syntax(file_id: FileId) -> File {
95 type FileSyntaxQuery;
96 }
97 fn file_lines(file_id: FileId) -> Arc<LineIndex> {
98 type FileLinesQuery;
99 }
100 fn file_symbols(file_id: FileId) -> Arc<SymbolIndex> {
101 type FileSymbolsQuery;
102 }
103 }
104}
105
106fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File {
107 let text = db.file_text(file_id);
108 File::parse(&*text)
109}
110fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> {
111 let text = db.file_text(file_id);
112 Arc::new(LineIndex::new(&*text))
113}
114fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<SymbolIndex> {
115 let syntax = db.file_syntax(file_id);
116 Arc::new(SymbolIndex::for_file(file_id, syntax))
117}
diff --git a/crates/ra_analysis/src/db/imp.rs b/crates/ra_analysis/src/db/imp.rs
deleted file mode 100644
index 7669b6184..000000000
--- a/crates/ra_analysis/src/db/imp.rs
+++ /dev/null
@@ -1,153 +0,0 @@
1use std::{
2 sync::Arc,
3 any::Any,
4 hash::{Hash, Hasher},
5 collections::hash_map::{DefaultHasher},
6 iter,
7};
8use rustc_hash::FxHashMap;
9use salsa;
10use crate::{FileId, imp::FileResolverImp};
11use super::{State, Query, QueryCtx};
12
13pub(super) type Data = Arc<Any + Send + Sync + 'static>;
14
15#[derive(Debug)]
16pub(super) struct Db {
17 names: Arc<FxHashMap<salsa::QueryTypeId, &'static str>>,
18 pub(super) imp: salsa::Db<State, Data>,
19}
20
21impl Db {
22 pub(super) fn new(mut reg: QueryRegistry) -> Db {
23 let config = reg.config.take().unwrap();
24 Db {
25 names: Arc::new(reg.names),
26 imp: salsa::Db::new(config, State::default())
27 }
28 }
29 pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db {
30 let names = self.names.clone();
31 let mut invalidations = salsa::Invalidations::new();
32 invalidations.invalidate(FILE_TEXT, changed_files.iter().map(hash).map(salsa::InputFingerprint));
33 if resolver_changed {
34 invalidations.invalidate(FILE_SET, iter::once(salsa::InputFingerprint(hash(&()))));
35 } else {
36 invalidations.invalidate(FILE_SET, iter::empty());
37 }
38 let imp = self.imp.with_ground_data(
39 new_state,
40 invalidations,
41 );
42 Db { names, imp }
43 }
44 pub(super) fn extract_trace(&self, ctx: &salsa::QueryCtx<State, Data>) -> Vec<&'static str> {
45 ctx.trace().into_iter().map(|it| self.names[&it]).collect()
46 }
47}
48
49pub(crate) trait EvalQuery {
50 type Params;
51 type Output;
52 fn query_type(&self) -> salsa::QueryTypeId;
53 fn f(&self) -> salsa::QueryFn<State, Data>;
54 fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc<Self::Output>;
55}
56
57impl<T, R> EvalQuery for Query<T, R>
58where
59 T: Hash + Send + Sync + 'static,
60 R: Hash + Send + Sync + 'static,
61{
62 type Params = T;
63 type Output = R;
64 fn query_type(&self) -> salsa::QueryTypeId {
65 salsa::QueryTypeId(self.0)
66 }
67 fn f(&self) -> salsa::QueryFn<State, Data> {
68 let f = self.1;
69 Box::new(move |ctx, data| {
70 let ctx = QueryCtx { imp: ctx };
71 let data: &T = data.downcast_ref().unwrap();
72 let res = f(ctx, data);
73 let h = hash(&res);
74 (Arc::new(res), salsa::OutputFingerprint(h))
75 })
76 }
77 fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc<Self::Output> {
78 let query_id = salsa::QueryId(
79 self.query_type(),
80 salsa::InputFingerprint(hash(&params)),
81 );
82 let res = ctx.imp.get(query_id, Arc::new(params));
83 res.downcast().unwrap()
84 }
85}
86
87pub(super) struct QueryRegistry {
88 config: Option<salsa::QueryConfig<State, Data>>,
89 names: FxHashMap<salsa::QueryTypeId, &'static str>,
90}
91
92impl QueryRegistry {
93 pub(super) fn new() -> QueryRegistry {
94 let mut config = salsa::QueryConfig::<State, Data>::new();
95 config = config.with_ground_query(
96 FILE_TEXT, Box::new(|state, params| {
97 let file_id: &FileId = params.downcast_ref().unwrap();
98 let res = state.file_map[file_id].clone();
99 let fingerprint = salsa::OutputFingerprint(hash(&res));
100 (res, fingerprint)
101 })
102 );
103 config = config.with_ground_query(
104 FILE_SET, Box::new(|state, _params| {
105 let file_ids: Vec<FileId> = state.file_map.keys().cloned().collect();
106 let hash = hash(&file_ids);
107 let file_resolver = state.file_resolver.clone();
108 let res = (file_ids, file_resolver);
109 let fingerprint = salsa::OutputFingerprint(hash);
110 (Arc::new(res), fingerprint)
111 })
112 );
113 let mut names = FxHashMap::default();
114 names.insert(FILE_TEXT, "FILE_TEXT");
115 names.insert(FILE_SET, "FILE_SET");
116 QueryRegistry { config: Some(config), names }
117 }
118 pub(super) fn add<Q: EvalQuery>(&mut self, q: Q, name: &'static str) {
119 let id = q.query_type();
120 let prev = self.names.insert(id, name);
121 assert!(prev.is_none(), "duplicate query: {:?}", id);
122 let config = self.config.take().unwrap();
123 let config = config.with_query(id, q.f());
124 self.config= Some(config);
125 }
126}
127
128fn hash<T: Hash>(x: &T) -> u64 {
129 let mut hasher = DefaultHasher::new();
130 x.hash(&mut hasher);
131 hasher.finish()
132}
133
134const FILE_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(0);
135pub(super) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc<String> {
136 let query_id = salsa::QueryId(
137 FILE_TEXT,
138 salsa::InputFingerprint(hash(&file_id)),
139 );
140 let res = ctx.imp.get(query_id, Arc::new(file_id));
141 res.downcast().unwrap()
142}
143
144const FILE_SET: salsa::QueryTypeId = salsa::QueryTypeId(1);
145pub(super) fn file_set(ctx: QueryCtx) -> Arc<(Vec<FileId>, FileResolverImp)> {
146 let query_id = salsa::QueryId(
147 FILE_SET,
148 salsa::InputFingerprint(hash(&())),
149 );
150 let res = ctx.imp.get(query_id, Arc::new(()));
151 res.downcast().unwrap()
152}
153
diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs
deleted file mode 100644
index 4eb7d922d..000000000
--- a/crates/ra_analysis/src/db/mod.rs
+++ /dev/null
@@ -1,85 +0,0 @@
1mod imp;
2
3use std::{
4 sync::Arc,
5};
6use im;
7use salsa;
8use crate::{FileId, imp::FileResolverImp};
9
10#[derive(Debug, Default, Clone)]
11pub(crate) struct State {
12 pub(crate) file_map: im::HashMap<FileId, Arc<String>>,
13 pub(crate) file_resolver: FileResolverImp
14}
15
16#[derive(Debug)]
17pub(crate) struct Db {
18 imp: imp::Db,
19}
20
21#[derive(Clone, Copy)]
22pub(crate) struct QueryCtx<'a> {
23 imp: &'a salsa::QueryCtx<State, imp::Data>,
24}
25
26pub(crate) struct Query<T, R>(pub(crate) u16, pub(crate) fn(QueryCtx, &T) -> R);
27
28pub(crate) struct QueryRegistry {
29 imp: imp::QueryRegistry,
30}
31
32impl Default for Db {
33 fn default() -> Db {
34 Db::new()
35 }
36}
37
38impl Db {
39 pub(crate) fn new() -> Db {
40 let reg = QueryRegistry::new();
41 Db { imp: imp::Db::new(reg.imp) }
42 }
43 pub(crate) fn state(&self) -> &State {
44 self.imp.imp.ground_data()
45 }
46 pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db {
47 Db { imp: self.imp.with_changes(new_state, changed_files, resolver_changed) }
48 }
49 pub(crate) fn make_query<F: FnOnce(QueryCtx) -> R, R>(&self, f: F) -> R {
50 let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() };
51 f(ctx)
52 }
53 #[allow(unused)]
54 pub(crate) fn trace_query<F: FnOnce(QueryCtx) -> R, R>(&self, f: F) -> (R, Vec<&'static str>) {
55 let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() };
56 let res = f(ctx);
57 let trace = self.imp.extract_trace(ctx.imp);
58 (res, trace)
59 }
60}
61
62impl<'a> QueryCtx<'a> {
63 pub(crate) fn get<Q: imp::EvalQuery>(&self, q: Q, params: Q::Params) -> Arc<Q::Output> {
64 q.get(self, params)
65 }
66}
67
68pub(crate) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc<String> {
69 imp::file_text(ctx, file_id)
70}
71
72pub(crate) fn file_set(ctx: QueryCtx) -> Arc<(Vec<FileId>, FileResolverImp)> {
73 imp::file_set(ctx)
74}
75impl QueryRegistry {
76 fn new() -> QueryRegistry {
77 let mut reg = QueryRegistry { imp: imp::QueryRegistry::new() };
78 crate::queries::register_queries(&mut reg);
79 crate::module_map::register_queries(&mut reg);
80 reg
81 }
82 pub(crate) fn add<Q: imp::EvalQuery>(&mut self, q: Q, name: &'static str) {
83 self.imp.add(q, name)
84 }
85}
diff --git a/crates/ra_analysis/src/descriptors.rs b/crates/ra_analysis/src/descriptors.rs
index f26dac875..8d9f38ca5 100644
--- a/crates/ra_analysis/src/descriptors.rs
+++ b/crates/ra_analysis/src/descriptors.rs
@@ -12,7 +12,7 @@ use crate::{
12 imp::FileResolverImp, 12 imp::FileResolverImp,
13}; 13};
14 14
15#[derive(Debug, Hash)] 15#[derive(Debug, PartialEq, Eq, Hash)]
16pub struct ModuleDescriptor { 16pub struct ModuleDescriptor {
17 pub submodules: Vec<Submodule> 17 pub submodules: Vec<Submodule>
18} 18}
@@ -43,7 +43,7 @@ pub struct Submodule {
43 pub name: SmolStr, 43 pub name: SmolStr,
44} 44}
45 45
46#[derive(Hash, Debug)] 46#[derive(Debug, PartialEq, Eq, Hash)]
47pub(crate) struct ModuleTreeDescriptor { 47pub(crate) struct ModuleTreeDescriptor {
48 nodes: Vec<NodeData>, 48 nodes: Vec<NodeData>,
49 links: Vec<LinkData>, 49 links: Vec<LinkData>,
@@ -52,7 +52,7 @@ pub(crate) struct ModuleTreeDescriptor {
52 52
53#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 53#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
54struct Node(usize); 54struct Node(usize);
55#[derive(Hash, Debug)] 55#[derive(Hash, Debug, PartialEq, Eq)]
56struct NodeData { 56struct NodeData {
57 file_id: FileId, 57 file_id: FileId,
58 links: Vec<Link>, 58 links: Vec<Link>,
@@ -61,7 +61,7 @@ struct NodeData {
61 61
62#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 62#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
63pub(crate) struct Link(usize); 63pub(crate) struct Link(usize);
64#[derive(Hash, Debug)] 64#[derive(Hash, Debug, PartialEq, Eq)]
65struct LinkData { 65struct LinkData {
66 owner: Node, 66 owner: Node,
67 name: SmolStr, 67 name: SmolStr,
@@ -70,7 +70,7 @@ struct LinkData {
70} 70}
71 71
72 72
73#[derive(Clone, Debug, Hash)] 73#[derive(Clone, Debug, Hash, PartialEq, Eq)]
74pub enum Problem { 74pub enum Problem {
75 UnresolvedModule { 75 UnresolvedModule {
76 candidate: RelativePathBuf, 76 candidate: RelativePathBuf,
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 26f5e175b..5efcaeca0 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -1,8 +1,8 @@
1use std::{ 1use std::{
2 sync::{ 2 sync::{
3 Arc, 3 Arc,
4 atomic::{AtomicBool, Ordering::SeqCst},
5 }, 4 },
5 hash::{Hash, Hasher},
6 fmt, 6 fmt,
7 collections::VecDeque, 7 collections::VecDeque,
8 iter, 8 iter,
@@ -29,6 +29,21 @@ pub(crate) struct FileResolverImp {
29 inner: Arc<FileResolver> 29 inner: Arc<FileResolver>
30} 30}
31 31
32impl PartialEq for FileResolverImp {
33 fn eq(&self, other: &FileResolverImp) -> bool {
34 self.inner() == other.inner()
35 }
36}
37
38impl Eq for FileResolverImp {
39}
40
41impl Hash for FileResolverImp {
42 fn hash<H: Hasher>(&self, hasher: &mut H) {
43 self.inner().hash(hasher);
44 }
45}
46
32impl FileResolverImp { 47impl FileResolverImp {
33 pub(crate) fn new(inner: Arc<FileResolver>) -> FileResolverImp { 48 pub(crate) fn new(inner: Arc<FileResolver>) -> FileResolverImp {
34 FileResolverImp { inner } 49 FileResolverImp { inner }
@@ -39,6 +54,9 @@ impl FileResolverImp {
39 pub(crate) fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> { 54 pub(crate) fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> {
40 self.inner.resolve(file_id, path) 55 self.inner.resolve(file_id, path)
41 } 56 }
57 fn inner(&self) -> *const FileResolver {
58 &*self.inner
59 }
42} 60}
43 61
44impl Default for FileResolverImp { 62impl Default for FileResolverImp {
@@ -59,29 +77,27 @@ impl Default for FileResolverImp {
59 77
60#[derive(Debug)] 78#[derive(Debug)]
61pub(crate) struct AnalysisHostImpl { 79pub(crate) struct AnalysisHostImpl {
62 data: Arc<WorldData> 80 data: WorldData
63} 81}
64 82
65impl AnalysisHostImpl { 83impl AnalysisHostImpl {
66 pub fn new() -> AnalysisHostImpl { 84 pub fn new() -> AnalysisHostImpl {
67 AnalysisHostImpl { 85 AnalysisHostImpl {
68 data: Arc::new(WorldData::default()), 86 data: WorldData::default(),
69 } 87 }
70 } 88 }
71 pub fn analysis(&self) -> AnalysisImpl { 89 pub fn analysis(&self) -> AnalysisImpl {
72 AnalysisImpl { 90 AnalysisImpl {
73 needs_reindex: AtomicBool::new(false),
74 data: self.data.clone(), 91 data: self.data.clone(),
75 } 92 }
76 } 93 }
77 pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) { 94 pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) {
78 let data = self.data_mut(); 95 self.data_mut()
79 data.root = Arc::new(data.root.apply_changes(changes, None)); 96 .root.apply_changes(changes, None);
80 } 97 }
81 pub fn set_file_resolver(&mut self, resolver: FileResolverImp) { 98 pub fn set_file_resolver(&mut self, resolver: FileResolverImp) {
82 let data = self.data_mut(); 99 self.data_mut()
83 data.file_resolver = resolver.clone(); 100 .root.apply_changes(&mut iter::empty(), Some(resolver));
84 data.root = Arc::new(data.root.apply_changes(&mut iter::empty(), Some(resolver)));
85 } 101 }
86 pub fn set_crate_graph(&mut self, graph: CrateGraph) { 102 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
87 let mut visited = FxHashSet::default(); 103 let mut visited = FxHashSet::default();
@@ -96,34 +112,24 @@ impl AnalysisHostImpl {
96 self.data_mut().libs.push(Arc::new(root)); 112 self.data_mut().libs.push(Arc::new(root));
97 } 113 }
98 fn data_mut(&mut self) -> &mut WorldData { 114 fn data_mut(&mut self) -> &mut WorldData {
99 Arc::make_mut(&mut self.data) 115 &mut self.data
100 } 116 }
101} 117}
102 118
103pub(crate) struct AnalysisImpl { 119pub(crate) struct AnalysisImpl {
104 needs_reindex: AtomicBool, 120 data: WorldData,
105 data: Arc<WorldData>,
106} 121}
107 122
108impl fmt::Debug for AnalysisImpl { 123impl fmt::Debug for AnalysisImpl {
109 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 124 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110 (&*self.data).fmt(f) 125 self.data.fmt(f)
111 }
112}
113
114impl Clone for AnalysisImpl {
115 fn clone(&self) -> AnalysisImpl {
116 AnalysisImpl {
117 needs_reindex: AtomicBool::new(self.needs_reindex.load(SeqCst)),
118 data: Arc::clone(&self.data),
119 }
120 } 126 }
121} 127}
122 128
123impl AnalysisImpl { 129impl AnalysisImpl {
124 fn root(&self, file_id: FileId) -> &SourceRoot { 130 fn root(&self, file_id: FileId) -> &SourceRoot {
125 if self.data.root.contains(file_id) { 131 if self.data.root.contains(file_id) {
126 return &*self.data.root; 132 return &self.data.root;
127 } 133 }
128 &**self.data.libs.iter().find(|it| it.contains(file_id)).unwrap() 134 &**self.data.libs.iter().find(|it| it.contains(file_id)).unwrap()
129 } 135 }
@@ -386,9 +392,8 @@ impl AnalysisImpl {
386 392
387#[derive(Default, Clone, Debug)] 393#[derive(Default, Clone, Debug)]
388struct WorldData { 394struct WorldData {
389 file_resolver: FileResolverImp,
390 crate_graph: CrateGraph, 395 crate_graph: CrateGraph,
391 root: Arc<WritableSourceRoot>, 396 root: WritableSourceRoot,
392 libs: Vec<Arc<ReadonlySourceRoot>>, 397 libs: Vec<Arc<ReadonlySourceRoot>>,
393} 398}
394 399
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 86c66236c..d8b355a81 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -19,7 +19,6 @@ mod imp;
19mod job; 19mod job;
20mod roots; 20mod roots;
21mod db; 21mod db;
22mod queries;
23mod descriptors; 22mod descriptors;
24 23
25use std::{ 24use std::{
@@ -162,7 +161,7 @@ impl Query {
162 } 161 }
163} 162}
164 163
165#[derive(Clone, Debug)] 164#[derive(Debug)]
166pub struct Analysis { 165pub struct Analysis {
167 imp: AnalysisImpl 166 imp: AnalysisImpl
168} 167}
@@ -258,3 +257,9 @@ impl LibraryData {
258 LibraryData { root } 257 LibraryData { root }
259 } 258 }
260} 259}
260
261#[test]
262fn analysis_is_send() {
263 fn is_send<T: Send>() {}
264 is_send::<Analysis>();
265}
diff --git a/crates/ra_analysis/src/module_map.rs b/crates/ra_analysis/src/module_map.rs
index c77c5cec6..c1799e3d4 100644
--- a/crates/ra_analysis/src/module_map.rs
+++ b/crates/ra_analysis/src/module_map.rs
@@ -1,157 +1,34 @@
1use std::sync::Arc; 1use std::sync::Arc;
2use crate::{ 2use crate::{
3 FileId, 3 FileId,
4 db::{ 4 db::{SyntaxDatabase},
5 Query, QueryRegistry, QueryCtx,
6 file_set
7 },
8 queries::file_syntax,
9 descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, 5 descriptors::{ModuleDescriptor, ModuleTreeDescriptor},
10}; 6};
11 7
12pub(crate) fn register_queries(reg: &mut QueryRegistry) { 8salsa::query_group! {
13 reg.add(MODULE_DESCR, "MODULE_DESCR"); 9 pub(crate) trait ModulesDatabase: SyntaxDatabase {
14 reg.add(MODULE_TREE, "MODULE_TREE"); 10 fn module_tree(key: ()) -> Arc<ModuleTreeDescriptor> {
15} 11 type ModuleTreeQuery;
16
17pub(crate) fn module_tree(ctx: QueryCtx) -> Arc<ModuleTreeDescriptor> {
18 ctx.get(MODULE_TREE, ())
19}
20
21const MODULE_DESCR: Query<FileId, ModuleDescriptor> = Query(30, |ctx, &file_id| {
22 let file = file_syntax(ctx, file_id);
23 ModuleDescriptor::new(file.ast())
24});
25
26const MODULE_TREE: Query<(), ModuleTreeDescriptor> = Query(31, |ctx, _| {
27 let file_set = file_set(ctx);
28 let mut files = Vec::new();
29 for &file_id in file_set.0.iter() {
30 let module_descr = ctx.get(MODULE_DESCR, file_id);
31 files.push((file_id, module_descr));
32 }
33 ModuleTreeDescriptor::new(files.iter().map(|(file_id, descr)| (*file_id, &**descr)), &file_set.1)
34});
35
36#[cfg(test)]
37mod tests {
38 use std::collections::HashMap;
39 use im;
40 use relative_path::{RelativePath, RelativePathBuf};
41 use crate::{
42 db::{Db},
43 imp::FileResolverImp,
44 FileId, FileResolver,
45 };
46 use super::*;
47
48 #[derive(Debug)]
49 struct FileMap(im::HashMap<FileId, RelativePathBuf>);
50
51 impl FileResolver for FileMap {
52 fn file_stem(&self, file_id: FileId) -> String {
53 self.0[&file_id].file_stem().unwrap().to_string()
54 } 12 }
55 fn resolve(&self, file_id: FileId, rel: &RelativePath) -> Option<FileId> { 13 fn module_descriptor(file_id: FileId) -> Arc<ModuleDescriptor> {
56 let path = self.0[&file_id].join(rel).normalize(); 14 type ModuleDescriptorQuery;
57 self.0.iter()
58 .filter_map(|&(id, ref p)| Some(id).filter(|_| p == &path))
59 .next()
60 } 15 }
61 } 16 }
17}
62 18
63 struct Fixture {
64 next_file_id: u32,
65 fm: im::HashMap<FileId, RelativePathBuf>,
66 db: Db,
67 }
68
69 impl Fixture {
70 fn new() -> Fixture {
71 Fixture {
72 next_file_id: 1,
73 fm: im::HashMap::new(),
74 db: Db::new(),
75 }
76 }
77 fn add_file(&mut self, path: &str, text: &str) -> FileId {
78 assert!(path.starts_with("/"));
79 let file_id = FileId(self.next_file_id);
80 self.next_file_id += 1;
81 self.fm.insert(file_id, RelativePathBuf::from(&path[1..]));
82 let mut new_state = self.db.state().clone();
83 new_state.file_map.insert(file_id, Arc::new(text.to_string()));
84 new_state.file_resolver = FileResolverImp::new(
85 Arc::new(FileMap(self.fm.clone()))
86 );
87 self.db = self.db.with_changes(new_state, &[file_id], true);
88 file_id
89 }
90 fn remove_file(&mut self, file_id: FileId) {
91 self.fm.remove(&file_id);
92 let mut new_state = self.db.state().clone();
93 new_state.file_map.remove(&file_id);
94 new_state.file_resolver = FileResolverImp::new(
95 Arc::new(FileMap(self.fm.clone()))
96 );
97 self.db = self.db.with_changes(new_state, &[file_id], true);
98 }
99 fn change_file(&mut self, file_id: FileId, new_text: &str) {
100 let mut new_state = self.db.state().clone();
101 new_state.file_map.insert(file_id, Arc::new(new_text.to_string()));
102 self.db = self.db.with_changes(new_state, &[file_id], false);
103 }
104 fn check_parent_modules(
105 &self,
106 file_id: FileId,
107 expected: &[FileId],
108 queries: &[(&'static str, u64)]
109 ) {
110 let (tree, events) = self.db.trace_query(|ctx| module_tree(ctx));
111 let actual = tree.parent_modules(file_id)
112 .into_iter()
113 .map(|link| link.owner(&tree))
114 .collect::<Vec<_>>();
115 assert_eq!(actual.as_slice(), expected);
116 let mut counts = HashMap::new();
117 events.into_iter()
118 .for_each(|event| *counts.entry(event).or_insert(0) += 1);
119 for &(query_id, expected_count) in queries.iter() {
120 let actual_count = *counts.get(&query_id).unwrap_or(&0);
121 assert_eq!(
122 actual_count,
123 expected_count,
124 "counts for {} differ",
125 query_id,
126 )
127 }
128
129 }
130 }
131
132 #[test]
133 fn test_parent_module() {
134 let mut f = Fixture::new();
135 let foo = f.add_file("/foo.rs", "");
136 f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]);
137
138 let lib = f.add_file("/lib.rs", "mod foo;");
139 f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]);
140 f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 0)]);
141
142 f.change_file(lib, "");
143 f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]);
144
145 f.change_file(lib, "mod foo;");
146 f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]);
147
148 f.change_file(lib, "mod bar;");
149 f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]);
150 19
151 f.change_file(lib, "mod foo;"); 20fn module_descriptor(db: &impl ModulesDatabase, file_id: FileId) -> Arc<ModuleDescriptor> {
152 f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); 21 let file = db.file_syntax(file_id);
22 Arc::new(ModuleDescriptor::new(file.ast()))
23}
153 24
154 f.remove_file(lib); 25fn module_tree(db: &impl ModulesDatabase, (): ()) -> Arc<ModuleTreeDescriptor> {
155 f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 0)]); 26 let file_set = db.file_set(());
27 let mut files = Vec::new();
28 for &file_id in file_set.files.iter() {
29 let module_descr = db.module_descriptor(file_id);
30 files.push((file_id, module_descr));
156 } 31 }
32 let res = ModuleTreeDescriptor::new(files.iter().map(|(file_id, descr)| (*file_id, &**descr)), &file_set.resolver);
33 Arc::new(res)
157} 34}
diff --git a/crates/ra_analysis/src/queries.rs b/crates/ra_analysis/src/queries.rs
deleted file mode 100644
index 613bf1e61..000000000
--- a/crates/ra_analysis/src/queries.rs
+++ /dev/null
@@ -1,39 +0,0 @@
1use std::sync::Arc;
2use ra_syntax::File;
3use ra_editor::LineIndex;
4use crate::{
5 FileId,
6 db::{Query, QueryCtx, QueryRegistry},
7 symbol_index::SymbolIndex,
8};
9
10pub(crate) use crate::db::{file_text, file_set};
11
12pub(crate) fn file_syntax(ctx: QueryCtx, file_id: FileId) -> File {
13 (&*ctx.get(FILE_SYNTAX, file_id)).clone()
14}
15pub(crate) fn file_lines(ctx: QueryCtx, file_id: FileId) -> Arc<LineIndex> {
16 ctx.get(FILE_LINES, file_id)
17}
18pub(crate) fn file_symbols(ctx: QueryCtx, file_id: FileId) -> Arc<SymbolIndex> {
19 ctx.get(FILE_SYMBOLS, file_id)
20}
21
22const FILE_SYNTAX: Query<FileId, File> = Query(16, |ctx, file_id: &FileId| {
23 let text = file_text(ctx, *file_id);
24 File::parse(&*text)
25});
26const FILE_LINES: Query<FileId, LineIndex> = Query(17, |ctx, file_id: &FileId| {
27 let text = file_text(ctx, *file_id);
28 LineIndex::new(&*text)
29});
30const FILE_SYMBOLS: Query<FileId, SymbolIndex> = Query(18, |ctx, file_id: &FileId| {
31 let syntax = file_syntax(ctx, *file_id);
32 SymbolIndex::for_file(*file_id, syntax)
33});
34
35pub(crate) fn register_queries(reg: &mut QueryRegistry) {
36 reg.add(FILE_SYNTAX, "FILE_SYNTAX");
37 reg.add(FILE_LINES, "FILE_LINES");
38 reg.add(FILE_SYMBOLS, "FILE_SYMBOLS");
39}
diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs
index 208acc4c2..76bcecd38 100644
--- a/crates/ra_analysis/src/roots.rs
+++ b/crates/ra_analysis/src/roots.rs
@@ -5,7 +5,8 @@ use std::{
5 5
6use once_cell::sync::OnceCell; 6use once_cell::sync::OnceCell;
7use rayon::prelude::*; 7use rayon::prelude::*;
8use rustc_hash::FxHashMap; 8use salsa::Database;
9use rustc_hash::{FxHashMap, FxHashSet};
9use ra_editor::LineIndex; 10use ra_editor::LineIndex;
10use ra_syntax::File; 11use ra_syntax::File;
11 12
@@ -14,7 +15,8 @@ use crate::{
14 imp::FileResolverImp, 15 imp::FileResolverImp,
15 symbol_index::SymbolIndex, 16 symbol_index::SymbolIndex,
16 descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, 17 descriptors::{ModuleDescriptor, ModuleTreeDescriptor},
17 db::Db, 18 db::{self, FilesDatabase, SyntaxDatabase},
19 module_map::ModulesDatabase,
18}; 20};
19 21
20pub(crate) trait SourceRoot { 22pub(crate) trait SourceRoot {
@@ -25,62 +27,68 @@ pub(crate) trait SourceRoot {
25 fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>); 27 fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>);
26} 28}
27 29
28#[derive(Default, Debug)] 30#[derive(Default, Debug, Clone)]
29pub(crate) struct WritableSourceRoot { 31pub(crate) struct WritableSourceRoot {
30 db: Db, 32 db: db::RootDatabase,
31} 33}
32 34
33impl WritableSourceRoot { 35impl WritableSourceRoot {
34 pub fn apply_changes( 36 pub fn apply_changes(
35 &self, 37 &mut self,
36 changes: &mut dyn Iterator<Item=(FileId, Option<String>)>, 38 changes: &mut dyn Iterator<Item=(FileId, Option<String>)>,
37 file_resolver: Option<FileResolverImp>, 39 file_resolver: Option<FileResolverImp>,
38 ) -> WritableSourceRoot { 40 ) {
39 let resolver_changed = file_resolver.is_some(); 41 let mut changed = FxHashSet::default();
40 let mut changed_files = Vec::new(); 42 let mut removed = FxHashSet::default();
41 let mut new_state = self.db.state().clone();
42
43 for (file_id, text) in changes { 43 for (file_id, text) in changes {
44 changed_files.push(file_id);
45 match text { 44 match text {
46 Some(text) => {
47 new_state.file_map.insert(file_id, Arc::new(text));
48 },
49 None => { 45 None => {
50 new_state.file_map.remove(&file_id); 46 removed.insert(file_id);
47 }
48 Some(text) => {
49 self.db.query(db::FileTextQuery)
50 .set(file_id, Arc::new(text));
51 changed.insert(file_id);
51 } 52 }
52 } 53 }
53 } 54 }
54 if let Some(file_resolver) = file_resolver { 55 let file_set = self.db.file_set(());
55 new_state.file_resolver = file_resolver 56 let mut files: FxHashSet<FileId> = file_set
56 } 57 .files
57 WritableSourceRoot { 58 .clone();
58 db: self.db.with_changes(new_state, &changed_files, resolver_changed) 59 for file_id in removed {
60 files.remove(&file_id);
59 } 61 }
62 files.extend(changed);
63 let resolver = file_resolver.unwrap_or_else(|| file_set.resolver.clone());
64 self.db.query(db::FileSetQuery)
65 .set((), Arc::new(db::FileSet { files, resolver }));
60 } 66 }
61} 67}
62 68
63impl SourceRoot for WritableSourceRoot { 69impl SourceRoot for WritableSourceRoot {
64 fn module_tree(&self) -> Arc<ModuleTreeDescriptor> { 70 fn module_tree(&self) -> Arc<ModuleTreeDescriptor> {
65 self.db.make_query(crate::module_map::module_tree) 71 self.db.module_tree(())
66 } 72 }
67
68 fn contains(&self, file_id: FileId) -> bool { 73 fn contains(&self, file_id: FileId) -> bool {
69 self.db.state().file_map.contains_key(&file_id) 74 self.db.file_set(())
75 .files
76 .contains(&file_id)
70 } 77 }
71 fn lines(&self, file_id: FileId) -> Arc<LineIndex> { 78 fn lines(&self, file_id: FileId) -> Arc<LineIndex> {
72 self.db.make_query(|ctx| crate::queries::file_lines(ctx, file_id)) 79 self.db.file_lines(file_id)
73 } 80 }
74 fn syntax(&self, file_id: FileId) -> File { 81 fn syntax(&self, file_id: FileId) -> File {
75 self.db.make_query(|ctx| crate::queries::file_syntax(ctx, file_id)) 82 self.db.file_syntax(file_id)
76 } 83 }
77 fn symbols<'a>(&'a self, acc: &mut Vec<Arc<SymbolIndex>>) { 84 fn symbols<'a>(&'a self, acc: &mut Vec<Arc<SymbolIndex>>) {
78 self.db.make_query(|ctx| { 85 let db = &self.db;
79 let file_set = crate::queries::file_set(ctx); 86 let symbols = db.file_set(());
80 let syms = file_set.0.iter() 87 let symbols = symbols
81 .map(|file_id| crate::queries::file_symbols(ctx, *file_id)); 88 .files
82 acc.extend(syms); 89 .iter()
83 }); 90 .map(|&file_id| db.file_symbols(file_id));
91 acc.extend(symbols);
84 } 92 }
85} 93}
86 94
diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs
index e5d83d365..54672fde4 100644
--- a/crates/ra_analysis/src/symbol_index.rs
+++ b/crates/ra_analysis/src/symbol_index.rs
@@ -17,6 +17,15 @@ pub(crate) struct SymbolIndex {
17 map: fst::Map, 17 map: fst::Map,
18} 18}
19 19
20impl PartialEq for SymbolIndex {
21 fn eq(&self, other: &SymbolIndex) -> bool {
22 self.symbols == other.symbols
23 }
24}
25
26impl Eq for SymbolIndex {
27}
28
20impl Hash for SymbolIndex { 29impl Hash for SymbolIndex {
21 fn hash<H: Hasher>(&self, hasher: &mut H) { 30 fn hash<H: Hasher>(&self, hasher: &mut H) {
22 self.symbols.hash(hasher) 31 self.symbols.hash(hasher)
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs
index 755640fb4..2d3679fa9 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/tests.rs
@@ -238,4 +238,4 @@ fn bar() {
238 assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]); 238 assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]);
239 assert_eq!(desc.ret_type, None); 239 assert_eq!(desc.ret_type, None);
240 assert_eq!(param, Some(1)); 240 assert_eq!(param, Some(1));
241} \ No newline at end of file 241}
diff --git a/crates/ra_editor/src/line_index.rs b/crates/ra_editor/src/line_index.rs
index 6ccfdbd83..95d64b8a8 100644
--- a/crates/ra_editor/src/line_index.rs
+++ b/crates/ra_editor/src/line_index.rs
@@ -1,7 +1,7 @@
1use superslice::Ext; 1use superslice::Ext;
2use crate::TextUnit; 2use crate::TextUnit;
3 3
4#[derive(Clone, Debug, Hash)] 4#[derive(Clone, Debug, Hash, PartialEq, Eq)]
5pub struct LineIndex { 5pub struct LineIndex {
6 newlines: Vec<TextUnit>, 6 newlines: Vec<TextUnit>,
7} 7}
diff --git a/crates/ra_editor/src/symbols.rs b/crates/ra_editor/src/symbols.rs
index 6211ed547..d9e4b2df7 100644
--- a/crates/ra_editor/src/symbols.rs
+++ b/crates/ra_editor/src/symbols.rs
@@ -17,7 +17,7 @@ pub struct StructureNode {
17 pub kind: SyntaxKind, 17 pub kind: SyntaxKind,
18} 18}
19 19
20#[derive(Debug, Clone, Hash)] 20#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21pub struct FileSymbol { 21pub struct FileSymbol {
22 pub name: SmolStr, 22 pub name: SmolStr,
23 pub node_range: TextRange, 23 pub node_range: TextRange,
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 1fe78f3d0..5acb39b60 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -478,7 +478,7 @@ pub fn handle_code_action(
478} 478}
479 479
480pub fn publish_diagnostics( 480pub fn publish_diagnostics(
481 world: ServerWorld, 481 world: &ServerWorld,
482 file_id: FileId, 482 file_id: FileId,
483) -> Result<req::PublishDiagnosticsParams> { 483) -> Result<req::PublishDiagnosticsParams> {
484 let uri = world.file_id_to_uri(file_id)?; 484 let uri = world.file_id_to_uri(file_id)?;
@@ -497,7 +497,7 @@ pub fn publish_diagnostics(
497} 497}
498 498
499pub fn publish_decorations( 499pub fn publish_decorations(
500 world: ServerWorld, 500 world: &ServerWorld,
501 file_id: FileId, 501 file_id: FileId,
502) -> Result<req::PublishDecorationsParams> { 502) -> Result<req::PublishDecorationsParams> {
503 let uri = world.file_id_to_uri(file_id)?; 503 let uri = world.file_id_to_uri(file_id)?;
diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs
index 773501efe..cf2477cb5 100644
--- a/crates/ra_lsp_server/src/main_loop/mod.rs
+++ b/crates/ra_lsp_server/src/main_loop/mod.rs
@@ -391,7 +391,7 @@ fn update_file_notifications_on_threadpool(
391) { 391) {
392 pool.spawn(move || { 392 pool.spawn(move || {
393 for file_id in subscriptions { 393 for file_id in subscriptions {
394 match handlers::publish_diagnostics(world.clone(), file_id) { 394 match handlers::publish_diagnostics(&world, file_id) {
395 Err(e) => { 395 Err(e) => {
396 error!("failed to compute diagnostics: {:?}", e) 396 error!("failed to compute diagnostics: {:?}", e)
397 } 397 }
@@ -400,7 +400,7 @@ fn update_file_notifications_on_threadpool(
400 sender.send(Task::Notify(not)); 400 sender.send(Task::Notify(not));
401 } 401 }
402 } 402 }
403 match handlers::publish_decorations(world.clone(), file_id) { 403 match handlers::publish_decorations(&world, file_id) {
404 Err(e) => { 404 Err(e) => {
405 error!("failed to compute decorations: {:?}", e) 405 error!("failed to compute decorations: {:?}", e)
406 } 406 }
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index c931afa02..9b3013ae8 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -23,7 +23,6 @@ pub struct ServerWorldState {
23 pub mem_map: FxHashMap<FileId, Option<String>>, 23 pub mem_map: FxHashMap<FileId, Option<String>>,
24} 24}
25 25
26#[derive(Clone)]
27pub struct ServerWorld { 26pub struct ServerWorld {
28 pub workspaces: Arc<Vec<CargoWorkspace>>, 27 pub workspaces: Arc<Vec<CargoWorkspace>>,
29 pub analysis: Analysis, 28 pub analysis: Analysis,
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 5bb54aba1..7eba5ee61 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -59,7 +59,7 @@ use crate::{
59 yellow::{GreenNode}, 59 yellow::{GreenNode},
60}; 60};
61 61
62#[derive(Clone, Debug, Hash)] 62#[derive(Clone, Debug, Hash, PartialEq, Eq)]
63pub struct File { 63pub struct File {
64 root: SyntaxNode 64 root: SyntaxNode
65} 65}
diff --git a/crates/salsa/Cargo.toml b/crates/salsa/Cargo.toml
deleted file mode 100644
index 9eb83234f..000000000
--- a/crates/salsa/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
1[package]
2name = "salsa"
3version = "0.1.0"
4authors = ["Aleksey Kladov <[email protected]>"]
5
6[dependencies]
7parking_lot = "0.6.3"
8im = "12.0.0"
diff --git a/crates/salsa/src/lib.rs b/crates/salsa/src/lib.rs
deleted file mode 100644
index 35deed374..000000000
--- a/crates/salsa/src/lib.rs
+++ /dev/null
@@ -1,293 +0,0 @@
1extern crate im;
2extern crate parking_lot;
3
4use std::{
5 sync::Arc,
6 collections::{HashSet, HashMap},
7 cell::RefCell,
8};
9use parking_lot::Mutex;
10
11pub type GroundQueryFn<T, D> = Box<Fn(&T, &D) -> (D, OutputFingerprint) + Send + Sync + 'static>;
12pub type QueryFn<T, D> = Box<Fn(&QueryCtx<T, D>, &D) -> (D, OutputFingerprint) + Send + Sync + 'static>;
13
14#[derive(Debug)]
15pub struct Db<T, D> {
16 db: Arc<DbState<T, D>>,
17 query_config: Arc<QueryConfig<T, D>>,
18}
19
20pub struct QueryConfig<T, D> {
21 ground_fn: HashMap<QueryTypeId, GroundQueryFn<T, D>>,
22 query_fn: HashMap<QueryTypeId, QueryFn<T, D>>,
23}
24
25impl<T, D> ::std::fmt::Debug for QueryConfig<T, D> {
26 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
27 ::std::fmt::Display::fmt("QueryConfig { ... }", f)
28 }
29}
30
31#[derive(Debug)]
32struct DbState<T, D> {
33 ground_data: T,
34 gen: Gen,
35 graph: Mutex<im::HashMap<QueryId, (Gen, Arc<QueryRecord<D>>)>>,
36}
37
38#[derive(Debug)]
39struct QueryRecord<D> {
40 params: D,
41 output: D,
42 output_fingerprint: OutputFingerprint,
43 deps: Vec<(QueryId, OutputFingerprint)>,
44}
45
46impl<T, D> DbState<T, D> {
47 fn record(
48 &self,
49 query_id: QueryId,
50 params: D,
51 output: D,
52 output_fingerprint: OutputFingerprint,
53 deps: Vec<(QueryId, OutputFingerprint)>,
54 ) {
55 let gen = self.gen;
56 let record = QueryRecord {
57 params,
58 output,
59 output_fingerprint,
60 deps,
61 };
62 self.graph.lock().insert(query_id, (gen, Arc::new(record)));
63 }
64}
65
66impl<T, D> QueryConfig<T, D> {
67 pub fn new() -> Self {
68 QueryConfig {
69 ground_fn: HashMap::new(),
70 query_fn: HashMap::new(),
71 }
72 }
73 pub fn with_ground_query(
74 mut self,
75 query_type: QueryTypeId,
76 query_fn: GroundQueryFn<T, D>
77 ) -> Self {
78 let prev = self.ground_fn.insert(query_type, query_fn);
79 assert!(prev.is_none());
80 self
81 }
82 pub fn with_query(
83 mut self,
84 query_type: QueryTypeId,
85 query_fn: QueryFn<T, D>,
86 ) -> Self {
87 let prev = self.query_fn.insert(query_type, query_fn);
88 assert!(prev.is_none());
89 self
90 }
91}
92
93pub struct QueryCtx<T, D> {
94 db: Arc<DbState<T, D>>,
95 query_config: Arc<QueryConfig<T, D>>,
96 stack: RefCell<Vec<Vec<(QueryId, OutputFingerprint)>>>,
97 executed: RefCell<Vec<QueryTypeId>>,
98}
99
100impl<T, D> QueryCtx<T, D>
101where
102 D: Clone
103{
104 fn new(db: &Db<T, D>) -> QueryCtx<T, D> {
105 QueryCtx {
106 db: Arc::clone(&db.db),
107 query_config: Arc::clone(&db.query_config),
108 stack: RefCell::new(vec![Vec::new()]),
109 executed: RefCell::new(Vec::new()),
110 }
111 }
112 pub fn get(
113 &self,
114 query_id: QueryId,
115 params: D,
116 ) -> D {
117 let (res, output_fingerprint) = self.get_inner(query_id, params);
118 self.record_dep(query_id, output_fingerprint);
119 res
120 }
121 pub fn trace(&self) -> Vec<QueryTypeId> {
122 ::std::mem::replace(&mut *self.executed.borrow_mut(), Vec::new())
123 }
124
125 fn get_inner(
126 &self,
127 query_id: QueryId,
128 params: D,
129 ) -> (D, OutputFingerprint) {
130 let (gen, record) = {
131 let guard = self.db.graph.lock();
132 match guard.get(&query_id).map(|it| it.clone()){
133 None => {
134 drop(guard);
135 return self.force(query_id, params);
136 },
137 Some(it) => it,
138 }
139 };
140 if gen == self.db.gen {
141 return (record.output.clone(), record.output_fingerprint)
142 }
143 if self.query_config.ground_fn.contains_key(&query_id.0) {
144 let (invalidated, record) = {
145 let guard = self.db.graph.lock();
146 let (gen, ref record) = guard[&query_id];
147 (gen == INVALIDATED, record.clone())
148 };
149 if invalidated {
150 return self.force(query_id, params);
151 } else {
152 return (record.output.clone(), record.output_fingerprint);
153 }
154 }
155 for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() {
156 let dep_params: D = {
157 let guard = self.db.graph.lock();
158 guard[&dep_query_id]
159 .1
160 .params
161 .clone()
162 };
163 if prev_fingerprint != self.get_inner(dep_query_id, dep_params).1 {
164 return self.force(query_id, params)
165 }
166 }
167 let gen = self.db.gen;
168 {
169 let mut guard = self.db.graph.lock();
170 guard[&query_id].0 = gen;
171 }
172 (record.output.clone(), record.output_fingerprint)
173 }
174 fn force(
175 &self,
176 query_id: QueryId,
177 params: D,
178 ) -> (D, OutputFingerprint) {
179 self.executed.borrow_mut().push(query_id.0);
180 self.stack.borrow_mut().push(Vec::new());
181
182 let (res, output_fingerprint) = if let Some(f) = self.query_config.ground_fn.get(&query_id.0) {
183 f(&self.db.ground_data, &params)
184 } else if let Some(f) = self.query_config.query_fn.get(&query_id.0) {
185 f(self, &params)
186 } else {
187 panic!("unknown query type: {:?}", query_id.0);
188 };
189
190 let res: D = res.into();
191
192 let deps = self.stack.borrow_mut().pop().unwrap();
193 self.db.record(query_id, params, res.clone(), output_fingerprint, deps);
194 (res, output_fingerprint)
195 }
196 fn record_dep(
197 &self,
198 query_id: QueryId,
199 output_fingerprint: OutputFingerprint,
200 ) -> () {
201 let mut stack = self.stack.borrow_mut();
202 let deps = stack.last_mut().unwrap();
203 deps.push((query_id, output_fingerprint))
204 }
205}
206
207pub struct Invalidations {
208 types: HashSet<QueryTypeId>,
209 ids: Vec<QueryId>,
210}
211
212impl Invalidations {
213 pub fn new() -> Invalidations {
214 Invalidations {
215 types: HashSet::new(),
216 ids: Vec::new(),
217 }
218 }
219 pub fn invalidate(
220 &mut self,
221 query_type: QueryTypeId,
222 params: impl Iterator<Item=InputFingerprint>,
223 ) {
224 self.types.insert(query_type);
225 self.ids.extend(params.map(|it| QueryId(query_type, it)))
226 }
227}
228
229impl<T, D> Db<T, D>
230where
231 D: Clone
232{
233 pub fn new(query_config: QueryConfig<T, D>, ground_data: T) -> Db<T, D> {
234 Db {
235 db: Arc::new(DbState { ground_data, gen: Gen(0), graph: Default::default() }),
236 query_config: Arc::new(query_config),
237 }
238 }
239 pub fn ground_data(&self) -> &T {
240 &self.db.ground_data
241 }
242 pub fn with_ground_data(
243 &self,
244 ground_data: T,
245 invalidations: Invalidations,
246 ) -> Db<T, D> {
247 for id in self.query_config.ground_fn.keys() {
248 assert!(
249 invalidations.types.contains(id),
250 "all ground queries must be invalidated"
251 );
252 }
253
254 let gen = Gen(self.db.gen.0 + 1);
255 let mut graph = self.db.graph.lock().clone();
256 for id in invalidations.ids {
257 if let Some((gen, _)) = graph.get_mut(&id) {
258 *gen = INVALIDATED;
259 }
260 }
261 let graph = Mutex::new(graph);
262 Db {
263 db: Arc::new(DbState { ground_data, gen, graph }),
264 query_config: Arc::clone(&self.query_config)
265 }
266 }
267 pub fn query_ctx(&self) -> QueryCtx<T, D> {
268 QueryCtx::new(self)
269 }
270 pub fn get(
271 &self,
272 query_id: QueryId,
273 params: D,
274 ) -> (D, Vec<QueryTypeId>) {
275 let ctx = self.query_ctx();
276 let res = ctx.get(query_id, params.into());
277 let executed = ::std::mem::replace(&mut *ctx.executed.borrow_mut(), Vec::new());
278 (res, executed)
279 }
280}
281
282#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
283struct Gen(u64);
284const INVALIDATED: Gen = Gen(!0);
285#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
286pub struct InputFingerprint(pub u64);
287#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
288pub struct OutputFingerprint(pub u64);
289#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
290pub struct QueryTypeId(pub u16);
291#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
292pub struct QueryId(pub QueryTypeId, pub InputFingerprint);
293
diff --git a/crates/salsa/tests/integration.rs b/crates/salsa/tests/integration.rs
deleted file mode 100644
index aed9219be..000000000
--- a/crates/salsa/tests/integration.rs
+++ /dev/null
@@ -1,170 +0,0 @@
1extern crate salsa;
2use std::{
3 iter::once,
4 sync::Arc,
5 collections::hash_map::{HashMap, DefaultHasher},
6 any::Any,
7 hash::{Hash, Hasher},
8};
9
10type State = HashMap<u32, String>;
11type Data = Arc<Any + Send + Sync + 'static>;
12const GET_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(1);
13const GET_FILES: salsa::QueryTypeId = salsa::QueryTypeId(2);
14const FILE_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(3);
15const TOTAL_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(4);
16
17fn mk_ground_query<T, R>(
18 state: &State,
19 params: &Data,
20 f: fn(&State, &T) -> R,
21) -> (Data, salsa::OutputFingerprint)
22where
23 T: 'static,
24 R: Hash + Send + Sync + 'static,
25{
26 let params = params.downcast_ref().unwrap();
27 let result = f(state, params);
28 let fingerprint = o_print(&result);
29 (Arc::new(result), fingerprint)
30}
31
32fn get<T, R>(db: &salsa::Db<State, Data>, query_type: salsa::QueryTypeId, param: T) -> (Arc<R>, Vec<salsa::QueryTypeId>)
33where
34 T: Hash + Send + Sync + 'static,
35 R: Send + Sync + 'static,
36{
37 let i_print = i_print(&param);
38 let param = Arc::new(param);
39 let (res, trace) = db.get(salsa::QueryId(query_type, i_print), param);
40 (res.downcast().unwrap(), trace)
41}
42
43struct QueryCtx<'a>(&'a salsa::QueryCtx<State, Data>);
44
45impl<'a> QueryCtx<'a> {
46 fn get_text(&self, id: u32) -> Arc<String> {
47 let i_print = i_print(&id);
48 let text = self.0.get(salsa::QueryId(GET_TEXT, i_print), Arc::new(id));
49 text.downcast().unwrap()
50 }
51 fn get_files(&self) -> Arc<Vec<u32>> {
52 let i_print = i_print(&());
53 let files = self.0.get(salsa::QueryId(GET_FILES, i_print), Arc::new(()));
54 let res = files.downcast().unwrap();
55 res
56 }
57 fn get_n_lines(&self, id: u32) -> usize {
58 let i_print = i_print(&id);
59 let n_lines = self.0.get(salsa::QueryId(FILE_NEWLINES, i_print), Arc::new(id));
60 *n_lines.downcast().unwrap()
61 }
62}
63
64fn mk_query<T, R>(
65 query_ctx: &salsa::QueryCtx<State, Data>,
66 params: &Data,
67 f: fn(QueryCtx, &T) -> R,
68) -> (Data, salsa::OutputFingerprint)
69where
70 T: 'static,
71 R: Hash + Send + Sync + 'static,
72{
73 let params: &T = params.downcast_ref().unwrap();
74 let query_ctx = QueryCtx(query_ctx);
75 let result = f(query_ctx, params);
76 let fingerprint = o_print(&result);
77 (Arc::new(result), fingerprint)
78}
79
80fn mk_queries() -> salsa::QueryConfig<State, Data> {
81 salsa::QueryConfig::<State, Data>::new()
82 .with_ground_query(GET_TEXT, Box::new(|state, id| {
83 mk_ground_query::<u32, String>(state, id, |state, id| state[id].clone())
84 }))
85 .with_ground_query(GET_FILES, Box::new(|state, id| {
86 mk_ground_query::<(), Vec<u32>>(state, id, |state, &()| state.keys().cloned().collect())
87 }))
88 .with_query(FILE_NEWLINES, Box::new(|query_ctx, id| {
89 mk_query(query_ctx, id, |query_ctx, &id| {
90 let text = query_ctx.get_text(id);
91 text.lines().count()
92 })
93 }))
94 .with_query(TOTAL_NEWLINES, Box::new(|query_ctx, id| {
95 mk_query(query_ctx, id, |query_ctx, &()| {
96 let mut total = 0;
97 for &id in query_ctx.get_files().iter() {
98 total += query_ctx.get_n_lines(id)
99 }
100 total
101 })
102 }))
103}
104
105#[test]
106fn test_number_of_lines() {
107 let mut state = State::new();
108 let db = salsa::Db::new(mk_queries(), state.clone());
109 let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
110 assert_eq!(*newlines, 0);
111 assert_eq!(trace.len(), 2);
112 let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
113 assert_eq!(*newlines, 0);
114 assert_eq!(trace.len(), 0);
115
116 state.insert(1, "hello\nworld".to_string());
117 let mut inv = salsa::Invalidations::new();
118 inv.invalidate(GET_TEXT, once(i_print(&1u32)));
119 inv.invalidate(GET_FILES, once(i_print(&())));
120 let db = db.with_ground_data(state.clone(), inv);
121 let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
122 assert_eq!(*newlines, 2);
123 assert_eq!(trace.len(), 4);
124
125 state.insert(2, "spam\neggs".to_string());
126 let mut inv = salsa::Invalidations::new();
127 inv.invalidate(GET_TEXT, once(i_print(&2u32)));
128 inv.invalidate(GET_FILES, once(i_print(&())));
129 let db = db.with_ground_data(state.clone(), inv);
130 let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
131 assert_eq!(*newlines, 4);
132 assert_eq!(trace.len(), 4);
133
134 let mut invs = vec![];
135 for i in 0..10 {
136 let id = i + 10;
137 invs.push(i_print(&id));
138 state.insert(id, "spam".to_string());
139 }
140 let mut inv = salsa::Invalidations::new();
141 inv.invalidate(GET_TEXT, invs.into_iter());
142 inv.invalidate(GET_FILES, once(i_print(&())));
143 let db = db.with_ground_data(state.clone(), inv);
144 let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
145 assert_eq!(*newlines, 14);
146 assert_eq!(trace.len(), 22);
147
148 state.insert(15, String::new());
149 let mut inv = salsa::Invalidations::new();
150 inv.invalidate(GET_TEXT, once(i_print(&15u32)));
151 inv.invalidate(GET_FILES, once(i_print(&())));
152 let db = db.with_ground_data(state.clone(), inv);
153 let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
154 assert_eq!(*newlines, 13);
155 assert_eq!(trace.len(), 4);
156}
157
158fn o_print<T: Hash>(x: &T) -> salsa::OutputFingerprint {
159 let mut hasher = DefaultHasher::new();
160 x.hash(&mut hasher);
161 let hash = hasher.finish();
162 salsa::OutputFingerprint(hash)
163}
164
165fn i_print<T: Hash>(x: &T) -> salsa::InputFingerprint {
166 let mut hasher = DefaultHasher::new();
167 x.hash(&mut hasher);
168 let hash = hasher.finish();
169 salsa::InputFingerprint(hash)
170}