aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yaml18
-rw-r--r--Cargo.lock20
-rw-r--r--crates/flycheck/src/lib.rs10
-rw-r--r--crates/ra_assists/src/ast_transform.rs2
-rw-r--r--crates/ra_assists/src/lib.rs25
-rw-r--r--crates/ra_assists/src/tests.rs2
-rw-r--r--crates/ra_hir/src/source_analyzer.rs7
-rw-r--r--crates/ra_hir_expand/src/hygiene.rs2
-rw-r--r--crates/ra_hir_expand/src/lib.rs3
-rw-r--r--crates/ra_ide/src/completion/complete_snippet.rs8
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs10
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs1
-rw-r--r--crates/ra_parser/src/parser.rs16
-rw-r--r--crates/ra_prof/src/memory_usage.rs2
-rw-r--r--crates/rust-analyzer/src/global_state.rs2
-rw-r--r--crates/rust-analyzer/src/handlers.rs2
-rw-r--r--crates/rust-analyzer/src/main_loop.rs15
-rw-r--r--crates/rust-analyzer/src/to_proto.rs8
-rw-r--r--docs/dev/README.md6
-rw-r--r--docs/dev/syntax.md2
-rw-r--r--editors/code/src/client.ts10
-rw-r--r--xtask/tests/tidy.rs15
22 files changed, 119 insertions, 67 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 2acd44012..f977c88be 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -88,11 +88,14 @@ jobs:
88 if: matrix.os == 'windows-latest' 88 if: matrix.os == 'windows-latest'
89 run: Remove-Item ./target/debug/xtask.exe, ./target/debug/deps/xtask.exe 89 run: Remove-Item ./target/debug/xtask.exe, ./target/debug/deps/xtask.exe
90 90
91 # Weird target to catch non-portable code 91 # Weird targets to catch non-portable code
92 rust-power: 92 rust-cross:
93 name: Rust Power 93 name: Rust Cross
94 runs-on: ubuntu-latest 94 runs-on: ubuntu-latest
95 95
96 env:
97 targets: "powerpc-unknown-linux-gnu x86_64-unknown-linux-musl"
98
96 steps: 99 steps:
97 - name: Checkout repository 100 - name: Checkout repository
98 uses: actions/checkout@v2 101 uses: actions/checkout@v2
@@ -103,7 +106,9 @@ jobs:
103 toolchain: stable 106 toolchain: stable
104 profile: minimal 107 profile: minimal
105 override: true 108 override: true
106 target: 'powerpc-unknown-linux-gnu' 109
110 - name: Install Rust targets
111 run: rustup target add ${{ env.targets }}
107 112
108 - name: Cache cargo directories 113 - name: Cache cargo directories
109 uses: actions/cache@v2 114 uses: actions/cache@v2
@@ -114,7 +119,10 @@ jobs:
114 key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 119 key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
115 120
116 - name: Check 121 - name: Check
117 run: cargo check --target=powerpc-unknown-linux-gnu --all-targets 122 run: |
123 for target in ${{ env.targets }}; do
124 cargo check --target=$target --all-targets
125 done
118 126
119 typescript: 127 typescript:
120 name: TypeScript 128 name: TypeScript
diff --git a/Cargo.lock b/Cargo.lock
index dc49fc4bd..265889162 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -418,9 +418,9 @@ dependencies = [
418 418
419[[package]] 419[[package]]
420name = "hashbrown" 420name = "hashbrown"
421version = "0.8.1" 421version = "0.8.2"
422source = "registry+https://github.com/rust-lang/crates.io-index" 422source = "registry+https://github.com/rust-lang/crates.io-index"
423checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" 423checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
424dependencies = [ 424dependencies = [
425 "autocfg", 425 "autocfg",
426] 426]
@@ -465,9 +465,9 @@ dependencies = [
465 465
466[[package]] 466[[package]]
467name = "indexmap" 467name = "indexmap"
468version = "1.5.0" 468version = "1.5.1"
469source = "registry+https://github.com/rust-lang/crates.io-index" 469source = "registry+https://github.com/rust-lang/crates.io-index"
470checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" 470checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9"
471dependencies = [ 471dependencies = [
472 "autocfg", 472 "autocfg",
473 "hashbrown", 473 "hashbrown",
@@ -852,9 +852,9 @@ dependencies = [
852 852
853[[package]] 853[[package]]
854name = "perf-event-open-sys" 854name = "perf-event-open-sys"
855version = "0.3.1" 855version = "0.3.2"
856source = "registry+https://github.com/rust-lang/crates.io-index" 856source = "registry+https://github.com/rust-lang/crates.io-index"
857checksum = "95db63e37862bc1b842135d2234ef9418f222cc660c6752f45e7cf9ddfb97f96" 857checksum = "83e7183862f36d10263d0a1ccaef50fef734ade948bf026afd1bd97355c78273"
858dependencies = [ 858dependencies = [
859 "libc", 859 "libc",
860] 860]
@@ -871,9 +871,9 @@ dependencies = [
871 871
872[[package]] 872[[package]]
873name = "pico-args" 873name = "pico-args"
874version = "0.3.3" 874version = "0.3.4"
875source = "registry+https://github.com/rust-lang/crates.io-index" 875source = "registry+https://github.com/rust-lang/crates.io-index"
876checksum = "1b1eee8b1f4966c8343d7ca0f5a8452cd35d5610a2e0efbe2a68cae44bef2046" 876checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1"
877 877
878[[package]] 878[[package]]
879name = "plain" 879name = "plain"
@@ -1694,9 +1694,9 @@ dependencies = [
1694 1694
1695[[package]] 1695[[package]]
1696name = "tracing-tree" 1696name = "tracing-tree"
1697version = "0.1.4" 1697version = "0.1.5"
1698source = "registry+https://github.com/rust-lang/crates.io-index" 1698source = "registry+https://github.com/rust-lang/crates.io-index"
1699checksum = "37ee7f0f53ed2093971a698db799ef56a2dfd89b32e3aeb5165f0e637a02be04" 1699checksum = "e1a3dc4774db3a6b2d66a4f8d8de670e874ec3ed55615860c994927419b32c5f"
1700dependencies = [ 1700dependencies = [
1701 "ansi_term", 1701 "ansi_term",
1702 "atty", 1702 "atty",
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs
index 7c38f5ef9..31e14246d 100644
--- a/crates/flycheck/src/lib.rs
+++ b/crates/flycheck/src/lib.rs
@@ -1,4 +1,4 @@
1//! cargo_check provides the functionality needed to run `cargo check` or 1//! Flycheck provides the functionality needed to run `cargo check` or
2//! another compatible command (f.x. clippy) in a background thread and provide 2//! another compatible command (f.x. clippy) in a background thread and provide
3//! LSP diagnostics based on the output of the command. 3//! LSP diagnostics based on the output of the command.
4 4
@@ -147,6 +147,12 @@ impl FlycheckActor {
147 // avoid busy-waiting. 147 // avoid busy-waiting.
148 let cargo_handle = self.cargo_handle.take().unwrap(); 148 let cargo_handle = self.cargo_handle.take().unwrap();
149 let res = cargo_handle.join(); 149 let res = cargo_handle.join();
150 if res.is_err() {
151 log::error!(
152 "Flycheck failed to run the following command: {:?}",
153 self.check_command()
154 )
155 }
150 self.send(Message::Progress(Progress::DidFinish(res))); 156 self.send(Message::Progress(Progress::DidFinish(res)));
151 } 157 }
152 Event::CheckEvent(Some(message)) => match message { 158 Event::CheckEvent(Some(message)) => match message {
@@ -253,7 +259,7 @@ impl CargoHandle {
253 return Err(io::Error::new( 259 return Err(io::Error::new(
254 io::ErrorKind::Other, 260 io::ErrorKind::Other,
255 format!( 261 format!(
256 "Cargo watcher failed,the command produced no valid metadata (exit code: {:?})", 262 "Cargo watcher failed, the command produced no valid metadata (exit code: {:?})",
257 exit_status 263 exit_status
258 ), 264 ),
259 )); 265 ));
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs
index 15ec75c95..07c978378 100644
--- a/crates/ra_assists/src/ast_transform.rs
+++ b/crates/ra_assists/src/ast_transform.rs
@@ -51,7 +51,7 @@ impl<'a> SubstituteTypeParams<'a> {
51 // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky 51 // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky
52 .skip(1) 52 .skip(1)
53 // The actual list of trait type parameters may be longer than the one 53 // The actual list of trait type parameters may be longer than the one
54 // used in the `impl` block due to trailing default type parametrs. 54 // used in the `impl` block due to trailing default type parameters.
55 // For that case we extend the `substs` with an empty iterator so we 55 // For that case we extend the `substs` with an empty iterator so we
56 // can still hit those trailing values and check if they actually have 56 // can still hit those trailing values and check if they actually have
57 // a default type. If they do, go for that type from `hir` to `ast` so 57 // a default type. If they do, go for that type from `hir` to `ast` so
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 507646cc8..890996a68 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -66,13 +66,13 @@ pub struct GroupLabel(pub String);
66 66
67#[derive(Debug, Clone)] 67#[derive(Debug, Clone)]
68pub struct Assist { 68pub struct Assist {
69 pub id: AssistId, 69 id: AssistId,
70 /// Short description of the assist, as shown in the UI. 70 /// Short description of the assist, as shown in the UI.
71 pub label: String, 71 label: String,
72 pub group: Option<GroupLabel>, 72 group: Option<GroupLabel>,
73 /// Target ranges are used to sort assists: the smaller the target range, 73 /// Target ranges are used to sort assists: the smaller the target range,
74 /// the more specific assist is, and so it should be sorted first. 74 /// the more specific assist is, and so it should be sorted first.
75 pub target: TextRange, 75 target: TextRange,
76} 76}
77 77
78#[derive(Debug, Clone)] 78#[derive(Debug, Clone)]
@@ -120,10 +120,25 @@ impl Assist {
120 group: Option<GroupLabel>, 120 group: Option<GroupLabel>,
121 target: TextRange, 121 target: TextRange,
122 ) -> Assist { 122 ) -> Assist {
123 // FIXME: make fields private, so that this invariant can't be broken
124 assert!(label.starts_with(|c: char| c.is_uppercase())); 123 assert!(label.starts_with(|c: char| c.is_uppercase()));
125 Assist { id, label, group, target } 124 Assist { id, label, group, target }
126 } 125 }
126
127 pub fn id(&self) -> AssistId {
128 self.id
129 }
130
131 pub fn label(&self) -> String {
132 self.label.clone()
133 }
134
135 pub fn group(&self) -> Option<GroupLabel> {
136 self.group.clone()
137 }
138
139 pub fn target(&self) -> TextRange {
140 self.target
141 }
127} 142}
128 143
129mod handlers { 144mod handlers {
diff --git a/crates/ra_assists/src/tests.rs b/crates/ra_assists/src/tests.rs
index 18fcb9049..e73836422 100644
--- a/crates/ra_assists/src/tests.rs
+++ b/crates/ra_assists/src/tests.rs
@@ -20,7 +20,7 @@ pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_
20 20
21// FIXME: instead of having a separate function here, maybe use 21// FIXME: instead of having a separate function here, maybe use
22// `extract_ranges` and mark the target as `<target> </target>` in the 22// `extract_ranges` and mark the target as `<target> </target>` in the
23// fixuture? 23// fixture?
24pub(crate) fn check_assist_target(assist: Handler, ra_fixture: &str, target: &str) { 24pub(crate) fn check_assist_target(assist: Handler, ra_fixture: &str, target: &str) {
25 check(assist, ra_fixture, ExpectedResult::Target(target)); 25 check(assist, ra_fixture, ExpectedResult::Target(target));
26} 26}
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index d0cb62ef0..d3d62debf 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -265,8 +265,7 @@ impl SourceAnalyzer {
265 } 265 }
266 266
267 // This must be a normal source file rather than macro file. 267 // This must be a normal source file rather than macro file.
268 let hir_path = 268 let hir_path = Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?;
269 crate::Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?;
270 269
271 // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we 270 // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we
272 // trying to resolve foo::bar. 271 // trying to resolve foo::bar.
@@ -451,7 +450,7 @@ fn adjust(
451pub(crate) fn resolve_hir_path( 450pub(crate) fn resolve_hir_path(
452 db: &dyn HirDatabase, 451 db: &dyn HirDatabase,
453 resolver: &Resolver, 452 resolver: &Resolver,
454 path: &crate::Path, 453 path: &Path,
455) -> Option<PathResolution> { 454) -> Option<PathResolution> {
456 let types = 455 let types =
457 resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty { 456 resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty {
@@ -512,7 +511,7 @@ pub(crate) fn resolve_hir_path(
512pub(crate) fn resolve_hir_path_qualifier( 511pub(crate) fn resolve_hir_path_qualifier(
513 db: &dyn HirDatabase, 512 db: &dyn HirDatabase,
514 resolver: &Resolver, 513 resolver: &Resolver,
515 path: &crate::Path, 514 path: &Path,
516) -> Option<PathResolution> { 515) -> Option<PathResolution> {
517 let items = resolver 516 let items = resolver
518 .resolve_module_path_in_items(db.upcast(), path.mod_path()) 517 .resolve_module_path_in_items(db.upcast(), path.mod_path())
diff --git a/crates/ra_hir_expand/src/hygiene.rs b/crates/ra_hir_expand/src/hygiene.rs
index 6b482a60c..aefe47bd3 100644
--- a/crates/ra_hir_expand/src/hygiene.rs
+++ b/crates/ra_hir_expand/src/hygiene.rs
@@ -17,7 +17,7 @@ pub struct Hygiene {
17 // This is what `$crate` expands to 17 // This is what `$crate` expands to
18 def_crate: Option<CrateId>, 18 def_crate: Option<CrateId>,
19 19
20 // Indiciate this is a local inner macro 20 // Indicate this is a local inner macro
21 local_inner: bool, 21 local_inner: bool,
22} 22}
23 23
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 2e8d63691..8bb735fc6 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -44,7 +44,8 @@ mod test_db;
44/// containing the call plus the offset of the macro call in the file. Note that 44/// containing the call plus the offset of the macro call in the file. Note that
45/// this is a recursive definition! However, the size_of of `HirFileId` is 45/// this is a recursive definition! However, the size_of of `HirFileId` is
46/// finite (because everything bottoms out at the real `FileId`) and small 46/// finite (because everything bottoms out at the real `FileId`) and small
47/// (`MacroCallId` uses the location interner). 47/// (`MacroCallId` uses the location interning. You can check details here:
48/// https://en.wikipedia.org/wiki/String_interning).
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
49pub struct HirFileId(HirFileIdRepr); 50pub struct HirFileId(HirFileIdRepr);
50 51
diff --git a/crates/ra_ide/src/completion/complete_snippet.rs b/crates/ra_ide/src/completion/complete_snippet.rs
index 28d8f7876..4368e4eec 100644
--- a/crates/ra_ide/src/completion/complete_snippet.rs
+++ b/crates/ra_ide/src/completion/complete_snippet.rs
@@ -36,7 +36,7 @@ pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionConte
36 snippet( 36 snippet(
37 ctx, 37 ctx,
38 cap, 38 cap,
39 "Test module", 39 "tmod (Test module)",
40 "\ 40 "\
41#[cfg(test)] 41#[cfg(test)]
42mod tests { 42mod tests {
@@ -54,7 +54,7 @@ mod tests {
54 snippet( 54 snippet(
55 ctx, 55 ctx,
56 cap, 56 cap,
57 "Test function", 57 "tfn (Test function)",
58 "\ 58 "\
59#[test] 59#[test]
60fn ${1:feature}() { 60fn ${1:feature}() {
@@ -106,10 +106,10 @@ mod tests {
106} 106}
107"#, 107"#,
108 expect![[r#" 108 expect![[r#"
109 sn Test function
110 sn Test module
111 sn macro_rules 109 sn macro_rules
112 sn pub(crate) 110 sn pub(crate)
111 sn tfn (Test function)
112 sn tmod (Test module)
113 "#]], 113 "#]],
114 ) 114 )
115 } 115 }
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index 6b03b30bb..4aa761148 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -27,7 +27,7 @@ pub(crate) struct CompletionContext<'a> {
27 pub(super) scope: SemanticsScope<'a>, 27 pub(super) scope: SemanticsScope<'a>,
28 pub(super) db: &'a RootDatabase, 28 pub(super) db: &'a RootDatabase,
29 pub(super) config: &'a CompletionConfig, 29 pub(super) config: &'a CompletionConfig,
30 pub(super) offset: TextSize, 30 pub(super) position: FilePosition,
31 /// The token before the cursor, in the original file. 31 /// The token before the cursor, in the original file.
32 pub(super) original_token: SyntaxToken, 32 pub(super) original_token: SyntaxToken,
33 /// The token before the cursor, in the macro-expanded file. 33 /// The token before the cursor, in the macro-expanded file.
@@ -117,7 +117,7 @@ impl<'a> CompletionContext<'a> {
117 config, 117 config,
118 original_token, 118 original_token,
119 token, 119 token,
120 offset: position.offset, 120 position,
121 krate, 121 krate,
122 expected_type: None, 122 expected_type: None,
123 name_ref_syntax: None, 123 name_ref_syntax: None,
@@ -209,7 +209,7 @@ impl<'a> CompletionContext<'a> {
209 mark::hit!(completes_if_prefix_is_keyword); 209 mark::hit!(completes_if_prefix_is_keyword);
210 self.original_token.text_range() 210 self.original_token.text_range()
211 } else { 211 } else {
212 TextRange::empty(self.offset) 212 TextRange::empty(self.position.offset)
213 } 213 }
214 } 214 }
215 215
@@ -379,8 +379,8 @@ impl<'a> CompletionContext<'a> {
379 self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some(); 379 self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
380 self.has_type_args = segment.generic_arg_list().is_some(); 380 self.has_type_args = segment.generic_arg_list().is_some();
381 381
382 #[allow(deprecated)] 382 let hygiene = hir::Hygiene::new(self.db, self.position.file_id.into());
383 if let Some(path) = hir::Path::from_ast(path.clone()) { 383 if let Some(path) = hir::Path::from_src(path.clone(), &hygiene) {
384 if let Some(path_prefix) = path.qualifier() { 384 if let Some(path_prefix) = path.qualifier() {
385 self.path_prefix = Some(path_prefix); 385 self.path_prefix = Some(path_prefix);
386 return; 386 return;
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index e1c25a838..51eaf7af6 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -509,7 +509,6 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
509// x.1i32; 509// x.1i32;
510// x.0x01; 510// x.0x01;
511// } 511// }
512#[allow(clippy::if_same_then_else)]
513fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 512fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
514 assert!(p.at(T![.])); 513 assert!(p.at(T![.]));
515 let m = lhs.precede(p); 514 let m = lhs.precede(p);
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs
index d797f2cc9..d2487acc3 100644
--- a/crates/ra_parser/src/parser.rs
+++ b/crates/ra_parser/src/parser.rs
@@ -269,8 +269,8 @@ impl Marker {
269 pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { 269 pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
270 self.bomb.defuse(); 270 self.bomb.defuse();
271 let idx = self.pos as usize; 271 let idx = self.pos as usize;
272 match p.events[idx] { 272 match &mut p.events[idx] {
273 Event::Start { kind: ref mut slot, .. } => { 273 Event::Start { kind: slot, .. } => {
274 *slot = kind; 274 *slot = kind;
275 } 275 }
276 _ => unreachable!(), 276 _ => unreachable!(),
@@ -320,8 +320,8 @@ impl CompletedMarker {
320 pub(crate) fn precede(self, p: &mut Parser) -> Marker { 320 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
321 let new_pos = p.start(); 321 let new_pos = p.start();
322 let idx = self.start_pos as usize; 322 let idx = self.start_pos as usize;
323 match p.events[idx] { 323 match &mut p.events[idx] {
324 Event::Start { ref mut forward_parent, .. } => { 324 Event::Start { forward_parent, .. } => {
325 *forward_parent = Some(new_pos.pos - self.start_pos); 325 *forward_parent = Some(new_pos.pos - self.start_pos);
326 } 326 }
327 _ => unreachable!(), 327 _ => unreachable!(),
@@ -333,12 +333,12 @@ impl CompletedMarker {
333 pub(crate) fn undo_completion(self, p: &mut Parser) -> Marker { 333 pub(crate) fn undo_completion(self, p: &mut Parser) -> Marker {
334 let start_idx = self.start_pos as usize; 334 let start_idx = self.start_pos as usize;
335 let finish_idx = self.finish_pos as usize; 335 let finish_idx = self.finish_pos as usize;
336 match p.events[start_idx] { 336 match &mut p.events[start_idx] {
337 Event::Start { ref mut kind, forward_parent: None } => *kind = TOMBSTONE, 337 Event::Start { kind, forward_parent: None } => *kind = TOMBSTONE,
338 _ => unreachable!(), 338 _ => unreachable!(),
339 } 339 }
340 match p.events[finish_idx] { 340 match &mut p.events[finish_idx] {
341 ref mut slot @ Event::Finish => *slot = Event::tombstone(), 341 slot @ Event::Finish => *slot = Event::tombstone(),
342 _ => unreachable!(), 342 _ => unreachable!(),
343 } 343 }
344 Marker::new(self.start_pos) 344 Marker::new(self.start_pos)
diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs
index c2ecbd33c..83390212a 100644
--- a/crates/ra_prof/src/memory_usage.rs
+++ b/crates/ra_prof/src/memory_usage.rs
@@ -24,7 +24,7 @@ impl std::ops::Sub for MemoryUsage {
24impl MemoryUsage { 24impl MemoryUsage {
25 pub fn current() -> MemoryUsage { 25 pub fn current() -> MemoryUsage {
26 cfg_if! { 26 cfg_if! {
27 if #[cfg(target_os = "linux")] { 27 if #[cfg(all(target_os = "linux", target_env = "gnu"))] {
28 // Note: This is incredibly slow. 28 // Note: This is incredibly slow.
29 let alloc = unsafe { libc::mallinfo() }.uordblks as isize; 29 let alloc = unsafe { libc::mallinfo() }.uordblks as isize;
30 MemoryUsage { allocated: Bytes(alloc) } 30 MemoryUsage { allocated: Bytes(alloc) }
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 0e592ac1b..658a50d15 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -73,6 +73,7 @@ pub(crate) struct GlobalState {
73 pub(crate) mem_docs: FxHashMap<VfsPath, DocumentData>, 73 pub(crate) mem_docs: FxHashMap<VfsPath, DocumentData>,
74 pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>, 74 pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
75 pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, 75 pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
76 pub(crate) shutdown_requested: bool,
76 pub(crate) status: Status, 77 pub(crate) status: Status,
77 pub(crate) source_root_config: SourceRootConfig, 78 pub(crate) source_root_config: SourceRootConfig,
78 pub(crate) proc_macro_client: ProcMacroClient, 79 pub(crate) proc_macro_client: ProcMacroClient,
@@ -124,6 +125,7 @@ impl GlobalState {
124 mem_docs: FxHashMap::default(), 125 mem_docs: FxHashMap::default(),
125 semantic_tokens_cache: Arc::new(Default::default()), 126 semantic_tokens_cache: Arc::new(Default::default()),
126 vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))), 127 vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))),
128 shutdown_requested: false,
127 status: Status::default(), 129 status: Status::default(),
128 source_root_config: SourceRootConfig::default(), 130 source_root_config: SourceRootConfig::default(),
129 proc_macro_client: ProcMacroClient::dummy(), 131 proc_macro_client: ProcMacroClient::dummy(),
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 895af1dd7..c2afcf192 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -864,7 +864,7 @@ pub(crate) fn handle_resolve_code_action(
864 let (id_string, index) = split_once(&params.id, ':').unwrap(); 864 let (id_string, index) = split_once(&params.id, ':').unwrap();
865 let index = index.parse::<usize>().unwrap(); 865 let index = index.parse::<usize>().unwrap();
866 let assist = &assists[index]; 866 let assist = &assists[index];
867 assert!(assist.assist.id.0 == id_string); 867 assert!(assist.assist.id().0 == id_string);
868 Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit) 868 Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit)
869} 869}
870 870
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 0ac6434dd..e6cf46df2 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -337,6 +337,16 @@ impl GlobalState {
337 fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> { 337 fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
338 self.register_request(&req, request_received); 338 self.register_request(&req, request_received);
339 339
340 if self.shutdown_requested {
341 self.respond(Response::new_err(
342 req.id,
343 lsp_server::ErrorCode::InvalidRequest as i32,
344 "Shutdown already requested.".to_owned(),
345 ));
346
347 return Ok(());
348 }
349
340 if self.status == Status::Loading && req.method != "shutdown" { 350 if self.status == Status::Loading && req.method != "shutdown" {
341 self.respond(lsp_server::Response::new_err( 351 self.respond(lsp_server::Response::new_err(
342 req.id, 352 req.id,
@@ -351,7 +361,10 @@ impl GlobalState {
351 .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))? 361 .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
352 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))? 362 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
353 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))? 363 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))?
354 .on_sync::<lsp_types::request::Shutdown>(|_, ()| Ok(()))? 364 .on_sync::<lsp_types::request::Shutdown>(|s, ()| {
365 s.shutdown_requested = true;
366 Ok(())
367 })?
355 .on_sync::<lsp_types::request::SelectionRangeRequest>(|s, p| { 368 .on_sync::<lsp_types::request::SelectionRangeRequest>(|s, p| {
356 handlers::handle_selection_range(s.snapshot(), p) 369 handlers::handle_selection_range(s.snapshot(), p)
357 })? 370 })?
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 27460db78..62fda8a1f 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -704,10 +704,10 @@ pub(crate) fn unresolved_code_action(
704 index: usize, 704 index: usize,
705) -> Result<lsp_ext::CodeAction> { 705) -> Result<lsp_ext::CodeAction> {
706 let res = lsp_ext::CodeAction { 706 let res = lsp_ext::CodeAction {
707 title: assist.label, 707 title: assist.label(),
708 id: Some(format!("{}:{}", assist.id.0.to_owned(), index.to_string())), 708 id: Some(format!("{}:{}", assist.id().0.to_owned(), index.to_string())),
709 group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), 709 group: assist.group().filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
710 kind: Some(code_action_kind(assist.id.1)), 710 kind: Some(code_action_kind(assist.id().1)),
711 edit: None, 711 edit: None,
712 is_preferred: None, 712 is_preferred: None,
713 }; 713 };
diff --git a/docs/dev/README.md b/docs/dev/README.md
index 67813a9c0..51cf716b3 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -256,9 +256,9 @@ Release steps:
256 * checkout the `release` branch 256 * checkout the `release` branch
257 * reset it to `upstream/nightly` 257 * reset it to `upstream/nightly`
258 * push it to `upstream`. This triggers GitHub Actions which: 258 * push it to `upstream`. This triggers GitHub Actions which:
259 ** runs `cargo xtask dist` to package binaries and VS Code extension 259 * runs `cargo xtask dist` to package binaries and VS Code extension
260 ** makes a GitHub release 260 * makes a GitHub release
261 ** pushes VS Code extension to the marketplace 261 * pushes VS Code extension to the marketplace
262 * create new changelog in `rust-analyzer.github.io` 262 * create new changelog in `rust-analyzer.github.io`
263 * create `rust-analyzer.github.io/git.log` file with the log of merge commits since last release 263 * create `rust-analyzer.github.io/git.log` file with the log of merge commits since last release
2642. While the release is in progress, fill-in the changelog using `git.log` 2642. While the release is in progress, fill-in the changelog using `git.log`
diff --git a/docs/dev/syntax.md b/docs/dev/syntax.md
index d4bc4b07c..f1bcdc4af 100644
--- a/docs/dev/syntax.md
+++ b/docs/dev/syntax.md
@@ -74,7 +74,7 @@ Points of note:
74* The original text can be recovered by concatenating the texts of all tokens in order. 74* The original text can be recovered by concatenating the texts of all tokens in order.
75* Accessing a child of particular type (for example, parameter list of a function) generally involves linerary traversing the children, looking for a specific `kind`. 75* Accessing a child of particular type (for example, parameter list of a function) generally involves linerary traversing the children, looking for a specific `kind`.
76* Modifying the tree is roughly `O(depth)`. 76* Modifying the tree is roughly `O(depth)`.
77 We don't make special efforts to guarantree that the depth is not liner, but, in practice, syntax trees are branchy and shallow. 77 We don't make special efforts to guarantee that the depth is not linear, but, in practice, syntax trees are branchy and shallow.
78* If mandatory (grammar wise) node is missing from the input, it's just missing from the tree. 78* If mandatory (grammar wise) node is missing from the input, it's just missing from the tree.
79* If an extra erroneous input is present, it is wrapped into a node with `ERROR` kind, and treated just like any other node. 79* If an extra erroneous input is present, it is wrapped into a node with `ERROR` kind, and treated just like any other node.
80* Parser errors are not a part of syntax tree. 80* Parser errors are not a part of syntax tree.
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 18948cb3c..f5db55b8c 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -4,7 +4,7 @@ import * as ra from '../src/lsp_ext';
4import * as Is from 'vscode-languageclient/lib/utils/is'; 4import * as Is from 'vscode-languageclient/lib/utils/is';
5 5
6import { CallHierarchyFeature } from 'vscode-languageclient/lib/callHierarchy.proposed'; 6import { CallHierarchyFeature } from 'vscode-languageclient/lib/callHierarchy.proposed';
7import { SemanticTokensFeature, DocumentSemanticsTokensSignature } from 'vscode-languageclient/lib/semanticTokens.proposed'; 7import { SemanticTokensFeature } from 'vscode-languageclient/lib/semanticTokens.proposed';
8import { assert } from './util'; 8import { assert } from './util';
9 9
10function renderCommand(cmd: ra.CommandLink) { 10function renderCommand(cmd: ra.CommandLink) {
@@ -44,12 +44,6 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
44 diagnosticCollectionName: "rustc", 44 diagnosticCollectionName: "rustc",
45 traceOutputChannel, 45 traceOutputChannel,
46 middleware: { 46 middleware: {
47 // Workaround for https://github.com/microsoft/vscode-languageserver-node/issues/576
48 async provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken, next: DocumentSemanticsTokensSignature) {
49 const res = await next(document, token);
50 if (res === undefined) throw new Error('busy');
51 return res;
52 },
53 async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) { 47 async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) {
54 return client.sendRequest(lc.HoverRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then( 48 return client.sendRequest(lc.HoverRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then(
55 (result) => { 49 (result) => {
@@ -135,7 +129,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
135 ); 129 );
136 } 130 }
137 131
138 } as any 132 }
139 }; 133 };
140 134
141 const client = new lc.LanguageClient( 135 const client = new lc.LanguageClient(
diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs
index d65a2acbc..4ff72865e 100644
--- a/xtask/tests/tidy.rs
+++ b/xtask/tests/tidy.rs
@@ -44,11 +44,26 @@ fn rust_files_are_tidy() {
44 let text = fs2::read_to_string(&path).unwrap(); 44 let text = fs2::read_to_string(&path).unwrap();
45 check_todo(&path, &text); 45 check_todo(&path, &text);
46 check_trailing_ws(&path, &text); 46 check_trailing_ws(&path, &text);
47 deny_clippy(&path, &text);
47 tidy_docs.visit(&path, &text); 48 tidy_docs.visit(&path, &text);
48 } 49 }
49 tidy_docs.finish(); 50 tidy_docs.finish();
50} 51}
51 52
53fn deny_clippy(path: &PathBuf, text: &String) {
54 if text.contains("[\u{61}llow(clippy") {
55 panic!(
56 "\n\nallowing lints is forbidden: {}.
57rust-analyzer intentionally doesn't check clippy on CI.
58You can allow lint globally via `xtask clippy`.
59See https://github.com/rust-lang/rust-clippy/issues/5537 for discussion.
60
61",
62 path.display()
63 )
64 }
65}
66
52#[test] 67#[test]
53fn check_licenses() { 68fn check_licenses() {
54 let expected = " 69 let expected = "