101: migrate to salsa-rs/salsa r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2018-10-15 20:59:33 +00:00
commit 8c74fd9619
22 changed files with 433 additions and 1065 deletions

298
Cargo.lock generated
View File

@ -14,6 +14,11 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayref"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.4.7"
@ -67,6 +72,20 @@ name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "block-buffer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byte-tools"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.6"
@ -79,9 +98,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -187,6 +206,16 @@ name = "crossbeam-utils"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "derive-new"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "deunicode"
version = "0.4.3"
@ -197,6 +226,14 @@ name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "digest"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "drop_bomb"
version = "0.1.4"
@ -229,12 +266,17 @@ name = "failure_derive"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "flexi_logger"
version = "0.9.2"
@ -277,9 +319,17 @@ dependencies = [
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "generic-array"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -312,13 +362,18 @@ dependencies = [
[[package]]
name = "im"
version = "12.1.0"
version = "12.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "indexmap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "itertools"
version = "0.7.8"
@ -343,11 +398,11 @@ version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -382,6 +437,11 @@ dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "maplit"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "matches"
version = "0.1.8"
@ -418,13 +478,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-derive"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -492,38 +552,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pest"
version = "1.0.6"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pest_derive"
version = "1.0.8"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_generator 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pest_generator"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pest_meta"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.19"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -532,7 +611,7 @@ version = "0.1.0"
dependencies = [
"crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -541,7 +620,7 @@ dependencies = [
"rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"salsa 0.1.0",
"salsa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"test_utils 0.1.0",
]
@ -579,7 +658,7 @@ dependencies = [
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gen_lsp_server 0.1.0",
"im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ra_analysis 0.1.0",
@ -588,10 +667,10 @@ dependencies = [
"rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -629,13 +708,21 @@ dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -712,7 +799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -721,7 +808,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -758,10 +845,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "salsa"
version = "0.1.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -783,7 +875,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -793,30 +885,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.31"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha-1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -837,10 +940,10 @@ dependencies = [
[[package]]
name = "smol_str"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -858,50 +961,32 @@ name = "superslice"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.7"
version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synom"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synstructure"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -918,7 +1003,7 @@ dependencies = [
[[package]]
name = "tera"
version = "0.11.16"
version = "0.11.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -926,11 +1011,11 @@ dependencies = [
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -960,7 +1045,7 @@ name = "text_unit"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -998,7 +1083,7 @@ dependencies = [
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ron 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tera 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)",
"tera 0.11.17 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1007,6 +1092,11 @@ name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-trie"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-util"
version = "0.1.1"
@ -1079,11 +1169,6 @@ name = "unicode-width"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.1.0"
@ -1112,7 +1197,7 @@ name = "url_serde"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1176,12 +1261,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1"
"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"
"checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
"checksum derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "899ec79626c14e00ccc9729b4d750bbe67fe76a8f436824c16e0233bbd9d7daa"
"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
"checksum drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9"
"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2103a4bd3f67bf8b3e89fe0695cd13ac23c9968a2a81f2ccf2d95f1bb4e5a520"
"checksum fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9b0408ab57c1bf7c634b2ac6a165d14f642dc3335a43203090a7f8c78b54577b"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90742b94a13db9b161eeab35f89bc9723634eb72bfd124f3ebb025734fdfef18"
"checksum im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9c7f9bb8aee47fc16d535a705f7867a9fc83bb822e5e1043bb98e77ffeed3c"
"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"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"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a"
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7"
"checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"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"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc"
"checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4"
"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum pest 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c3abb0d36ede865dcc689fd3bee2ff39094eff6e57a814f4a53c3c6108088353"
"checksum pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b76f477146419bc539a63f4ef40e902166cb43b3e51cecc71d9136fd12c567e7"
"checksum pest_generator 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebee4e9680be4fd162e6f3394ae4192a6b60b1e4d17d845e631f0c68d1a3386"
"checksum pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f6d5f6f0e6082578c86af197d780dc38328e3f768cec06aac9bc46d714e8221"
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa"
"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
"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"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
"checksum salsa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8301c563959d6d50fe0a34817f0d9ff08fe12eda7456e01e2bbde1588ea30602"
"checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
"checksum serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "bb47a3d5c84320222f66d7db21157c4a7407755de41798f9b4c1c40593397b1a"
"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
"checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
"checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
"checksum smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "248055d41f4c53f8ee7048e8a578a5190d0cca306630718091e4d481735e44b9"
"checksum smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ed6f19b800d76574926e458d5f8e2dbea86c2b58c08d33a982448f09ac8d0c"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum superslice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50b13d42370e0f5fc62eafdd5c2d20065eaf5458dab215ff3e20e63eea96b30"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)" = "455a6ec9b368f8c479b0ae5494d13b22dc00990d2f00d68c9dc6a2dc4f17f210"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b036b7b35e846707c0e55c2c9441fa47867c0f87fca416921db3261b1d8c741a"
"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum tera 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4f79f17fe555fffe4838a082a63636883ee13022888dc7bdc99edad8e0a411cd"
"checksum tera 0.11.17 (registry+https://github.com/rust-lang/crates.io-index)" = "2829d259c4699fbbe8acb353d231e6da31ff4301c52244413ed29ff6093da412"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc86da66d0b9aa8d359b0ec31b4342c6bc52637eadef05b91b098551a9f8e9"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
"checksum unic-char-property 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce36d3f7ce754afdbccccf8ff0dd0134e50fb44aaae579f96218856e9e5dbd1e"
"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"
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"

View File

@ -15,7 +15,7 @@ fst = "0.3.1"
im = "12.0.0"
ra_syntax = { path = "../ra_syntax" }
ra_editor = { path = "../ra_editor" }
salsa = { path = "../salsa" }
salsa = "0.5.0"
rustc-hash = "1.0"
[dev-dependencies]

View File

@ -0,0 +1,117 @@
use std::{
fmt,
sync::Arc,
hash::{Hash, Hasher},
};
use salsa;
use rustc_hash::FxHashSet;
use ra_syntax::File;
use ra_editor::{LineIndex};
use crate::{
symbol_index::SymbolIndex,
module_map::{ModulesDatabase, ModuleTreeQuery, ModuleDescriptorQuery},
FileId, FileResolverImp,
};
#[derive(Default)]
pub(crate) struct RootDatabase {
runtime: salsa::runtime::Runtime<RootDatabase>,
}
impl fmt::Debug for RootDatabase {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("RootDatabase { ... }")
}
}
impl salsa::Database for RootDatabase {
fn salsa_runtime(&self) -> &salsa::runtime::Runtime<RootDatabase> {
&self.runtime
}
}
impl salsa::ParallelDatabase for RootDatabase {
fn fork(&self) -> Self {
RootDatabase {
runtime: self.runtime.fork(),
}
}
}
impl Clone for RootDatabase {
fn clone(&self) -> RootDatabase {
salsa::ParallelDatabase::fork(self)
}
}
salsa::database_storage! {
pub(crate) struct RootDatabaseStorage for RootDatabase {
impl FilesDatabase {
fn file_text() for FileTextQuery;
fn file_set() for FileSetQuery;
}
impl SyntaxDatabase {
fn file_syntax() for FileSyntaxQuery;
fn file_lines() for FileLinesQuery;
fn file_symbols() for FileSymbolsQuery;
}
impl ModulesDatabase {
fn module_tree() for ModuleTreeQuery;
fn module_descriptor() for ModuleDescriptorQuery;
}
}
}
salsa::query_group! {
pub(crate) trait FilesDatabase: salsa::Database {
fn file_text(file_id: FileId) -> Arc<String> {
type FileTextQuery;
storage input;
}
fn file_set(key: ()) -> Arc<FileSet> {
type FileSetQuery;
storage input;
}
}
}
#[derive(Default, Debug, PartialEq, Eq)]
pub(crate) struct FileSet {
pub(crate) files: FxHashSet<FileId>,
pub(crate) resolver: FileResolverImp,
}
impl Hash for FileSet {
fn hash<H: Hasher>(&self, hasher: &mut H) {
let mut files = self.files.iter().cloned().collect::<Vec<_>>();
files.sort();
files.hash(hasher);
}
}
salsa::query_group! {
pub(crate) trait SyntaxDatabase: FilesDatabase {
fn file_syntax(file_id: FileId) -> File {
type FileSyntaxQuery;
}
fn file_lines(file_id: FileId) -> Arc<LineIndex> {
type FileLinesQuery;
}
fn file_symbols(file_id: FileId) -> Arc<SymbolIndex> {
type FileSymbolsQuery;
}
}
}
fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File {
let text = db.file_text(file_id);
File::parse(&*text)
}
fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> {
let text = db.file_text(file_id);
Arc::new(LineIndex::new(&*text))
}
fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<SymbolIndex> {
let syntax = db.file_syntax(file_id);
Arc::new(SymbolIndex::for_file(file_id, syntax))
}

View File

@ -1,153 +0,0 @@
use std::{
sync::Arc,
any::Any,
hash::{Hash, Hasher},
collections::hash_map::{DefaultHasher},
iter,
};
use rustc_hash::FxHashMap;
use salsa;
use crate::{FileId, imp::FileResolverImp};
use super::{State, Query, QueryCtx};
pub(super) type Data = Arc<Any + Send + Sync + 'static>;
#[derive(Debug)]
pub(super) struct Db {
names: Arc<FxHashMap<salsa::QueryTypeId, &'static str>>,
pub(super) imp: salsa::Db<State, Data>,
}
impl Db {
pub(super) fn new(mut reg: QueryRegistry) -> Db {
let config = reg.config.take().unwrap();
Db {
names: Arc::new(reg.names),
imp: salsa::Db::new(config, State::default())
}
}
pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db {
let names = self.names.clone();
let mut invalidations = salsa::Invalidations::new();
invalidations.invalidate(FILE_TEXT, changed_files.iter().map(hash).map(salsa::InputFingerprint));
if resolver_changed {
invalidations.invalidate(FILE_SET, iter::once(salsa::InputFingerprint(hash(&()))));
} else {
invalidations.invalidate(FILE_SET, iter::empty());
}
let imp = self.imp.with_ground_data(
new_state,
invalidations,
);
Db { names, imp }
}
pub(super) fn extract_trace(&self, ctx: &salsa::QueryCtx<State, Data>) -> Vec<&'static str> {
ctx.trace().into_iter().map(|it| self.names[&it]).collect()
}
}
pub(crate) trait EvalQuery {
type Params;
type Output;
fn query_type(&self) -> salsa::QueryTypeId;
fn f(&self) -> salsa::QueryFn<State, Data>;
fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc<Self::Output>;
}
impl<T, R> EvalQuery for Query<T, R>
where
T: Hash + Send + Sync + 'static,
R: Hash + Send + Sync + 'static,
{
type Params = T;
type Output = R;
fn query_type(&self) -> salsa::QueryTypeId {
salsa::QueryTypeId(self.0)
}
fn f(&self) -> salsa::QueryFn<State, Data> {
let f = self.1;
Box::new(move |ctx, data| {
let ctx = QueryCtx { imp: ctx };
let data: &T = data.downcast_ref().unwrap();
let res = f(ctx, data);
let h = hash(&res);
(Arc::new(res), salsa::OutputFingerprint(h))
})
}
fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc<Self::Output> {
let query_id = salsa::QueryId(
self.query_type(),
salsa::InputFingerprint(hash(&params)),
);
let res = ctx.imp.get(query_id, Arc::new(params));
res.downcast().unwrap()
}
}
pub(super) struct QueryRegistry {
config: Option<salsa::QueryConfig<State, Data>>,
names: FxHashMap<salsa::QueryTypeId, &'static str>,
}
impl QueryRegistry {
pub(super) fn new() -> QueryRegistry {
let mut config = salsa::QueryConfig::<State, Data>::new();
config = config.with_ground_query(
FILE_TEXT, Box::new(|state, params| {
let file_id: &FileId = params.downcast_ref().unwrap();
let res = state.file_map[file_id].clone();
let fingerprint = salsa::OutputFingerprint(hash(&res));
(res, fingerprint)
})
);
config = config.with_ground_query(
FILE_SET, Box::new(|state, _params| {
let file_ids: Vec<FileId> = state.file_map.keys().cloned().collect();
let hash = hash(&file_ids);
let file_resolver = state.file_resolver.clone();
let res = (file_ids, file_resolver);
let fingerprint = salsa::OutputFingerprint(hash);
(Arc::new(res), fingerprint)
})
);
let mut names = FxHashMap::default();
names.insert(FILE_TEXT, "FILE_TEXT");
names.insert(FILE_SET, "FILE_SET");
QueryRegistry { config: Some(config), names }
}
pub(super) fn add<Q: EvalQuery>(&mut self, q: Q, name: &'static str) {
let id = q.query_type();
let prev = self.names.insert(id, name);
assert!(prev.is_none(), "duplicate query: {:?}", id);
let config = self.config.take().unwrap();
let config = config.with_query(id, q.f());
self.config= Some(config);
}
}
fn hash<T: Hash>(x: &T) -> u64 {
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
}
const FILE_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(0);
pub(super) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc<String> {
let query_id = salsa::QueryId(
FILE_TEXT,
salsa::InputFingerprint(hash(&file_id)),
);
let res = ctx.imp.get(query_id, Arc::new(file_id));
res.downcast().unwrap()
}
const FILE_SET: salsa::QueryTypeId = salsa::QueryTypeId(1);
pub(super) fn file_set(ctx: QueryCtx) -> Arc<(Vec<FileId>, FileResolverImp)> {
let query_id = salsa::QueryId(
FILE_SET,
salsa::InputFingerprint(hash(&())),
);
let res = ctx.imp.get(query_id, Arc::new(()));
res.downcast().unwrap()
}

View File

@ -1,85 +0,0 @@
mod imp;
use std::{
sync::Arc,
};
use im;
use salsa;
use crate::{FileId, imp::FileResolverImp};
#[derive(Debug, Default, Clone)]
pub(crate) struct State {
pub(crate) file_map: im::HashMap<FileId, Arc<String>>,
pub(crate) file_resolver: FileResolverImp
}
#[derive(Debug)]
pub(crate) struct Db {
imp: imp::Db,
}
#[derive(Clone, Copy)]
pub(crate) struct QueryCtx<'a> {
imp: &'a salsa::QueryCtx<State, imp::Data>,
}
pub(crate) struct Query<T, R>(pub(crate) u16, pub(crate) fn(QueryCtx, &T) -> R);
pub(crate) struct QueryRegistry {
imp: imp::QueryRegistry,
}
impl Default for Db {
fn default() -> Db {
Db::new()
}
}
impl Db {
pub(crate) fn new() -> Db {
let reg = QueryRegistry::new();
Db { imp: imp::Db::new(reg.imp) }
}
pub(crate) fn state(&self) -> &State {
self.imp.imp.ground_data()
}
pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db {
Db { imp: self.imp.with_changes(new_state, changed_files, resolver_changed) }
}
pub(crate) fn make_query<F: FnOnce(QueryCtx) -> R, R>(&self, f: F) -> R {
let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() };
f(ctx)
}
#[allow(unused)]
pub(crate) fn trace_query<F: FnOnce(QueryCtx) -> R, R>(&self, f: F) -> (R, Vec<&'static str>) {
let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() };
let res = f(ctx);
let trace = self.imp.extract_trace(ctx.imp);
(res, trace)
}
}
impl<'a> QueryCtx<'a> {
pub(crate) fn get<Q: imp::EvalQuery>(&self, q: Q, params: Q::Params) -> Arc<Q::Output> {
q.get(self, params)
}
}
pub(crate) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc<String> {
imp::file_text(ctx, file_id)
}
pub(crate) fn file_set(ctx: QueryCtx) -> Arc<(Vec<FileId>, FileResolverImp)> {
imp::file_set(ctx)
}
impl QueryRegistry {
fn new() -> QueryRegistry {
let mut reg = QueryRegistry { imp: imp::QueryRegistry::new() };
crate::queries::register_queries(&mut reg);
crate::module_map::register_queries(&mut reg);
reg
}
pub(crate) fn add<Q: imp::EvalQuery>(&mut self, q: Q, name: &'static str) {
self.imp.add(q, name)
}
}

View File

@ -12,7 +12,7 @@ use crate::{
imp::FileResolverImp,
};
#[derive(Debug, Hash)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct ModuleDescriptor {
pub submodules: Vec<Submodule>
}
@ -43,7 +43,7 @@ pub struct Submodule {
pub name: SmolStr,
}
#[derive(Hash, Debug)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct ModuleTreeDescriptor {
nodes: Vec<NodeData>,
links: Vec<LinkData>,
@ -52,7 +52,7 @@ pub(crate) struct ModuleTreeDescriptor {
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
struct Node(usize);
#[derive(Hash, Debug)]
#[derive(Hash, Debug, PartialEq, Eq)]
struct NodeData {
file_id: FileId,
links: Vec<Link>,
@ -61,7 +61,7 @@ struct NodeData {
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct Link(usize);
#[derive(Hash, Debug)]
#[derive(Hash, Debug, PartialEq, Eq)]
struct LinkData {
owner: Node,
name: SmolStr,
@ -70,7 +70,7 @@ struct LinkData {
}
#[derive(Clone, Debug, Hash)]
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum Problem {
UnresolvedModule {
candidate: RelativePathBuf,

View File

@ -1,8 +1,8 @@
use std::{
sync::{
Arc,
atomic::{AtomicBool, Ordering::SeqCst},
},
hash::{Hash, Hasher},
fmt,
collections::VecDeque,
iter,
@ -29,6 +29,21 @@ pub(crate) struct FileResolverImp {
inner: Arc<FileResolver>
}
impl PartialEq for FileResolverImp {
fn eq(&self, other: &FileResolverImp) -> bool {
self.inner() == other.inner()
}
}
impl Eq for FileResolverImp {
}
impl Hash for FileResolverImp {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.inner().hash(hasher);
}
}
impl FileResolverImp {
pub(crate) fn new(inner: Arc<FileResolver>) -> FileResolverImp {
FileResolverImp { inner }
@ -39,6 +54,9 @@ impl FileResolverImp {
pub(crate) fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> {
self.inner.resolve(file_id, path)
}
fn inner(&self) -> *const FileResolver {
&*self.inner
}
}
impl Default for FileResolverImp {
@ -59,29 +77,27 @@ impl Default for FileResolverImp {
#[derive(Debug)]
pub(crate) struct AnalysisHostImpl {
data: Arc<WorldData>
data: WorldData
}
impl AnalysisHostImpl {
pub fn new() -> AnalysisHostImpl {
AnalysisHostImpl {
data: Arc::new(WorldData::default()),
data: WorldData::default(),
}
}
pub fn analysis(&self) -> AnalysisImpl {
AnalysisImpl {
needs_reindex: AtomicBool::new(false),
data: self.data.clone(),
}
}
pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) {
let data = self.data_mut();
data.root = Arc::new(data.root.apply_changes(changes, None));
self.data_mut()
.root.apply_changes(changes, None);
}
pub fn set_file_resolver(&mut self, resolver: FileResolverImp) {
let data = self.data_mut();
data.file_resolver = resolver.clone();
data.root = Arc::new(data.root.apply_changes(&mut iter::empty(), Some(resolver)));
self.data_mut()
.root.apply_changes(&mut iter::empty(), Some(resolver));
}
pub fn set_crate_graph(&mut self, graph: CrateGraph) {
let mut visited = FxHashSet::default();
@ -96,34 +112,24 @@ impl AnalysisHostImpl {
self.data_mut().libs.push(Arc::new(root));
}
fn data_mut(&mut self) -> &mut WorldData {
Arc::make_mut(&mut self.data)
&mut self.data
}
}
pub(crate) struct AnalysisImpl {
needs_reindex: AtomicBool,
data: Arc<WorldData>,
data: WorldData,
}
impl fmt::Debug for AnalysisImpl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(&*self.data).fmt(f)
}
}
impl Clone for AnalysisImpl {
fn clone(&self) -> AnalysisImpl {
AnalysisImpl {
needs_reindex: AtomicBool::new(self.needs_reindex.load(SeqCst)),
data: Arc::clone(&self.data),
}
self.data.fmt(f)
}
}
impl AnalysisImpl {
fn root(&self, file_id: FileId) -> &SourceRoot {
if self.data.root.contains(file_id) {
return &*self.data.root;
return &self.data.root;
}
&**self.data.libs.iter().find(|it| it.contains(file_id)).unwrap()
}
@ -386,9 +392,8 @@ impl AnalysisImpl {
#[derive(Default, Clone, Debug)]
struct WorldData {
file_resolver: FileResolverImp,
crate_graph: CrateGraph,
root: Arc<WritableSourceRoot>,
root: WritableSourceRoot,
libs: Vec<Arc<ReadonlySourceRoot>>,
}

View File

@ -19,7 +19,6 @@ mod imp;
mod job;
mod roots;
mod db;
mod queries;
mod descriptors;
use std::{
@ -162,7 +161,7 @@ impl Query {
}
}
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct Analysis {
imp: AnalysisImpl
}
@ -258,3 +257,9 @@ impl LibraryData {
LibraryData { root }
}
}
#[test]
fn analysis_is_send() {
fn is_send<T: Send>() {}
is_send::<Analysis>();
}

View File

@ -1,157 +1,34 @@
use std::sync::Arc;
use crate::{
FileId,
db::{
Query, QueryRegistry, QueryCtx,
file_set
},
queries::file_syntax,
db::{SyntaxDatabase},
descriptors::{ModuleDescriptor, ModuleTreeDescriptor},
};
pub(crate) fn register_queries(reg: &mut QueryRegistry) {
reg.add(MODULE_DESCR, "MODULE_DESCR");
reg.add(MODULE_TREE, "MODULE_TREE");
salsa::query_group! {
pub(crate) trait ModulesDatabase: SyntaxDatabase {
fn module_tree(key: ()) -> Arc<ModuleTreeDescriptor> {
type ModuleTreeQuery;
}
fn module_descriptor(file_id: FileId) -> Arc<ModuleDescriptor> {
type ModuleDescriptorQuery;
}
}
}
pub(crate) fn module_tree(ctx: QueryCtx) -> Arc<ModuleTreeDescriptor> {
ctx.get(MODULE_TREE, ())
fn module_descriptor(db: &impl ModulesDatabase, file_id: FileId) -> Arc<ModuleDescriptor> {
let file = db.file_syntax(file_id);
Arc::new(ModuleDescriptor::new(file.ast()))
}
const MODULE_DESCR: Query<FileId, ModuleDescriptor> = Query(30, |ctx, &file_id| {
let file = file_syntax(ctx, file_id);
ModuleDescriptor::new(file.ast())
});
const MODULE_TREE: Query<(), ModuleTreeDescriptor> = Query(31, |ctx, _| {
let file_set = file_set(ctx);
fn module_tree(db: &impl ModulesDatabase, (): ()) -> Arc<ModuleTreeDescriptor> {
let file_set = db.file_set(());
let mut files = Vec::new();
for &file_id in file_set.0.iter() {
let module_descr = ctx.get(MODULE_DESCR, file_id);
for &file_id in file_set.files.iter() {
let module_descr = db.module_descriptor(file_id);
files.push((file_id, module_descr));
}
ModuleTreeDescriptor::new(files.iter().map(|(file_id, descr)| (*file_id, &**descr)), &file_set.1)
});
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use im;
use relative_path::{RelativePath, RelativePathBuf};
use crate::{
db::{Db},
imp::FileResolverImp,
FileId, FileResolver,
};
use super::*;
#[derive(Debug)]
struct FileMap(im::HashMap<FileId, RelativePathBuf>);
impl FileResolver for FileMap {
fn file_stem(&self, file_id: FileId) -> String {
self.0[&file_id].file_stem().unwrap().to_string()
}
fn resolve(&self, file_id: FileId, rel: &RelativePath) -> Option<FileId> {
let path = self.0[&file_id].join(rel).normalize();
self.0.iter()
.filter_map(|&(id, ref p)| Some(id).filter(|_| p == &path))
.next()
}
}
struct Fixture {
next_file_id: u32,
fm: im::HashMap<FileId, RelativePathBuf>,
db: Db,
}
impl Fixture {
fn new() -> Fixture {
Fixture {
next_file_id: 1,
fm: im::HashMap::new(),
db: Db::new(),
}
}
fn add_file(&mut self, path: &str, text: &str) -> FileId {
assert!(path.starts_with("/"));
let file_id = FileId(self.next_file_id);
self.next_file_id += 1;
self.fm.insert(file_id, RelativePathBuf::from(&path[1..]));
let mut new_state = self.db.state().clone();
new_state.file_map.insert(file_id, Arc::new(text.to_string()));
new_state.file_resolver = FileResolverImp::new(
Arc::new(FileMap(self.fm.clone()))
);
self.db = self.db.with_changes(new_state, &[file_id], true);
file_id
}
fn remove_file(&mut self, file_id: FileId) {
self.fm.remove(&file_id);
let mut new_state = self.db.state().clone();
new_state.file_map.remove(&file_id);
new_state.file_resolver = FileResolverImp::new(
Arc::new(FileMap(self.fm.clone()))
);
self.db = self.db.with_changes(new_state, &[file_id], true);
}
fn change_file(&mut self, file_id: FileId, new_text: &str) {
let mut new_state = self.db.state().clone();
new_state.file_map.insert(file_id, Arc::new(new_text.to_string()));
self.db = self.db.with_changes(new_state, &[file_id], false);
}
fn check_parent_modules(
&self,
file_id: FileId,
expected: &[FileId],
queries: &[(&'static str, u64)]
) {
let (tree, events) = self.db.trace_query(|ctx| module_tree(ctx));
let actual = tree.parent_modules(file_id)
.into_iter()
.map(|link| link.owner(&tree))
.collect::<Vec<_>>();
assert_eq!(actual.as_slice(), expected);
let mut counts = HashMap::new();
events.into_iter()
.for_each(|event| *counts.entry(event).or_insert(0) += 1);
for &(query_id, expected_count) in queries.iter() {
let actual_count = *counts.get(&query_id).unwrap_or(&0);
assert_eq!(
actual_count,
expected_count,
"counts for {} differ",
query_id,
)
}
}
}
#[test]
fn test_parent_module() {
let mut f = Fixture::new();
let foo = f.add_file("/foo.rs", "");
f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]);
let lib = f.add_file("/lib.rs", "mod foo;");
f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]);
f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 0)]);
f.change_file(lib, "");
f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]);
f.change_file(lib, "mod foo;");
f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]);
f.change_file(lib, "mod bar;");
f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]);
f.change_file(lib, "mod foo;");
f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]);
f.remove_file(lib);
f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 0)]);
}
let res = ModuleTreeDescriptor::new(files.iter().map(|(file_id, descr)| (*file_id, &**descr)), &file_set.resolver);
Arc::new(res)
}

View File

@ -1,39 +0,0 @@
use std::sync::Arc;
use ra_syntax::File;
use ra_editor::LineIndex;
use crate::{
FileId,
db::{Query, QueryCtx, QueryRegistry},
symbol_index::SymbolIndex,
};
pub(crate) use crate::db::{file_text, file_set};
pub(crate) fn file_syntax(ctx: QueryCtx, file_id: FileId) -> File {
(&*ctx.get(FILE_SYNTAX, file_id)).clone()
}
pub(crate) fn file_lines(ctx: QueryCtx, file_id: FileId) -> Arc<LineIndex> {
ctx.get(FILE_LINES, file_id)
}
pub(crate) fn file_symbols(ctx: QueryCtx, file_id: FileId) -> Arc<SymbolIndex> {
ctx.get(FILE_SYMBOLS, file_id)
}
const FILE_SYNTAX: Query<FileId, File> = Query(16, |ctx, file_id: &FileId| {
let text = file_text(ctx, *file_id);
File::parse(&*text)
});
const FILE_LINES: Query<FileId, LineIndex> = Query(17, |ctx, file_id: &FileId| {
let text = file_text(ctx, *file_id);
LineIndex::new(&*text)
});
const FILE_SYMBOLS: Query<FileId, SymbolIndex> = Query(18, |ctx, file_id: &FileId| {
let syntax = file_syntax(ctx, *file_id);
SymbolIndex::for_file(*file_id, syntax)
});
pub(crate) fn register_queries(reg: &mut QueryRegistry) {
reg.add(FILE_SYNTAX, "FILE_SYNTAX");
reg.add(FILE_LINES, "FILE_LINES");
reg.add(FILE_SYMBOLS, "FILE_SYMBOLS");
}

View File

@ -5,7 +5,8 @@ use std::{
use once_cell::sync::OnceCell;
use rayon::prelude::*;
use rustc_hash::FxHashMap;
use salsa::Database;
use rustc_hash::{FxHashMap, FxHashSet};
use ra_editor::LineIndex;
use ra_syntax::File;
@ -14,7 +15,8 @@ use crate::{
imp::FileResolverImp,
symbol_index::SymbolIndex,
descriptors::{ModuleDescriptor, ModuleTreeDescriptor},
db::Db,
db::{self, FilesDatabase, SyntaxDatabase},
module_map::ModulesDatabase,
};
pub(crate) trait SourceRoot {
@ -25,62 +27,68 @@ pub(crate) trait SourceRoot {
fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>);
}
#[derive(Default, Debug)]
#[derive(Default, Debug, Clone)]
pub(crate) struct WritableSourceRoot {
db: Db,
db: db::RootDatabase,
}
impl WritableSourceRoot {
pub fn apply_changes(
&self,
&mut self,
changes: &mut dyn Iterator<Item=(FileId, Option<String>)>,
file_resolver: Option<FileResolverImp>,
) -> WritableSourceRoot {
let resolver_changed = file_resolver.is_some();
let mut changed_files = Vec::new();
let mut new_state = self.db.state().clone();
) {
let mut changed = FxHashSet::default();
let mut removed = FxHashSet::default();
for (file_id, text) in changes {
changed_files.push(file_id);
match text {
Some(text) => {
new_state.file_map.insert(file_id, Arc::new(text));
},
None => {
new_state.file_map.remove(&file_id);
removed.insert(file_id);
}
Some(text) => {
self.db.query(db::FileTextQuery)
.set(file_id, Arc::new(text));
changed.insert(file_id);
}
}
}
if let Some(file_resolver) = file_resolver {
new_state.file_resolver = file_resolver
}
WritableSourceRoot {
db: self.db.with_changes(new_state, &changed_files, resolver_changed)
let file_set = self.db.file_set(());
let mut files: FxHashSet<FileId> = file_set
.files
.clone();
for file_id in removed {
files.remove(&file_id);
}
files.extend(changed);
let resolver = file_resolver.unwrap_or_else(|| file_set.resolver.clone());
self.db.query(db::FileSetQuery)
.set((), Arc::new(db::FileSet { files, resolver }));
}
}
impl SourceRoot for WritableSourceRoot {
fn module_tree(&self) -> Arc<ModuleTreeDescriptor> {
self.db.make_query(crate::module_map::module_tree)
self.db.module_tree(())
}
fn contains(&self, file_id: FileId) -> bool {
self.db.state().file_map.contains_key(&file_id)
self.db.file_set(())
.files
.contains(&file_id)
}
fn lines(&self, file_id: FileId) -> Arc<LineIndex> {
self.db.make_query(|ctx| crate::queries::file_lines(ctx, file_id))
self.db.file_lines(file_id)
}
fn syntax(&self, file_id: FileId) -> File {
self.db.make_query(|ctx| crate::queries::file_syntax(ctx, file_id))
self.db.file_syntax(file_id)
}
fn symbols<'a>(&'a self, acc: &mut Vec<Arc<SymbolIndex>>) {
self.db.make_query(|ctx| {
let file_set = crate::queries::file_set(ctx);
let syms = file_set.0.iter()
.map(|file_id| crate::queries::file_symbols(ctx, *file_id));
acc.extend(syms);
});
let db = &self.db;
let symbols = db.file_set(());
let symbols = symbols
.files
.iter()
.map(|&file_id| db.file_symbols(file_id));
acc.extend(symbols);
}
}

View File

@ -17,6 +17,15 @@ pub(crate) struct SymbolIndex {
map: fst::Map,
}
impl PartialEq for SymbolIndex {
fn eq(&self, other: &SymbolIndex) -> bool {
self.symbols == other.symbols
}
}
impl Eq for SymbolIndex {
}
impl Hash for SymbolIndex {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.symbols.hash(hasher)

View File

@ -238,4 +238,4 @@ fn bar() {
assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]);
assert_eq!(desc.ret_type, None);
assert_eq!(param, Some(1));
}
}

View File

@ -1,7 +1,7 @@
use superslice::Ext;
use crate::TextUnit;
#[derive(Clone, Debug, Hash)]
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct LineIndex {
newlines: Vec<TextUnit>,
}

View File

@ -17,7 +17,7 @@ pub struct StructureNode {
pub kind: SyntaxKind,
}
#[derive(Debug, Clone, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FileSymbol {
pub name: SmolStr,
pub node_range: TextRange,

View File

@ -478,7 +478,7 @@ pub fn handle_code_action(
}
pub fn publish_diagnostics(
world: ServerWorld,
world: &ServerWorld,
file_id: FileId,
) -> Result<req::PublishDiagnosticsParams> {
let uri = world.file_id_to_uri(file_id)?;
@ -497,7 +497,7 @@ pub fn publish_diagnostics(
}
pub fn publish_decorations(
world: ServerWorld,
world: &ServerWorld,
file_id: FileId,
) -> Result<req::PublishDecorationsParams> {
let uri = world.file_id_to_uri(file_id)?;

View File

@ -391,7 +391,7 @@ fn update_file_notifications_on_threadpool(
) {
pool.spawn(move || {
for file_id in subscriptions {
match handlers::publish_diagnostics(world.clone(), file_id) {
match handlers::publish_diagnostics(&world, file_id) {
Err(e) => {
error!("failed to compute diagnostics: {:?}", e)
}
@ -400,7 +400,7 @@ fn update_file_notifications_on_threadpool(
sender.send(Task::Notify(not));
}
}
match handlers::publish_decorations(world.clone(), file_id) {
match handlers::publish_decorations(&world, file_id) {
Err(e) => {
error!("failed to compute decorations: {:?}", e)
}

View File

@ -23,7 +23,6 @@ pub struct ServerWorldState {
pub mem_map: FxHashMap<FileId, Option<String>>,
}
#[derive(Clone)]
pub struct ServerWorld {
pub workspaces: Arc<Vec<CargoWorkspace>>,
pub analysis: Analysis,

View File

@ -59,7 +59,7 @@ use crate::{
yellow::{GreenNode},
};
#[derive(Clone, Debug, Hash)]
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct File {
root: SyntaxNode
}

View File

@ -1,8 +0,0 @@
[package]
name = "salsa"
version = "0.1.0"
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
[dependencies]
parking_lot = "0.6.3"
im = "12.0.0"

View File

@ -1,293 +0,0 @@
extern crate im;
extern crate parking_lot;
use std::{
sync::Arc,
collections::{HashSet, HashMap},
cell::RefCell,
};
use parking_lot::Mutex;
pub type GroundQueryFn<T, D> = Box<Fn(&T, &D) -> (D, OutputFingerprint) + Send + Sync + 'static>;
pub type QueryFn<T, D> = Box<Fn(&QueryCtx<T, D>, &D) -> (D, OutputFingerprint) + Send + Sync + 'static>;
#[derive(Debug)]
pub struct Db<T, D> {
db: Arc<DbState<T, D>>,
query_config: Arc<QueryConfig<T, D>>,
}
pub struct QueryConfig<T, D> {
ground_fn: HashMap<QueryTypeId, GroundQueryFn<T, D>>,
query_fn: HashMap<QueryTypeId, QueryFn<T, D>>,
}
impl<T, D> ::std::fmt::Debug for QueryConfig<T, D> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::std::fmt::Display::fmt("QueryConfig { ... }", f)
}
}
#[derive(Debug)]
struct DbState<T, D> {
ground_data: T,
gen: Gen,
graph: Mutex<im::HashMap<QueryId, (Gen, Arc<QueryRecord<D>>)>>,
}
#[derive(Debug)]
struct QueryRecord<D> {
params: D,
output: D,
output_fingerprint: OutputFingerprint,
deps: Vec<(QueryId, OutputFingerprint)>,
}
impl<T, D> DbState<T, D> {
fn record(
&self,
query_id: QueryId,
params: D,
output: D,
output_fingerprint: OutputFingerprint,
deps: Vec<(QueryId, OutputFingerprint)>,
) {
let gen = self.gen;
let record = QueryRecord {
params,
output,
output_fingerprint,
deps,
};
self.graph.lock().insert(query_id, (gen, Arc::new(record)));
}
}
impl<T, D> QueryConfig<T, D> {
pub fn new() -> Self {
QueryConfig {
ground_fn: HashMap::new(),
query_fn: HashMap::new(),
}
}
pub fn with_ground_query(
mut self,
query_type: QueryTypeId,
query_fn: GroundQueryFn<T, D>
) -> Self {
let prev = self.ground_fn.insert(query_type, query_fn);
assert!(prev.is_none());
self
}
pub fn with_query(
mut self,
query_type: QueryTypeId,
query_fn: QueryFn<T, D>,
) -> Self {
let prev = self.query_fn.insert(query_type, query_fn);
assert!(prev.is_none());
self
}
}
pub struct QueryCtx<T, D> {
db: Arc<DbState<T, D>>,
query_config: Arc<QueryConfig<T, D>>,
stack: RefCell<Vec<Vec<(QueryId, OutputFingerprint)>>>,
executed: RefCell<Vec<QueryTypeId>>,
}
impl<T, D> QueryCtx<T, D>
where
D: Clone
{
fn new(db: &Db<T, D>) -> QueryCtx<T, D> {
QueryCtx {
db: Arc::clone(&db.db),
query_config: Arc::clone(&db.query_config),
stack: RefCell::new(vec![Vec::new()]),
executed: RefCell::new(Vec::new()),
}
}
pub fn get(
&self,
query_id: QueryId,
params: D,
) -> D {
let (res, output_fingerprint) = self.get_inner(query_id, params);
self.record_dep(query_id, output_fingerprint);
res
}
pub fn trace(&self) -> Vec<QueryTypeId> {
::std::mem::replace(&mut *self.executed.borrow_mut(), Vec::new())
}
fn get_inner(
&self,
query_id: QueryId,
params: D,
) -> (D, OutputFingerprint) {
let (gen, record) = {
let guard = self.db.graph.lock();
match guard.get(&query_id).map(|it| it.clone()){
None => {
drop(guard);
return self.force(query_id, params);
},
Some(it) => it,
}
};
if gen == self.db.gen {
return (record.output.clone(), record.output_fingerprint)
}
if self.query_config.ground_fn.contains_key(&query_id.0) {
let (invalidated, record) = {
let guard = self.db.graph.lock();
let (gen, ref record) = guard[&query_id];
(gen == INVALIDATED, record.clone())
};
if invalidated {
return self.force(query_id, params);
} else {
return (record.output.clone(), record.output_fingerprint);
}
}
for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() {
let dep_params: D = {
let guard = self.db.graph.lock();
guard[&dep_query_id]
.1
.params
.clone()
};
if prev_fingerprint != self.get_inner(dep_query_id, dep_params).1 {
return self.force(query_id, params)
}
}
let gen = self.db.gen;
{
let mut guard = self.db.graph.lock();
guard[&query_id].0 = gen;
}
(record.output.clone(), record.output_fingerprint)
}
fn force(
&self,
query_id: QueryId,
params: D,
) -> (D, OutputFingerprint) {
self.executed.borrow_mut().push(query_id.0);
self.stack.borrow_mut().push(Vec::new());
let (res, output_fingerprint) = if let Some(f) = self.query_config.ground_fn.get(&query_id.0) {
f(&self.db.ground_data, &params)
} else if let Some(f) = self.query_config.query_fn.get(&query_id.0) {
f(self, &params)
} else {
panic!("unknown query type: {:?}", query_id.0);
};
let res: D = res.into();
let deps = self.stack.borrow_mut().pop().unwrap();
self.db.record(query_id, params, res.clone(), output_fingerprint, deps);
(res, output_fingerprint)
}
fn record_dep(
&self,
query_id: QueryId,
output_fingerprint: OutputFingerprint,
) -> () {
let mut stack = self.stack.borrow_mut();
let deps = stack.last_mut().unwrap();
deps.push((query_id, output_fingerprint))
}
}
pub struct Invalidations {
types: HashSet<QueryTypeId>,
ids: Vec<QueryId>,
}
impl Invalidations {
pub fn new() -> Invalidations {
Invalidations {
types: HashSet::new(),
ids: Vec::new(),
}
}
pub fn invalidate(
&mut self,
query_type: QueryTypeId,
params: impl Iterator<Item=InputFingerprint>,
) {
self.types.insert(query_type);
self.ids.extend(params.map(|it| QueryId(query_type, it)))
}
}
impl<T, D> Db<T, D>
where
D: Clone
{
pub fn new(query_config: QueryConfig<T, D>, ground_data: T) -> Db<T, D> {
Db {
db: Arc::new(DbState { ground_data, gen: Gen(0), graph: Default::default() }),
query_config: Arc::new(query_config),
}
}
pub fn ground_data(&self) -> &T {
&self.db.ground_data
}
pub fn with_ground_data(
&self,
ground_data: T,
invalidations: Invalidations,
) -> Db<T, D> {
for id in self.query_config.ground_fn.keys() {
assert!(
invalidations.types.contains(id),
"all ground queries must be invalidated"
);
}
let gen = Gen(self.db.gen.0 + 1);
let mut graph = self.db.graph.lock().clone();
for id in invalidations.ids {
if let Some((gen, _)) = graph.get_mut(&id) {
*gen = INVALIDATED;
}
}
let graph = Mutex::new(graph);
Db {
db: Arc::new(DbState { ground_data, gen, graph }),
query_config: Arc::clone(&self.query_config)
}
}
pub fn query_ctx(&self) -> QueryCtx<T, D> {
QueryCtx::new(self)
}
pub fn get(
&self,
query_id: QueryId,
params: D,
) -> (D, Vec<QueryTypeId>) {
let ctx = self.query_ctx();
let res = ctx.get(query_id, params.into());
let executed = ::std::mem::replace(&mut *ctx.executed.borrow_mut(), Vec::new());
(res, executed)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
struct Gen(u64);
const INVALIDATED: Gen = Gen(!0);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct InputFingerprint(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct OutputFingerprint(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct QueryTypeId(pub u16);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct QueryId(pub QueryTypeId, pub InputFingerprint);

View File

@ -1,170 +0,0 @@
extern crate salsa;
use std::{
iter::once,
sync::Arc,
collections::hash_map::{HashMap, DefaultHasher},
any::Any,
hash::{Hash, Hasher},
};
type State = HashMap<u32, String>;
type Data = Arc<Any + Send + Sync + 'static>;
const GET_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(1);
const GET_FILES: salsa::QueryTypeId = salsa::QueryTypeId(2);
const FILE_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(3);
const TOTAL_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(4);
fn mk_ground_query<T, R>(
state: &State,
params: &Data,
f: fn(&State, &T) -> R,
) -> (Data, salsa::OutputFingerprint)
where
T: 'static,
R: Hash + Send + Sync + 'static,
{
let params = params.downcast_ref().unwrap();
let result = f(state, params);
let fingerprint = o_print(&result);
(Arc::new(result), fingerprint)
}
fn get<T, R>(db: &salsa::Db<State, Data>, query_type: salsa::QueryTypeId, param: T) -> (Arc<R>, Vec<salsa::QueryTypeId>)
where
T: Hash + Send + Sync + 'static,
R: Send + Sync + 'static,
{
let i_print = i_print(&param);
let param = Arc::new(param);
let (res, trace) = db.get(salsa::QueryId(query_type, i_print), param);
(res.downcast().unwrap(), trace)
}
struct QueryCtx<'a>(&'a salsa::QueryCtx<State, Data>);
impl<'a> QueryCtx<'a> {
fn get_text(&self, id: u32) -> Arc<String> {
let i_print = i_print(&id);
let text = self.0.get(salsa::QueryId(GET_TEXT, i_print), Arc::new(id));
text.downcast().unwrap()
}
fn get_files(&self) -> Arc<Vec<u32>> {
let i_print = i_print(&());
let files = self.0.get(salsa::QueryId(GET_FILES, i_print), Arc::new(()));
let res = files.downcast().unwrap();
res
}
fn get_n_lines(&self, id: u32) -> usize {
let i_print = i_print(&id);
let n_lines = self.0.get(salsa::QueryId(FILE_NEWLINES, i_print), Arc::new(id));
*n_lines.downcast().unwrap()
}
}
fn mk_query<T, R>(
query_ctx: &salsa::QueryCtx<State, Data>,
params: &Data,
f: fn(QueryCtx, &T) -> R,
) -> (Data, salsa::OutputFingerprint)
where
T: 'static,
R: Hash + Send + Sync + 'static,
{
let params: &T = params.downcast_ref().unwrap();
let query_ctx = QueryCtx(query_ctx);
let result = f(query_ctx, params);
let fingerprint = o_print(&result);
(Arc::new(result), fingerprint)
}
fn mk_queries() -> salsa::QueryConfig<State, Data> {
salsa::QueryConfig::<State, Data>::new()
.with_ground_query(GET_TEXT, Box::new(|state, id| {
mk_ground_query::<u32, String>(state, id, |state, id| state[id].clone())
}))
.with_ground_query(GET_FILES, Box::new(|state, id| {
mk_ground_query::<(), Vec<u32>>(state, id, |state, &()| state.keys().cloned().collect())
}))
.with_query(FILE_NEWLINES, Box::new(|query_ctx, id| {
mk_query(query_ctx, id, |query_ctx, &id| {
let text = query_ctx.get_text(id);
text.lines().count()
})
}))
.with_query(TOTAL_NEWLINES, Box::new(|query_ctx, id| {
mk_query(query_ctx, id, |query_ctx, &()| {
let mut total = 0;
for &id in query_ctx.get_files().iter() {
total += query_ctx.get_n_lines(id)
}
total
})
}))
}
#[test]
fn test_number_of_lines() {
let mut state = State::new();
let db = salsa::Db::new(mk_queries(), state.clone());
let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
assert_eq!(*newlines, 0);
assert_eq!(trace.len(), 2);
let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
assert_eq!(*newlines, 0);
assert_eq!(trace.len(), 0);
state.insert(1, "hello\nworld".to_string());
let mut inv = salsa::Invalidations::new();
inv.invalidate(GET_TEXT, once(i_print(&1u32)));
inv.invalidate(GET_FILES, once(i_print(&())));
let db = db.with_ground_data(state.clone(), inv);
let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
assert_eq!(*newlines, 2);
assert_eq!(trace.len(), 4);
state.insert(2, "spam\neggs".to_string());
let mut inv = salsa::Invalidations::new();
inv.invalidate(GET_TEXT, once(i_print(&2u32)));
inv.invalidate(GET_FILES, once(i_print(&())));
let db = db.with_ground_data(state.clone(), inv);
let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
assert_eq!(*newlines, 4);
assert_eq!(trace.len(), 4);
let mut invs = vec![];
for i in 0..10 {
let id = i + 10;
invs.push(i_print(&id));
state.insert(id, "spam".to_string());
}
let mut inv = salsa::Invalidations::new();
inv.invalidate(GET_TEXT, invs.into_iter());
inv.invalidate(GET_FILES, once(i_print(&())));
let db = db.with_ground_data(state.clone(), inv);
let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
assert_eq!(*newlines, 14);
assert_eq!(trace.len(), 22);
state.insert(15, String::new());
let mut inv = salsa::Invalidations::new();
inv.invalidate(GET_TEXT, once(i_print(&15u32)));
inv.invalidate(GET_FILES, once(i_print(&())));
let db = db.with_ground_data(state.clone(), inv);
let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ());
assert_eq!(*newlines, 13);
assert_eq!(trace.len(), 4);
}
fn o_print<T: Hash>(x: &T) -> salsa::OutputFingerprint {
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
let hash = hasher.finish();
salsa::OutputFingerprint(hash)
}
fn i_print<T: Hash>(x: &T) -> salsa::InputFingerprint {
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
let hash = hasher.finish();
salsa::InputFingerprint(hash)
}