aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock62
-rw-r--r--crates/gen_lsp_server/Cargo.toml2
-rw-r--r--crates/gen_lsp_server/src/lib.rs10
-rw-r--r--crates/gen_lsp_server/src/stdio.rs10
-rw-r--r--crates/ra_analysis/src/completion/complete_keyword.rs55
-rw-r--r--crates/ra_analysis/src/completion/completion_context.rs32
-rw-r--r--crates/ra_lsp_server/Cargo.toml4
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs48
-rw-r--r--crates/ra_lsp_server/src/project_model.rs4
-rw-r--r--crates/ra_lsp_server/tests/heavy_tests/support.rs17
-rw-r--r--crates/ra_syntax/src/grammar/patterns.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt78
-rw-r--r--crates/ra_vfs/Cargo.toml2
-rw-r--r--crates/ra_vfs/src/io.rs4
-rw-r--r--crates/ra_vfs/src/lib.rs2
-rw-r--r--crates/thread_worker/Cargo.toml2
-rw-r--r--crates/thread_worker/src/lib.rs6
18 files changed, 192 insertions, 152 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8e962d352..150e6d1ea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -166,13 +166,12 @@ dependencies = [
166 166
167[[package]] 167[[package]]
168name = "crossbeam-channel" 168name = "crossbeam-channel"
169version = "0.2.6" 169version = "0.3.6"
170source = "registry+https://github.com/rust-lang/crates.io-index" 170source = "registry+https://github.com/rust-lang/crates.io-index"
171dependencies = [ 171dependencies = [
172 "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 172 "crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
173 "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 173 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
174 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 174 "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
175 "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
176 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", 175 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
177] 176]
178 177
@@ -200,19 +199,6 @@ dependencies = [
200] 199]
201 200
202[[package]] 201[[package]]
203name = "crossbeam-epoch"
204version = "0.6.1"
205source = "registry+https://github.com/rust-lang/crates.io-index"
206dependencies = [
207 "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
208 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
209 "crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
210 "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
211 "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
212 "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
213]
214
215[[package]]
216name = "crossbeam-utils" 202name = "crossbeam-utils"
217version = "0.2.2" 203version = "0.2.2"
218source = "registry+https://github.com/rust-lang/crates.io-index" 204source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -222,11 +208,6 @@ dependencies = [
222 208
223[[package]] 209[[package]]
224name = "crossbeam-utils" 210name = "crossbeam-utils"
225version = "0.5.0"
226source = "registry+https://github.com/rust-lang/crates.io-index"
227
228[[package]]
229name = "crossbeam-utils"
230version = "0.6.3" 211version = "0.6.3"
231source = "registry+https://github.com/rust-lang/crates.io-index" 212source = "registry+https://github.com/rust-lang/crates.io-index"
232dependencies = [ 213dependencies = [
@@ -355,7 +336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
355name = "gen_lsp_server" 336name = "gen_lsp_server"
356version = "0.1.0" 337version = "0.1.0"
357dependencies = [ 338dependencies = [
358 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 339 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
359 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 340 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
360 "languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)", 341 "languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)",
361 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 342 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -764,7 +745,7 @@ name = "ra_lsp_server"
764version = "0.1.0" 745version = "0.1.0"
765dependencies = [ 746dependencies = [
766 "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 747 "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
767 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 748 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
768 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 749 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
769 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 750 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
770 "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 751 "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -785,7 +766,7 @@ dependencies = [
785 "serde 1.0.83 (registry+https://github.com/rust-lang/crates.io-index)", 766 "serde 1.0.83 (registry+https://github.com/rust-lang/crates.io-index)",
786 "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", 767 "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
787 "smol_str 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 768 "smol_str 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
788 "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 769 "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
789 "test_utils 0.1.0", 770 "test_utils 0.1.0",
790 "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 771 "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
791 "thread_worker 0.1.0", 772 "thread_worker 0.1.0",
@@ -824,7 +805,7 @@ dependencies = [
824name = "ra_vfs" 805name = "ra_vfs"
825version = "0.1.0" 806version = "0.1.0"
826dependencies = [ 807dependencies = [
827 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 808 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
828 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 809 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
829 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 810 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
830 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 811 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -835,16 +816,6 @@ dependencies = [
835 816
836[[package]] 817[[package]]
837name = "rand" 818name = "rand"
838version = "0.4.3"
839source = "registry+https://github.com/rust-lang/crates.io-index"
840dependencies = [
841 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
842 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
843 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
844]
845
846[[package]]
847name = "rand"
848version = "0.5.5" 819version = "0.5.5"
849source = "registry+https://github.com/rust-lang/crates.io-index" 820source = "registry+https://github.com/rust-lang/crates.io-index"
850dependencies = [ 821dependencies = [
@@ -1208,15 +1179,6 @@ dependencies = [
1208] 1179]
1209 1180
1210[[package]] 1181[[package]]
1211name = "tempdir"
1212version = "0.3.7"
1213source = "registry+https://github.com/rust-lang/crates.io-index"
1214dependencies = [
1215 "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
1216 "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1217]
1218
1219[[package]]
1220name = "tempfile" 1182name = "tempfile"
1221version = "3.0.5" 1183version = "3.0.5"
1222source = "registry+https://github.com/rust-lang/crates.io-index" 1184source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1308,7 +1270,7 @@ dependencies = [
1308name = "thread_worker" 1270name = "thread_worker"
1309version = "0.1.0" 1271version = "0.1.0"
1310dependencies = [ 1272dependencies = [
1311 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 1273 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
1312 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1274 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
1313 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1275 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1314] 1276]
@@ -1543,12 +1505,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1543"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" 1505"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
1544"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" 1506"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
1545"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1507"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
1546"checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" 1508"checksum crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "137bc235f622ffaa0428e3854e24acb53291fc0b3ff6fb2cb75a8be6fb02f06b"
1547"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" 1509"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
1548"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" 1510"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
1549"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8"
1550"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" 1511"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
1551"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
1552"checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a" 1512"checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a"
1553"checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c" 1513"checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c"
1554"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" 1514"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
@@ -1606,7 +1566,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1606"checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f" 1566"checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f"
1607"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" 1567"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
1608"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" 1568"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
1609"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
1610"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" 1569"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
1611"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" 1570"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a"
1612"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" 1571"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a"
@@ -1650,7 +1609,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1650"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" 1609"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
1651"checksum syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9545a6a093a3f0bd59adb472700acc08cad3776f860f16a897dfce8c88721cbc" 1610"checksum syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9545a6a093a3f0bd59adb472700acc08cad3776f860f16a897dfce8c88721cbc"
1652"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" 1611"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
1653"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
1654"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2" 1612"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
1655"checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3" 1613"checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3"
1656"checksum teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d89ad4617d1dec55331067fadaa041e813479e1779616f3d3ce9308bf46184e" 1614"checksum teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d89ad4617d1dec55331067fadaa041e813479e1779616f3d3ce9308bf46184e"
diff --git a/crates/gen_lsp_server/Cargo.toml b/crates/gen_lsp_server/Cargo.toml
index afeeb1513..2aee4ea16 100644
--- a/crates/gen_lsp_server/Cargo.toml
+++ b/crates/gen_lsp_server/Cargo.toml
@@ -13,4 +13,4 @@ log = "0.4.3"
13failure = "0.1.2" 13failure = "0.1.2"
14serde_json = "1.0.24" 14serde_json = "1.0.24"
15serde = { version = "1.0.83", features = ["derive"] } 15serde = { version = "1.0.83", features = ["derive"] }
16crossbeam-channel = "0.2.4" 16crossbeam-channel = "0.3.5"
diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs
index 8779fbf0f..b20652928 100644
--- a/crates/gen_lsp_server/src/lib.rs
+++ b/crates/gen_lsp_server/src/lib.rs
@@ -95,7 +95,7 @@ pub fn run_server(
95 server(params, &receiver, &sender)?; 95 server(params, &receiver, &sender)?;
96 log::info!("lsp server waiting for exit notification"); 96 log::info!("lsp server waiting for exit notification");
97 match receiver.recv() { 97 match receiver.recv() {
98 Some(RawMessage::Notification(n)) => n 98 Ok(RawMessage::Notification(n)) => n
99 .cast::<Exit>() 99 .cast::<Exit>()
100 .map_err(|n| format_err!("unexpected notification during shutdown: {:?}", n))?, 100 .map_err(|n| format_err!("unexpected notification during shutdown: {:?}", n))?,
101 m => bail!("unexpected message during shutdown: {:?}", m), 101 m => bail!("unexpected message during shutdown: {:?}", m),
@@ -109,7 +109,7 @@ pub fn handle_shutdown(req: RawRequest, sender: &Sender<RawMessage>) -> Option<R
109 match req.cast::<Shutdown>() { 109 match req.cast::<Shutdown>() {
110 Ok((id, ())) => { 110 Ok((id, ())) => {
111 let resp = RawResponse::ok::<Shutdown>(id, &()); 111 let resp = RawResponse::ok::<Shutdown>(id, &());
112 sender.send(RawMessage::Response(resp)); 112 let _ = sender.send(RawMessage::Response(resp));
113 None 113 None
114 } 114 }
115 Err(req) => Some(req), 115 Err(req) => Some(req),
@@ -122,16 +122,16 @@ fn initialize(
122 caps: ServerCapabilities, 122 caps: ServerCapabilities,
123) -> Result<InitializeParams> { 123) -> Result<InitializeParams> {
124 let (id, params) = match receiver.recv() { 124 let (id, params) = match receiver.recv() {
125 Some(RawMessage::Request(req)) => match req.cast::<Initialize>() { 125 Ok(RawMessage::Request(req)) => match req.cast::<Initialize>() {
126 Err(req) => bail!("expected initialize request, got {:?}", req), 126 Err(req) => bail!("expected initialize request, got {:?}", req),
127 Ok(req) => req, 127 Ok(req) => req,
128 }, 128 },
129 msg => bail!("expected initialize request, got {:?}", msg), 129 msg => bail!("expected initialize request, got {:?}", msg),
130 }; 130 };
131 let resp = RawResponse::ok::<Initialize>(id, &InitializeResult { capabilities: caps }); 131 let resp = RawResponse::ok::<Initialize>(id, &InitializeResult { capabilities: caps });
132 sender.send(RawMessage::Response(resp)); 132 sender.send(RawMessage::Response(resp)).unwrap();
133 match receiver.recv() { 133 match receiver.recv() {
134 Some(RawMessage::Notification(n)) => { 134 Ok(RawMessage::Notification(n)) => {
135 n.cast::<Initialized>() 135 n.cast::<Initialized>()
136 .map_err(|_| format_err!("expected initialized notification"))?; 136 .map_err(|_| format_err!("expected initialized notification"))?;
137 } 137 }
diff --git a/crates/gen_lsp_server/src/stdio.rs b/crates/gen_lsp_server/src/stdio.rs
index 35d8e46d0..5c8e33854 100644
--- a/crates/gen_lsp_server/src/stdio.rs
+++ b/crates/gen_lsp_server/src/stdio.rs
@@ -9,11 +9,13 @@ use failure::bail;
9use crate::{RawMessage, Result}; 9use crate::{RawMessage, Result};
10 10
11pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads) { 11pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads) {
12 let (writer_sender, mut writer_receiver) = bounded::<RawMessage>(16); 12 let (writer_sender, writer_receiver) = bounded::<RawMessage>(16);
13 let writer = thread::spawn(move || { 13 let writer = thread::spawn(move || {
14 let stdout = stdout(); 14 let stdout = stdout();
15 let mut stdout = stdout.lock(); 15 let mut stdout = stdout.lock();
16 writer_receiver.try_for_each(|it| it.write(&mut stdout))?; 16 writer_receiver
17 .into_iter()
18 .try_for_each(|it| it.write(&mut stdout))?;
17 Ok(()) 19 Ok(())
18 }); 20 });
19 let (reader_sender, reader_receiver) = bounded::<RawMessage>(16); 21 let (reader_sender, reader_receiver) = bounded::<RawMessage>(16);
@@ -21,7 +23,9 @@ pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads)
21 let stdin = stdin(); 23 let stdin = stdin();
22 let mut stdin = stdin.lock(); 24 let mut stdin = stdin.lock();
23 while let Some(msg) = RawMessage::read(&mut stdin)? { 25 while let Some(msg) = RawMessage::read(&mut stdin)? {
24 reader_sender.send(msg); 26 if let Err(_) = reader_sender.send(msg) {
27 break;
28 }
25 } 29 }
26 Ok(()) 30 Ok(())
27 }); 31 });
diff --git a/crates/ra_analysis/src/completion/complete_keyword.rs b/crates/ra_analysis/src/completion/complete_keyword.rs
index 2869e67e0..d70fdaada 100644
--- a/crates/ra_analysis/src/completion/complete_keyword.rs
+++ b/crates/ra_analysis/src/completion/complete_keyword.rs
@@ -32,8 +32,13 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
32 acc.add(keyword("else if", "else if $0 {}")); 32 acc.add(keyword("else if", "else if $0 {}"));
33 } 33 }
34 if is_in_loop_body(ctx.leaf) { 34 if is_in_loop_body(ctx.leaf) {
35 acc.add(keyword("continue", "continue")); 35 if ctx.can_be_stmt {
36 acc.add(keyword("break", "break")); 36 acc.add(keyword("continue", "continue;"));
37 acc.add(keyword("break", "break;"));
38 } else {
39 acc.add(keyword("continue", "continue"));
40 acc.add(keyword("break", "break"));
41 }
37 } 42 }
38 acc.add_all(complete_return(fn_def, ctx.can_be_stmt)); 43 acc.add_all(complete_return(fn_def, ctx.can_be_stmt));
39} 44}
@@ -186,6 +191,24 @@ mod tests {
186 return "return $0;" 191 return "return $0;"
187 "#, 192 "#,
188 ); 193 );
194 check_keyword_completion(
195 r"
196 fn quux() -> i32 {
197 if condition {
198 <|>
199 }
200 let x = 92;
201 x
202 }
203 ",
204 r#"
205 if "if $0 {}"
206 match "match $0 {}"
207 while "while $0 {}"
208 loop "loop {$0}"
209 return "return $0;"
210 "#,
211 );
189 } 212 }
190 213
191 #[test] 214 #[test]
@@ -201,8 +224,8 @@ mod tests {
201 match "match $0 {}" 224 match "match $0 {}"
202 while "while $0 {}" 225 while "while $0 {}"
203 loop "loop {$0}" 226 loop "loop {$0}"
204 continue "continue" 227 continue "continue;"
205 break "break" 228 break "break;"
206 return "return $0;" 229 return "return $0;"
207 "#, 230 "#,
208 ); 231 );
@@ -222,4 +245,28 @@ mod tests {
222 "#, 245 "#,
223 ); 246 );
224 } 247 }
248
249 #[test]
250 fn no_semi_after_break_continue_in_expr() {
251 check_keyword_completion(
252 r"
253 fn f() {
254 loop {
255 match () {
256 () => br<|>
257 }
258 }
259 }
260 ",
261 r#"
262 if "if $0 {}"
263 match "match $0 {}"
264 while "while $0 {}"
265 loop "loop {$0}"
266 continue "continue"
267 break "break"
268 return "return"
269 "#,
270 )
271 }
225} 272}
diff --git a/crates/ra_analysis/src/completion/completion_context.rs b/crates/ra_analysis/src/completion/completion_context.rs
index 4685c9328..4584f355d 100644
--- a/crates/ra_analysis/src/completion/completion_context.rs
+++ b/crates/ra_analysis/src/completion/completion_context.rs
@@ -148,24 +148,24 @@ impl<'a> CompletionContext<'a> {
148 if path.qualifier().is_none() { 148 if path.qualifier().is_none() {
149 self.is_trivial_path = true; 149 self.is_trivial_path = true;
150 150
151 self.can_be_stmt = match name_ref 151 // Find either enclosing expr statement (thing with `;`) or a
152 // block. If block, check that we are the last expr.
153 self.can_be_stmt = name_ref
152 .syntax() 154 .syntax()
153 .ancestors() 155 .ancestors()
154 .filter_map(ast::ExprStmt::cast) 156 .find_map(|node| {
155 .next() 157 if let Some(stmt) = ast::ExprStmt::cast(node) {
156 { 158 return Some(stmt.syntax().range() == name_ref.syntax().range());
157 None => { 159 }
158 name_ref 160 if let Some(block) = ast::Block::cast(node) {
159 .syntax() 161 return Some(
160 .ancestors() 162 block.expr().map(|e| e.syntax().range())
161 .filter_map(ast::Block::cast) 163 == Some(name_ref.syntax().range()),
162 .next() 164 );
163 .and_then(|block| block.expr()) 165 }
164 .map(|e| e.syntax().range()) 166 None
165 == Some(name_ref.syntax().range()) 167 })
166 } 168 .unwrap_or(false);
167 Some(expr_stmt) => expr_stmt.syntax().range() == name_ref.syntax().range(),
168 };
169 169
170 if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) { 170 if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) {
171 if let Some(if_expr) = 171 if let Some(if_expr) =
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index 646df2497..22a26b844 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -13,7 +13,7 @@ failure_derive = "0.1.2"
13serde_json = "1.0.24" 13serde_json = "1.0.24"
14serde = "1.0.83" 14serde = "1.0.83"
15drop_bomb = "0.1.0" 15drop_bomb = "0.1.0"
16crossbeam-channel = "0.2.4" 16crossbeam-channel = "0.3.5"
17flexi_logger = "0.10.0" 17flexi_logger = "0.10.0"
18log = "0.4.3" 18log = "0.4.3"
19url_serde = "0.2.0" 19url_serde = "0.2.0"
@@ -35,6 +35,6 @@ gen_lsp_server = { path = "../gen_lsp_server" }
35ra_vfs = { path = "../ra_vfs" } 35ra_vfs = { path = "../ra_vfs" }
36 36
37[dev-dependencies] 37[dev-dependencies]
38tempdir = "0.3.7" 38tempfile = "3"
39test_utils = { path = "../test_utils" } 39test_utils = { path = "../test_utils" }
40tools = { path = "../tools" } 40tools = { path = "../tools" }
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 97c1be778..3ebae4ecd 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -7,7 +7,7 @@ use std::{
7 sync::Arc, 7 sync::Arc,
8}; 8};
9 9
10use crossbeam_channel::{unbounded, select, Receiver, Sender}; 10use crossbeam_channel::{unbounded, select, Receiver, Sender, RecvError};
11use gen_lsp_server::{ 11use gen_lsp_server::{
12 handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, 12 handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse,
13}; 13};
@@ -62,7 +62,7 @@ pub fn main_loop(
62 let (task_sender, task_receiver) = unbounded::<Task>(); 62 let (task_sender, task_receiver) = unbounded::<Task>();
63 let (ws_worker, ws_watcher) = workspace_loader(); 63 let (ws_worker, ws_watcher) = workspace_loader();
64 64
65 ws_worker.send(ws_root.clone()); 65 ws_worker.send(ws_root.clone()).unwrap();
66 // FIXME: support dynamic workspace loading. 66 // FIXME: support dynamic workspace loading.
67 let workspaces = match ws_worker.recv().unwrap() { 67 let workspaces = match ws_worker.recv().unwrap() {
68 Ok(ws) => vec![ws], 68 Ok(ws) => vec![ws],
@@ -95,7 +95,9 @@ pub fn main_loop(
95 ); 95 );
96 96
97 log::info!("waiting for tasks to finish..."); 97 log::info!("waiting for tasks to finish...");
98 task_receiver.for_each(|task| on_task(task, msg_sender, &mut pending_requests)); 98 task_receiver
99 .into_iter()
100 .for_each(|task| on_task(task, msg_sender, &mut pending_requests));
99 log::info!("...tasks have finished"); 101 log::info!("...tasks have finished");
100 log::info!("joining threadpool..."); 102 log::info!("joining threadpool...");
101 drop(pool); 103 drop(pool);
@@ -170,16 +172,16 @@ fn main_loop_inner(
170 loop { 172 loop {
171 log::trace!("selecting"); 173 log::trace!("selecting");
172 let event = select! { 174 let event = select! {
173 recv(msg_receiver, msg) => match msg { 175 recv(msg_receiver) -> msg => match msg {
174 Some(msg) => Event::Msg(msg), 176 Ok(msg) => Event::Msg(msg),
175 None => bail!("client exited without shutdown"), 177 Err(RecvError) => bail!("client exited without shutdown"),
176 }, 178 },
177 recv(task_receiver, task) => Event::Task(task.unwrap()), 179 recv(task_receiver) -> task => Event::Task(task.unwrap()),
178 recv(state.vfs.read().task_receiver(), task) => match task { 180 recv(state.vfs.read().task_receiver()) -> task => match task {
179 None => bail!("vfs died"), 181 Ok(task) => Event::Vfs(task),
180 Some(task) => Event::Vfs(task), 182 Err(RecvError) => bail!("vfs died"),
181 } 183 },
182 recv(libdata_receiver, data) => Event::Lib(data.unwrap()) 184 recv(libdata_receiver) -> data => Event::Lib(data.unwrap())
183 }; 185 };
184 log::info!("loop_turn = {:?}", event); 186 log::info!("loop_turn = {:?}", event);
185 let start = std::time::Instant::now(); 187 let start = std::time::Instant::now();
@@ -209,7 +211,7 @@ fn main_loop_inner(
209 ErrorCode::MethodNotFound as i32, 211 ErrorCode::MethodNotFound as i32,
210 "unknown request".to_string(), 212 "unknown request".to_string(),
211 ); 213 );
212 msg_sender.send(RawMessage::Response(resp)) 214 msg_sender.send(RawMessage::Response(resp)).unwrap()
213 } 215 }
214 } 216 }
215 } 217 }
@@ -229,7 +231,7 @@ fn main_loop_inner(
229 log::info!("indexing {:?} ... ", root); 231 log::info!("indexing {:?} ... ", root);
230 let data = LibraryData::prepare(root, files); 232 let data = LibraryData::prepare(root, files);
231 log::info!("indexed {:?} {:?}", start.elapsed(), root); 233 log::info!("indexed {:?} {:?}", start.elapsed(), root);
232 sender.send(data); 234 sender.send(data).unwrap();
233 }); 235 });
234 } 236 }
235 if state.roots_to_scan == 0 { 237 if state.roots_to_scan == 0 {
@@ -253,10 +255,12 @@ fn on_task(task: Task, msg_sender: &Sender<RawMessage>, pending_requests: &mut F
253 match task { 255 match task {
254 Task::Respond(response) => { 256 Task::Respond(response) => {
255 if pending_requests.remove(&response.id) { 257 if pending_requests.remove(&response.id) {
256 msg_sender.send(RawMessage::Response(response)) 258 msg_sender.send(RawMessage::Response(response)).unwrap();
257 } 259 }
258 } 260 }
259 Task::Notify(n) => msg_sender.send(RawMessage::Notification(n)), 261 Task::Notify(n) => {
262 msg_sender.send(RawMessage::Notification(n)).unwrap();
263 }
260 } 264 }
261} 265}
262 266
@@ -328,7 +332,7 @@ fn on_notification(
328 ErrorCode::RequestCancelled as i32, 332 ErrorCode::RequestCancelled as i32,
329 "canceled by client".to_string(), 333 "canceled by client".to_string(),
330 ); 334 );
331 msg_sender.send(RawMessage::Response(response)) 335 msg_sender.send(RawMessage::Response(response)).unwrap()
332 } 336 }
333 return Ok(()); 337 return Ok(());
334 } 338 }
@@ -381,7 +385,7 @@ fn on_notification(
381 diagnostics: Vec::new(), 385 diagnostics: Vec::new(),
382 }; 386 };
383 let not = RawNotification::new::<req::PublishDiagnostics>(&params); 387 let not = RawNotification::new::<req::PublishDiagnostics>(&params);
384 msg_sender.send(RawMessage::Notification(not)); 388 msg_sender.send(RawMessage::Notification(not)).unwrap();
385 return Ok(()); 389 return Ok(());
386 } 390 }
387 Err(not) => not, 391 Err(not) => not,
@@ -441,7 +445,7 @@ impl<'a> PoolDispatcher<'a> {
441 }, 445 },
442 }; 446 };
443 let task = Task::Respond(resp); 447 let task = Task::Respond(resp);
444 sender.send(task); 448 sender.send(task).unwrap();
445 }); 449 });
446 self.res = Some(id); 450 self.res = Some(id);
447 } 451 }
@@ -476,7 +480,7 @@ fn update_file_notifications_on_threadpool(
476 } 480 }
477 Ok(params) => { 481 Ok(params) => {
478 let not = RawNotification::new::<req::PublishDiagnostics>(&params); 482 let not = RawNotification::new::<req::PublishDiagnostics>(&params);
479 sender.send(Task::Notify(not)); 483 sender.send(Task::Notify(not)).unwrap();
480 } 484 }
481 } 485 }
482 if publish_decorations { 486 if publish_decorations {
@@ -488,7 +492,7 @@ fn update_file_notifications_on_threadpool(
488 } 492 }
489 Ok(params) => { 493 Ok(params) => {
490 let not = RawNotification::new::<req::PublishDecorations>(&params); 494 let not = RawNotification::new::<req::PublishDecorations>(&params);
491 sender.send(Task::Notify(not)) 495 sender.send(Task::Notify(not)).unwrap();
492 } 496 }
493 } 497 }
494 } 498 }
@@ -501,7 +505,7 @@ fn feedback(intrnal_mode: bool, msg: &str, sender: &Sender<RawMessage>) {
501 return; 505 return;
502 } 506 }
503 let not = RawNotification::new::<req::InternalFeedback>(&msg.to_string()); 507 let not = RawNotification::new::<req::InternalFeedback>(&msg.to_string());
504 sender.send(RawMessage::Notification(not)); 508 sender.send(RawMessage::Notification(not)).unwrap();
505} 509}
506 510
507fn is_canceled(e: &failure::Error) -> bool { 511fn is_canceled(e: &failure::Error) -> bool {
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs
index 5852a157d..ae2149463 100644
--- a/crates/ra_lsp_server/src/project_model.rs
+++ b/crates/ra_lsp_server/src/project_model.rs
@@ -204,8 +204,10 @@ pub fn workspace_loader() -> (Worker<PathBuf, Result<CargoWorkspace>>, WorkerHan
204 1, 204 1,
205 |input_receiver, output_sender| { 205 |input_receiver, output_sender| {
206 input_receiver 206 input_receiver
207 .into_iter()
207 .map(|path| CargoWorkspace::from_cargo_metadata(path.as_path())) 208 .map(|path| CargoWorkspace::from_cargo_metadata(path.as_path()))
208 .for_each(|it| output_sender.send(it)) 209 .try_for_each(|it| output_sender.send(it))
210 .unwrap()
209 }, 211 },
210 ) 212 )
211} 213}
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs
index c14d287ca..7db168b0f 100644
--- a/crates/ra_lsp_server/tests/heavy_tests/support.rs
+++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs
@@ -16,7 +16,7 @@ use languageserver_types::{
16}; 16};
17use serde::Serialize; 17use serde::Serialize;
18use serde_json::{to_string_pretty, Value}; 18use serde_json::{to_string_pretty, Value};
19use tempdir::TempDir; 19use tempfile::TempDir;
20use thread_worker::{WorkerHandle, Worker}; 20use thread_worker::{WorkerHandle, Worker};
21use test_utils::{parse_fixture, find_mismatch}; 21use test_utils::{parse_fixture, find_mismatch};
22 22
@@ -28,7 +28,7 @@ pub fn project(fixture: &str) -> Server {
28 static INIT: Once = Once::new(); 28 static INIT: Once = Once::new();
29 INIT.call_once(|| Logger::with_env_or_str(crate::LOG).start().unwrap()); 29 INIT.call_once(|| Logger::with_env_or_str(crate::LOG).start().unwrap());
30 30
31 let tmp_dir = TempDir::new("test-project").unwrap(); 31 let tmp_dir = TempDir::new().unwrap();
32 let mut paths = vec![]; 32 let mut paths = vec![];
33 33
34 for entry in parse_fixture(fixture) { 34 for entry in parse_fixture(fixture) {
@@ -118,7 +118,11 @@ impl Server {
118 } 118 }
119 fn send_request_(&self, r: RawRequest) -> Value { 119 fn send_request_(&self, r: RawRequest) -> Value {
120 let id = r.id; 120 let id = r.id;
121 self.worker.as_ref().unwrap().send(RawMessage::Request(r)); 121 self.worker
122 .as_ref()
123 .unwrap()
124 .send(RawMessage::Request(r))
125 .unwrap();
122 while let Some(msg) = self.recv() { 126 while let Some(msg) = self.recv() {
123 match msg { 127 match msg {
124 RawMessage::Request(req) => panic!("unexpected request: {:?}", req), 128 RawMessage::Request(req) => panic!("unexpected request: {:?}", req),
@@ -167,7 +171,8 @@ impl Server {
167 self.worker 171 self.worker
168 .as_ref() 172 .as_ref()
169 .unwrap() 173 .unwrap()
170 .send(RawMessage::Notification(not)); 174 .send(RawMessage::Notification(not))
175 .unwrap();
171 } 176 }
172} 177}
173 178
@@ -185,7 +190,7 @@ impl Drop for Server {
185fn recv_timeout(receiver: &Receiver<RawMessage>) -> Option<RawMessage> { 190fn recv_timeout(receiver: &Receiver<RawMessage>) -> Option<RawMessage> {
186 let timeout = Duration::from_secs(5); 191 let timeout = Duration::from_secs(5);
187 select! { 192 select! {
188 recv(receiver, msg) => msg, 193 recv(receiver) -> msg => msg.ok(),
189 recv(after(timeout)) => panic!("timed out"), 194 recv(after(timeout)) -> _ => panic!("timed out"),
190 } 195 }
191} 196}
diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs
index 64cdf0b1b..692ffbb8c 100644
--- a/crates/ra_syntax/src/grammar/patterns.rs
+++ b/crates/ra_syntax/src/grammar/patterns.rs
@@ -48,11 +48,16 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
48 // test literal_pattern 48 // test literal_pattern
49 // fn main() { 49 // fn main() {
50 // match () { 50 // match () {
51 // -1 => (),
51 // 92 => (), 52 // 92 => (),
52 // 'c' => (), 53 // 'c' => (),
53 // "hello" => (), 54 // "hello" => (),
54 // } 55 // }
55 // } 56 // }
57 if p.at(MINUS) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER) {
58 p.bump();
59 }
60
56 if let Some(m) = expressions::literal(p) { 61 if let Some(m) = expressions::literal(p) {
57 return Some(m); 62 return Some(m);
58 } 63 }
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.rs
index 16f674d9d..6dfd67b4c 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.rs
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.rs
@@ -1,5 +1,6 @@
1fn main() { 1fn main() {
2 match () { 2 match () {
3 -1 => (),
3 92 => (), 4 92 => (),
4 'c' => (), 5 'c' => (),
5 "hello" => (), 6 "hello" => (),
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt
index 99b289d56..71d62eaba 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 95) 1SOURCE_FILE@[0; 113)
2 FN_DEF@[0; 94) 2 FN_DEF@[0; 112)
3 FN_KW@[0; 2) 3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3) 4 WHITESPACE@[2; 3)
5 NAME@[3; 7) 5 NAME@[3; 7)
@@ -8,22 +8,23 @@ SOURCE_FILE@[0; 95)
8 L_PAREN@[7; 8) 8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9) 9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10) 10 WHITESPACE@[9; 10)
11 BLOCK@[10; 94) 11 BLOCK@[10; 112)
12 L_CURLY@[10; 11) 12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16) 13 WHITESPACE@[11; 16)
14 MATCH_EXPR@[16; 92) 14 MATCH_EXPR@[16; 110)
15 MATCH_KW@[16; 21) 15 MATCH_KW@[16; 21)
16 WHITESPACE@[21; 22) 16 WHITESPACE@[21; 22)
17 TUPLE_EXPR@[22; 24) 17 TUPLE_EXPR@[22; 24)
18 L_PAREN@[22; 23) 18 L_PAREN@[22; 23)
19 R_PAREN@[23; 24) 19 R_PAREN@[23; 24)
20 WHITESPACE@[24; 25) 20 WHITESPACE@[24; 25)
21 MATCH_ARM_LIST@[25; 92) 21 MATCH_ARM_LIST@[25; 110)
22 L_CURLY@[25; 26) 22 L_CURLY@[25; 26)
23 WHITESPACE@[26; 35) 23 WHITESPACE@[26; 35)
24 MATCH_ARM@[35; 43) 24 MATCH_ARM@[35; 43)
25 LITERAL@[35; 37) 25 MINUS@[35; 36)
26 INT_NUMBER@[35; 37) "92" 26 LITERAL@[36; 37)
27 INT_NUMBER@[36; 37) "1"
27 WHITESPACE@[37; 38) 28 WHITESPACE@[37; 38)
28 FAT_ARROW@[38; 40) 29 FAT_ARROW@[38; 40)
29 WHITESPACE@[40; 41) 30 WHITESPACE@[40; 41)
@@ -32,29 +33,40 @@ SOURCE_FILE@[0; 95)
32 R_PAREN@[42; 43) 33 R_PAREN@[42; 43)
33 COMMA@[43; 44) 34 COMMA@[43; 44)
34 WHITESPACE@[44; 53) 35 WHITESPACE@[44; 53)
35 MATCH_ARM@[53; 62) 36 MATCH_ARM@[53; 61)
36 LITERAL@[53; 56) 37 LITERAL@[53; 55)
37 CHAR@[53; 56) 38 INT_NUMBER@[53; 55) "92"
38 WHITESPACE@[56; 57) 39 WHITESPACE@[55; 56)
39 FAT_ARROW@[57; 59) 40 FAT_ARROW@[56; 58)
40 WHITESPACE@[59; 60) 41 WHITESPACE@[58; 59)
41 TUPLE_EXPR@[60; 62) 42 TUPLE_EXPR@[59; 61)
42 L_PAREN@[60; 61) 43 L_PAREN@[59; 60)
43 R_PAREN@[61; 62) 44 R_PAREN@[60; 61)
44 COMMA@[62; 63) 45 COMMA@[61; 62)
45 WHITESPACE@[63; 72) 46 WHITESPACE@[62; 71)
46 MATCH_ARM@[72; 85) 47 MATCH_ARM@[71; 80)
47 LITERAL@[72; 79) 48 LITERAL@[71; 74)
48 STRING@[72; 79) 49 CHAR@[71; 74)
49 WHITESPACE@[79; 80) 50 WHITESPACE@[74; 75)
50 FAT_ARROW@[80; 82) 51 FAT_ARROW@[75; 77)
51 WHITESPACE@[82; 83) 52 WHITESPACE@[77; 78)
52 TUPLE_EXPR@[83; 85) 53 TUPLE_EXPR@[78; 80)
53 L_PAREN@[83; 84) 54 L_PAREN@[78; 79)
54 R_PAREN@[84; 85) 55 R_PAREN@[79; 80)
55 COMMA@[85; 86) 56 COMMA@[80; 81)
56 WHITESPACE@[86; 91) 57 WHITESPACE@[81; 90)
57 R_CURLY@[91; 92) 58 MATCH_ARM@[90; 103)
58 WHITESPACE@[92; 93) 59 LITERAL@[90; 97)
59 R_CURLY@[93; 94) 60 STRING@[90; 97)
60 WHITESPACE@[94; 95) 61 WHITESPACE@[97; 98)
62 FAT_ARROW@[98; 100)
63 WHITESPACE@[100; 101)
64 TUPLE_EXPR@[101; 103)
65 L_PAREN@[101; 102)
66 R_PAREN@[102; 103)
67 COMMA@[103; 104)
68 WHITESPACE@[104; 109)
69 R_CURLY@[109; 110)
70 WHITESPACE@[110; 111)
71 R_CURLY@[111; 112)
72 WHITESPACE@[112; 113)
diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml
index ccea8a866..7c170cdfc 100644
--- a/crates/ra_vfs/Cargo.toml
+++ b/crates/ra_vfs/Cargo.toml
@@ -8,7 +8,7 @@ authors = ["Aleksey Kladov <[email protected]>"]
8walkdir = "2.2.7" 8walkdir = "2.2.7"
9relative-path = "0.4.0" 9relative-path = "0.4.0"
10rustc-hash = "1.0" 10rustc-hash = "1.0"
11crossbeam-channel = "0.2.4" 11crossbeam-channel = "0.3.5"
12log = "0.4.6" 12log = "0.4.6"
13 13
14thread_worker = { path = "../thread_worker" } 14thread_worker = { path = "../thread_worker" }
diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs
index 4cfdb83da..80328ad18 100644
--- a/crates/ra_vfs/src/io.rs
+++ b/crates/ra_vfs/src/io.rs
@@ -32,8 +32,10 @@ pub(crate) type Worker = thread_worker::Worker<Task, TaskResult>;
32pub(crate) fn start() -> (Worker, WorkerHandle) { 32pub(crate) fn start() -> (Worker, WorkerHandle) {
33 thread_worker::spawn("vfs", 128, |input_receiver, output_sender| { 33 thread_worker::spawn("vfs", 128, |input_receiver, output_sender| {
34 input_receiver 34 input_receiver
35 .into_iter()
35 .map(handle_task) 36 .map(handle_task)
36 .for_each(|it| output_sender.send(it)) 37 .try_for_each(|it| output_sender.send(it))
38 .unwrap()
37 }) 39 })
38} 40}
39 41
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs
index 90d5e21f4..757eac95b 100644
--- a/crates/ra_vfs/src/lib.rs
+++ b/crates/ra_vfs/src/lib.rs
@@ -148,7 +148,7 @@ impl Vfs {
148 path: path.clone(), 148 path: path.clone(),
149 filter: Box::new(filter), 149 filter: Box::new(filter),
150 }; 150 };
151 res.worker.inp.send(task); 151 res.worker.inp.send(task).unwrap();
152 } 152 }
153 let roots = res.roots.iter().map(|(id, _)| id).collect(); 153 let roots = res.roots.iter().map(|(id, _)| id).collect();
154 (res, roots) 154 (res, roots)
diff --git a/crates/thread_worker/Cargo.toml b/crates/thread_worker/Cargo.toml
index 62d66a1a3..c74b376e2 100644
--- a/crates/thread_worker/Cargo.toml
+++ b/crates/thread_worker/Cargo.toml
@@ -6,6 +6,6 @@ authors = ["Aleksey Kladov <[email protected]>"]
6 6
7[dependencies] 7[dependencies]
8drop_bomb = "0.1.0" 8drop_bomb = "0.1.0"
9crossbeam-channel = "0.2.4" 9crossbeam-channel = "0.3.5"
10log = "0.4.3" 10log = "0.4.3"
11 11
diff --git a/crates/thread_worker/src/lib.rs b/crates/thread_worker/src/lib.rs
index 12e8bf17e..5e46f62fe 100644
--- a/crates/thread_worker/src/lib.rs
+++ b/crates/thread_worker/src/lib.rs
@@ -2,7 +2,7 @@
2 2
3use std::thread; 3use std::thread;
4 4
5use crossbeam_channel::{bounded, unbounded, Receiver, Sender}; 5use crossbeam_channel::{bounded, unbounded, Receiver, Sender, RecvError, SendError};
6use drop_bomb::DropBomb; 6use drop_bomb::DropBomb;
7 7
8pub struct Worker<I, O> { 8pub struct Worker<I, O> {
@@ -34,10 +34,10 @@ impl<I, O> Worker<I, O> {
34 self.out 34 self.out
35 } 35 }
36 36
37 pub fn send(&self, item: I) { 37 pub fn send(&self, item: I) -> Result<(), SendError<I>> {
38 self.inp.send(item) 38 self.inp.send(item)
39 } 39 }
40 pub fn recv(&self) -> Option<O> { 40 pub fn recv(&self) -> Result<O, RecvError> {
41 self.out.recv() 41 self.out.recv()
42 } 42 }
43} 43}