diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/flycheck/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/flycheck/src/lib.rs | 68 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/Cargo.toml | 6 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/extract_function.rs | 36 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 9 | ||||
-rw-r--r-- | crates/rust-analyzer/src/diagnostics.rs | 1 | ||||
-rw-r--r-- | crates/rust-analyzer/src/diagnostics/to_proto.rs | 56 | ||||
-rw-r--r-- | crates/syntax/Cargo.toml | 2 |
9 files changed, 123 insertions, 63 deletions
diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml index 2a1a21b28..18b9ce7df 100644 --- a/crates/flycheck/Cargo.toml +++ b/crates/flycheck/Cargo.toml | |||
@@ -13,6 +13,7 @@ doctest = false | |||
13 | crossbeam-channel = "0.5.0" | 13 | crossbeam-channel = "0.5.0" |
14 | log = "0.4.8" | 14 | log = "0.4.8" |
15 | cargo_metadata = "0.13" | 15 | cargo_metadata = "0.13" |
16 | serde = { version = "1.0.106", features = ["derive"] } | ||
16 | serde_json = "1.0.48" | 17 | serde_json = "1.0.48" |
17 | jod-thread = "0.1.1" | 18 | jod-thread = "0.1.1" |
18 | 19 | ||
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index e2a59497a..1682d8bde 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs | |||
@@ -4,13 +4,14 @@ | |||
4 | 4 | ||
5 | use std::{ | 5 | use std::{ |
6 | fmt, | 6 | fmt, |
7 | io::{self, BufReader}, | 7 | io::{self, BufRead, BufReader}, |
8 | path::PathBuf, | 8 | path::PathBuf, |
9 | process::{self, Command, Stdio}, | 9 | process::{self, Command, Stdio}, |
10 | time::Duration, | 10 | time::Duration, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; | 13 | use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; |
14 | use serde::Deserialize; | ||
14 | use stdx::JodChild; | 15 | use stdx::JodChild; |
15 | 16 | ||
16 | pub use cargo_metadata::diagnostic::{ | 17 | pub use cargo_metadata::diagnostic::{ |
@@ -128,7 +129,7 @@ struct FlycheckActor { | |||
128 | 129 | ||
129 | enum Event { | 130 | enum Event { |
130 | Restart(Restart), | 131 | Restart(Restart), |
131 | CheckEvent(Option<cargo_metadata::Message>), | 132 | CheckEvent(Option<CargoMessage>), |
132 | } | 133 | } |
133 | 134 | ||
134 | impl FlycheckActor { | 135 | impl FlycheckActor { |
@@ -180,21 +181,16 @@ impl FlycheckActor { | |||
180 | self.progress(Progress::DidFinish(res)); | 181 | self.progress(Progress::DidFinish(res)); |
181 | } | 182 | } |
182 | Event::CheckEvent(Some(message)) => match message { | 183 | Event::CheckEvent(Some(message)) => match message { |
183 | cargo_metadata::Message::CompilerArtifact(msg) => { | 184 | CargoMessage::CompilerArtifact(msg) => { |
184 | self.progress(Progress::DidCheckCrate(msg.target.name)); | 185 | self.progress(Progress::DidCheckCrate(msg.target.name)); |
185 | } | 186 | } |
186 | 187 | ||
187 | cargo_metadata::Message::CompilerMessage(msg) => { | 188 | CargoMessage::Diagnostic(msg) => { |
188 | self.send(Message::AddDiagnostic { | 189 | self.send(Message::AddDiagnostic { |
189 | workspace_root: self.workspace_root.clone(), | 190 | workspace_root: self.workspace_root.clone(), |
190 | diagnostic: msg.message, | 191 | diagnostic: msg, |
191 | }); | 192 | }); |
192 | } | 193 | } |
193 | |||
194 | cargo_metadata::Message::BuildScriptExecuted(_) | ||
195 | | cargo_metadata::Message::BuildFinished(_) | ||
196 | | cargo_metadata::Message::TextLine(_) | ||
197 | | _ => {} | ||
198 | }, | 194 | }, |
199 | } | 195 | } |
200 | } | 196 | } |
@@ -261,7 +257,7 @@ struct CargoHandle { | |||
261 | child: JodChild, | 257 | child: JodChild, |
262 | #[allow(unused)] | 258 | #[allow(unused)] |
263 | thread: jod_thread::JoinHandle<io::Result<bool>>, | 259 | thread: jod_thread::JoinHandle<io::Result<bool>>, |
264 | receiver: Receiver<cargo_metadata::Message>, | 260 | receiver: Receiver<CargoMessage>, |
265 | } | 261 | } |
266 | 262 | ||
267 | impl CargoHandle { | 263 | impl CargoHandle { |
@@ -294,14 +290,11 @@ impl CargoHandle { | |||
294 | 290 | ||
295 | struct CargoActor { | 291 | struct CargoActor { |
296 | child_stdout: process::ChildStdout, | 292 | child_stdout: process::ChildStdout, |
297 | sender: Sender<cargo_metadata::Message>, | 293 | sender: Sender<CargoMessage>, |
298 | } | 294 | } |
299 | 295 | ||
300 | impl CargoActor { | 296 | impl CargoActor { |
301 | fn new( | 297 | fn new(child_stdout: process::ChildStdout, sender: Sender<CargoMessage>) -> CargoActor { |
302 | child_stdout: process::ChildStdout, | ||
303 | sender: Sender<cargo_metadata::Message>, | ||
304 | ) -> CargoActor { | ||
305 | CargoActor { child_stdout, sender } | 298 | CargoActor { child_stdout, sender } |
306 | } | 299 | } |
307 | fn run(self) -> io::Result<bool> { | 300 | fn run(self) -> io::Result<bool> { |
@@ -315,7 +308,7 @@ impl CargoActor { | |||
315 | // erroneus output. | 308 | // erroneus output. |
316 | let stdout = BufReader::new(self.child_stdout); | 309 | let stdout = BufReader::new(self.child_stdout); |
317 | let mut read_at_least_one_message = false; | 310 | let mut read_at_least_one_message = false; |
318 | for message in cargo_metadata::Message::parse_stream(stdout) { | 311 | for message in stdout.lines() { |
319 | let message = match message { | 312 | let message = match message { |
320 | Ok(message) => message, | 313 | Ok(message) => message, |
321 | Err(err) => { | 314 | Err(err) => { |
@@ -326,13 +319,44 @@ impl CargoActor { | |||
326 | 319 | ||
327 | read_at_least_one_message = true; | 320 | read_at_least_one_message = true; |
328 | 321 | ||
329 | // Skip certain kinds of messages to only spend time on what's useful | 322 | // Try to deserialize a message from Cargo or Rustc. |
330 | match &message { | 323 | let mut deserializer = serde_json::Deserializer::from_str(&message); |
331 | cargo_metadata::Message::CompilerArtifact(artifact) if artifact.fresh => (), | 324 | deserializer.disable_recursion_limit(); |
332 | cargo_metadata::Message::BuildScriptExecuted(_) => (), | 325 | if let Ok(message) = JsonMessage::deserialize(&mut deserializer) { |
333 | _ => self.sender.send(message).unwrap(), | 326 | match message { |
327 | // Skip certain kinds of messages to only spend time on what's useful | ||
328 | JsonMessage::Cargo(message) => match message { | ||
329 | cargo_metadata::Message::CompilerArtifact(artifact) if !artifact.fresh => { | ||
330 | self.sender.send(CargoMessage::CompilerArtifact(artifact)).unwrap() | ||
331 | } | ||
332 | cargo_metadata::Message::CompilerMessage(msg) => { | ||
333 | self.sender.send(CargoMessage::Diagnostic(msg.message)).unwrap() | ||
334 | } | ||
335 | |||
336 | cargo_metadata::Message::CompilerArtifact(_) | ||
337 | | cargo_metadata::Message::BuildScriptExecuted(_) | ||
338 | | cargo_metadata::Message::BuildFinished(_) | ||
339 | | cargo_metadata::Message::TextLine(_) | ||
340 | | _ => (), | ||
341 | }, | ||
342 | JsonMessage::Rustc(message) => { | ||
343 | self.sender.send(CargoMessage::Diagnostic(message)).unwrap() | ||
344 | } | ||
345 | } | ||
334 | } | 346 | } |
335 | } | 347 | } |
336 | Ok(read_at_least_one_message) | 348 | Ok(read_at_least_one_message) |
337 | } | 349 | } |
338 | } | 350 | } |
351 | |||
352 | enum CargoMessage { | ||
353 | CompilerArtifact(cargo_metadata::Artifact), | ||
354 | Diagnostic(Diagnostic), | ||
355 | } | ||
356 | |||
357 | #[derive(Deserialize)] | ||
358 | #[serde(untagged)] | ||
359 | enum JsonMessage { | ||
360 | Cargo(cargo_metadata::Message), | ||
361 | Rustc(Diagnostic), | ||
362 | } | ||
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 16a94a058..eaeca01bd 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -196,13 +196,6 @@ impl ItemTree { | |||
196 | self.raw_attrs(of).clone().filter(db, krate) | 196 | self.raw_attrs(of).clone().filter(db, krate) |
197 | } | 197 | } |
198 | 198 | ||
199 | pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ { | ||
200 | match &self.data { | ||
201 | Some(data) => Some(data.inner_items.values().flatten().copied()).into_iter().flatten(), | ||
202 | None => None.into_iter().flatten(), | ||
203 | } | ||
204 | } | ||
205 | |||
206 | pub fn inner_items_of_block(&self, block: FileAstId<ast::BlockExpr>) -> &[ModItem] { | 199 | pub fn inner_items_of_block(&self, block: FileAstId<ast::BlockExpr>) -> &[ModItem] { |
207 | match &self.data { | 200 | match &self.data { |
208 | Some(data) => data.inner_items.get(&block).map(|it| &**it).unwrap_or(&[]), | 201 | Some(data) => data.inner_items.get(&block).map(|it| &**it).unwrap_or(&[]), |
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index abc0e7532..66b3418f2 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -18,9 +18,9 @@ ena = "0.14.0" | |||
18 | log = "0.4.8" | 18 | log = "0.4.8" |
19 | rustc-hash = "1.1.0" | 19 | rustc-hash = "1.1.0" |
20 | scoped-tls = "1" | 20 | scoped-tls = "1" |
21 | chalk-solve = { version = "0.60", default-features = false } | 21 | chalk-solve = { version = "0.64", default-features = false } |
22 | chalk-ir = "0.60" | 22 | chalk-ir = "0.64" |
23 | chalk-recursive = "0.60" | 23 | chalk-recursive = "0.64" |
24 | la-arena = { version = "0.2.0", path = "../../lib/arena" } | 24 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
25 | 25 | ||
26 | stdx = { path = "../stdx", version = "0.0.0" } | 26 | stdx = { path = "../stdx", version = "0.0.0" } |
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 78a57fbdc..5f80a40c8 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs | |||
@@ -1227,9 +1227,19 @@ fn make_body( | |||
1227 | FunctionBody::Expr(expr) => { | 1227 | FunctionBody::Expr(expr) => { |
1228 | let expr = rewrite_body_segment(ctx, &fun.params, &handler, expr.syntax()); | 1228 | let expr = rewrite_body_segment(ctx, &fun.params, &handler, expr.syntax()); |
1229 | let expr = ast::Expr::cast(expr).unwrap(); | 1229 | let expr = ast::Expr::cast(expr).unwrap(); |
1230 | let expr = expr.dedent(old_indent).indent(IndentLevel(1)); | 1230 | match expr { |
1231 | ast::Expr::BlockExpr(block) => { | ||
1232 | // If the extracted expression is itself a block, there is no need to wrap it inside another block. | ||
1233 | let block = block.dedent(old_indent); | ||
1234 | // Recreate the block for formatting consistency with other extracted functions. | ||
1235 | make::block_expr(block.statements(), block.tail_expr()) | ||
1236 | } | ||
1237 | _ => { | ||
1238 | let expr = expr.dedent(old_indent).indent(IndentLevel(1)); | ||
1231 | 1239 | ||
1232 | make::block_expr(Vec::new(), Some(expr)) | 1240 | make::block_expr(Vec::new(), Some(expr)) |
1241 | } | ||
1242 | } | ||
1233 | } | 1243 | } |
1234 | FunctionBody::Span { parent, text_range } => { | 1244 | FunctionBody::Span { parent, text_range } => { |
1235 | let mut elements: Vec<_> = parent | 1245 | let mut elements: Vec<_> = parent |
@@ -1544,7 +1554,7 @@ fn foo() { | |||
1544 | } | 1554 | } |
1545 | 1555 | ||
1546 | fn $0fun_name() -> i32 { | 1556 | fn $0fun_name() -> i32 { |
1547 | { 1 + 1 } | 1557 | 1 + 1 |
1548 | }"#, | 1558 | }"#, |
1549 | ); | 1559 | ); |
1550 | } | 1560 | } |
@@ -2526,17 +2536,15 @@ fn foo() { | |||
2526 | } | 2536 | } |
2527 | 2537 | ||
2528 | fn $0fun_name(n: &mut i32) { | 2538 | fn $0fun_name(n: &mut i32) { |
2529 | { | 2539 | *n += *n; |
2530 | *n += *n; | 2540 | bar(*n); |
2531 | bar(*n); | 2541 | bar(*n+1); |
2532 | bar(*n+1); | 2542 | bar(*n**n); |
2533 | bar(*n**n); | 2543 | bar(&*n); |
2534 | bar(&*n); | 2544 | n.inc(); |
2535 | n.inc(); | 2545 | let v = n; |
2536 | let v = n; | 2546 | *v = v.succ(); |
2537 | *v = v.succ(); | 2547 | n.succ(); |
2538 | n.succ(); | ||
2539 | } | ||
2540 | }", | 2548 | }", |
2541 | ); | 2549 | ); |
2542 | } | 2550 | } |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 7ddea22c8..1109d2daf 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -17,7 +17,7 @@ use ide_db::helpers::{ | |||
17 | }; | 17 | }; |
18 | use lsp_types::{ClientCapabilities, MarkupKind}; | 18 | use lsp_types::{ClientCapabilities, MarkupKind}; |
19 | use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource}; | 19 | use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource}; |
20 | use rustc_hash::FxHashSet; | 20 | use rustc_hash::{FxHashMap, FxHashSet}; |
21 | use serde::{de::DeserializeOwned, Deserialize}; | 21 | use serde::{de::DeserializeOwned, Deserialize}; |
22 | use vfs::AbsPathBuf; | 22 | use vfs::AbsPathBuf; |
23 | 23 | ||
@@ -99,6 +99,9 @@ config_data! { | |||
99 | diagnostics_enableExperimental: bool = "true", | 99 | diagnostics_enableExperimental: bool = "true", |
100 | /// List of rust-analyzer diagnostics to disable. | 100 | /// List of rust-analyzer diagnostics to disable. |
101 | diagnostics_disabled: FxHashSet<String> = "[]", | 101 | diagnostics_disabled: FxHashSet<String> = "[]", |
102 | /// Map of prefixes to be substituted when parsing diagnostic file paths. | ||
103 | /// This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`. | ||
104 | diagnostics_remapPrefix: FxHashMap<String, String> = "{}", | ||
102 | /// List of warnings that should be displayed with info severity. | 105 | /// List of warnings that should be displayed with info severity. |
103 | /// | 106 | /// |
104 | /// The warnings will be indicated by a blue squiggly underline in code | 107 | /// The warnings will be indicated by a blue squiggly underline in code |
@@ -474,6 +477,7 @@ impl Config { | |||
474 | } | 477 | } |
475 | pub fn diagnostics_map(&self) -> DiagnosticsMapConfig { | 478 | pub fn diagnostics_map(&self) -> DiagnosticsMapConfig { |
476 | DiagnosticsMapConfig { | 479 | DiagnosticsMapConfig { |
480 | remap_prefix: self.data.diagnostics_remapPrefix.clone(), | ||
477 | warnings_as_info: self.data.diagnostics_warningsAsInfo.clone(), | 481 | warnings_as_info: self.data.diagnostics_warningsAsInfo.clone(), |
478 | warnings_as_hint: self.data.diagnostics_warningsAsHint.clone(), | 482 | warnings_as_hint: self.data.diagnostics_warningsAsHint.clone(), |
479 | } | 483 | } |
@@ -835,6 +839,9 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json | |||
835 | "items": { "type": "string" }, | 839 | "items": { "type": "string" }, |
836 | "uniqueItems": true, | 840 | "uniqueItems": true, |
837 | }, | 841 | }, |
842 | "FxHashMap<String, String>" => set! { | ||
843 | "type": "object", | ||
844 | }, | ||
838 | "Option<usize>" => set! { | 845 | "Option<usize>" => set! { |
839 | "type": ["null", "integer"], | 846 | "type": ["null", "integer"], |
840 | "minimum": 0, | 847 | "minimum": 0, |
diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs index f01548c50..d4b9db362 100644 --- a/crates/rust-analyzer/src/diagnostics.rs +++ b/crates/rust-analyzer/src/diagnostics.rs | |||
@@ -12,6 +12,7 @@ pub(crate) type CheckFixes = Arc<FxHashMap<FileId, Vec<Fix>>>; | |||
12 | 12 | ||
13 | #[derive(Debug, Default, Clone)] | 13 | #[derive(Debug, Default, Clone)] |
14 | pub struct DiagnosticsMapConfig { | 14 | pub struct DiagnosticsMapConfig { |
15 | pub remap_prefix: FxHashMap<String, String>, | ||
15 | pub warnings_as_info: Vec<String>, | 16 | pub warnings_as_info: Vec<String>, |
16 | pub warnings_as_hint: Vec<String>, | 17 | pub warnings_as_hint: Vec<String>, |
17 | } | 18 | } |
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index ca18997e4..82dd0da9a 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs | |||
@@ -1,6 +1,9 @@ | |||
1 | //! This module provides the functionality needed to convert diagnostics from | 1 | //! This module provides the functionality needed to convert diagnostics from |
2 | //! `cargo check` json format to the LSP diagnostic format. | 2 | //! `cargo check` json format to the LSP diagnostic format. |
3 | use std::{collections::HashMap, path::Path}; | 3 | use std::{ |
4 | collections::HashMap, | ||
5 | path::{Path, PathBuf}, | ||
6 | }; | ||
4 | 7 | ||
5 | use flycheck::{DiagnosticLevel, DiagnosticSpan}; | 8 | use flycheck::{DiagnosticLevel, DiagnosticSpan}; |
6 | use stdx::format_to; | 9 | use stdx::format_to; |
@@ -41,8 +44,12 @@ fn is_dummy_macro_file(file_name: &str) -> bool { | |||
41 | } | 44 | } |
42 | 45 | ||
43 | /// Converts a Rust span to a LSP location | 46 | /// Converts a Rust span to a LSP location |
44 | fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { | 47 | fn location( |
45 | let file_name = workspace_root.join(&span.file_name); | 48 | config: &DiagnosticsMapConfig, |
49 | workspace_root: &Path, | ||
50 | span: &DiagnosticSpan, | ||
51 | ) -> lsp_types::Location { | ||
52 | let file_name = resolve_path(config, workspace_root, &span.file_name); | ||
46 | let uri = url_from_abs_path(&file_name); | 53 | let uri = url_from_abs_path(&file_name); |
47 | 54 | ||
48 | // FIXME: this doesn't handle UTF16 offsets correctly | 55 | // FIXME: this doesn't handle UTF16 offsets correctly |
@@ -58,32 +65,50 @@ fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location | |||
58 | /// | 65 | /// |
59 | /// This takes locations pointing into the standard library, or generally outside the current | 66 | /// This takes locations pointing into the standard library, or generally outside the current |
60 | /// workspace into account and tries to avoid those, in case macros are involved. | 67 | /// workspace into account and tries to avoid those, in case macros are involved. |
61 | fn primary_location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { | 68 | fn primary_location( |
69 | config: &DiagnosticsMapConfig, | ||
70 | workspace_root: &Path, | ||
71 | span: &DiagnosticSpan, | ||
72 | ) -> lsp_types::Location { | ||
62 | let span_stack = std::iter::successors(Some(span), |span| Some(&span.expansion.as_ref()?.span)); | 73 | let span_stack = std::iter::successors(Some(span), |span| Some(&span.expansion.as_ref()?.span)); |
63 | for span in span_stack.clone() { | 74 | for span in span_stack.clone() { |
64 | let abs_path = workspace_root.join(&span.file_name); | 75 | let abs_path = resolve_path(config, workspace_root, &span.file_name); |
65 | if !is_dummy_macro_file(&span.file_name) && abs_path.starts_with(workspace_root) { | 76 | if !is_dummy_macro_file(&span.file_name) && abs_path.starts_with(workspace_root) { |
66 | return location(workspace_root, span); | 77 | return location(config, workspace_root, span); |
67 | } | 78 | } |
68 | } | 79 | } |
69 | 80 | ||
70 | // Fall back to the outermost macro invocation if no suitable span comes up. | 81 | // Fall back to the outermost macro invocation if no suitable span comes up. |
71 | let last_span = span_stack.last().unwrap(); | 82 | let last_span = span_stack.last().unwrap(); |
72 | location(workspace_root, last_span) | 83 | location(config, workspace_root, last_span) |
73 | } | 84 | } |
74 | 85 | ||
75 | /// Converts a secondary Rust span to a LSP related information | 86 | /// Converts a secondary Rust span to a LSP related information |
76 | /// | 87 | /// |
77 | /// If the span is unlabelled this will return `None`. | 88 | /// If the span is unlabelled this will return `None`. |
78 | fn diagnostic_related_information( | 89 | fn diagnostic_related_information( |
90 | config: &DiagnosticsMapConfig, | ||
79 | workspace_root: &Path, | 91 | workspace_root: &Path, |
80 | span: &DiagnosticSpan, | 92 | span: &DiagnosticSpan, |
81 | ) -> Option<lsp_types::DiagnosticRelatedInformation> { | 93 | ) -> Option<lsp_types::DiagnosticRelatedInformation> { |
82 | let message = span.label.clone()?; | 94 | let message = span.label.clone()?; |
83 | let location = location(workspace_root, span); | 95 | let location = location(config, workspace_root, span); |
84 | Some(lsp_types::DiagnosticRelatedInformation { location, message }) | 96 | Some(lsp_types::DiagnosticRelatedInformation { location, message }) |
85 | } | 97 | } |
86 | 98 | ||
99 | /// Resolves paths applying any matching path prefix remappings, and then | ||
100 | /// joining the path to the workspace root. | ||
101 | fn resolve_path(config: &DiagnosticsMapConfig, workspace_root: &Path, file_name: &str) -> PathBuf { | ||
102 | match config | ||
103 | .remap_prefix | ||
104 | .iter() | ||
105 | .find_map(|(from, to)| file_name.strip_prefix(from).map(|file_name| (to, file_name))) | ||
106 | { | ||
107 | Some((to, file_name)) => workspace_root.join(format!("{}{}", to, file_name)), | ||
108 | None => workspace_root.join(file_name), | ||
109 | } | ||
110 | } | ||
111 | |||
87 | struct SubDiagnostic { | 112 | struct SubDiagnostic { |
88 | related: lsp_types::DiagnosticRelatedInformation, | 113 | related: lsp_types::DiagnosticRelatedInformation, |
89 | suggested_fix: Option<lsp_ext::CodeAction>, | 114 | suggested_fix: Option<lsp_ext::CodeAction>, |
@@ -95,6 +120,7 @@ enum MappedRustChildDiagnostic { | |||
95 | } | 120 | } |
96 | 121 | ||
97 | fn map_rust_child_diagnostic( | 122 | fn map_rust_child_diagnostic( |
123 | config: &DiagnosticsMapConfig, | ||
98 | workspace_root: &Path, | 124 | workspace_root: &Path, |
99 | rd: &flycheck::Diagnostic, | 125 | rd: &flycheck::Diagnostic, |
100 | ) -> MappedRustChildDiagnostic { | 126 | ) -> MappedRustChildDiagnostic { |
@@ -108,7 +134,7 @@ fn map_rust_child_diagnostic( | |||
108 | let mut edit_map: HashMap<lsp_types::Url, Vec<lsp_types::TextEdit>> = HashMap::new(); | 134 | let mut edit_map: HashMap<lsp_types::Url, Vec<lsp_types::TextEdit>> = HashMap::new(); |
109 | for &span in &spans { | 135 | for &span in &spans { |
110 | if let Some(suggested_replacement) = &span.suggested_replacement { | 136 | if let Some(suggested_replacement) = &span.suggested_replacement { |
111 | let location = location(workspace_root, span); | 137 | let location = location(config, workspace_root, span); |
112 | let edit = lsp_types::TextEdit::new(location.range, suggested_replacement.clone()); | 138 | let edit = lsp_types::TextEdit::new(location.range, suggested_replacement.clone()); |
113 | edit_map.entry(location.uri).or_default().push(edit); | 139 | edit_map.entry(location.uri).or_default().push(edit); |
114 | } | 140 | } |
@@ -117,7 +143,7 @@ fn map_rust_child_diagnostic( | |||
117 | if edit_map.is_empty() { | 143 | if edit_map.is_empty() { |
118 | MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { | 144 | MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { |
119 | related: lsp_types::DiagnosticRelatedInformation { | 145 | related: lsp_types::DiagnosticRelatedInformation { |
120 | location: location(workspace_root, spans[0]), | 146 | location: location(config, workspace_root, spans[0]), |
121 | message: rd.message.clone(), | 147 | message: rd.message.clone(), |
122 | }, | 148 | }, |
123 | suggested_fix: None, | 149 | suggested_fix: None, |
@@ -125,7 +151,7 @@ fn map_rust_child_diagnostic( | |||
125 | } else { | 151 | } else { |
126 | MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { | 152 | MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { |
127 | related: lsp_types::DiagnosticRelatedInformation { | 153 | related: lsp_types::DiagnosticRelatedInformation { |
128 | location: location(workspace_root, spans[0]), | 154 | location: location(config, workspace_root, spans[0]), |
129 | message: rd.message.clone(), | 155 | message: rd.message.clone(), |
130 | }, | 156 | }, |
131 | suggested_fix: Some(lsp_ext::CodeAction { | 157 | suggested_fix: Some(lsp_ext::CodeAction { |
@@ -190,7 +216,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
190 | let mut tags = Vec::new(); | 216 | let mut tags = Vec::new(); |
191 | 217 | ||
192 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { | 218 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { |
193 | let related = diagnostic_related_information(workspace_root, secondary_span); | 219 | let related = diagnostic_related_information(config, workspace_root, secondary_span); |
194 | if let Some(related) = related { | 220 | if let Some(related) = related { |
195 | subdiagnostics.push(SubDiagnostic { related, suggested_fix: None }); | 221 | subdiagnostics.push(SubDiagnostic { related, suggested_fix: None }); |
196 | } | 222 | } |
@@ -198,7 +224,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
198 | 224 | ||
199 | let mut message = rd.message.clone(); | 225 | let mut message = rd.message.clone(); |
200 | for child in &rd.children { | 226 | for child in &rd.children { |
201 | let child = map_rust_child_diagnostic(workspace_root, &child); | 227 | let child = map_rust_child_diagnostic(config, workspace_root, &child); |
202 | match child { | 228 | match child { |
203 | MappedRustChildDiagnostic::SubDiagnostic(sub) => { | 229 | MappedRustChildDiagnostic::SubDiagnostic(sub) => { |
204 | subdiagnostics.push(sub); | 230 | subdiagnostics.push(sub); |
@@ -242,7 +268,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
242 | primary_spans | 268 | primary_spans |
243 | .iter() | 269 | .iter() |
244 | .flat_map(|primary_span| { | 270 | .flat_map(|primary_span| { |
245 | let primary_location = primary_location(workspace_root, &primary_span); | 271 | let primary_location = primary_location(config, workspace_root, &primary_span); |
246 | 272 | ||
247 | let mut message = message.clone(); | 273 | let mut message = message.clone(); |
248 | if needs_primary_span_label { | 274 | if needs_primary_span_label { |
@@ -272,7 +298,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
272 | // generated that code. | 298 | // generated that code. |
273 | let is_in_macro_call = i != 0; | 299 | let is_in_macro_call = i != 0; |
274 | 300 | ||
275 | let secondary_location = location(workspace_root, &span); | 301 | let secondary_location = location(config, workspace_root, &span); |
276 | if secondary_location == primary_location { | 302 | if secondary_location == primary_location { |
277 | continue; | 303 | continue; |
278 | } | 304 | } |
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index a8c1a8075..556f80882 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml | |||
@@ -14,7 +14,7 @@ doctest = false | |||
14 | cov-mark = { version = "1.1", features = ["thread-local"] } | 14 | cov-mark = { version = "1.1", features = ["thread-local"] } |
15 | itertools = "0.10.0" | 15 | itertools = "0.10.0" |
16 | rowan = "=0.13.0-pre.3" | 16 | rowan = "=0.13.0-pre.3" |
17 | rustc_lexer = { version = "714.0.0", package = "rustc-ap-rustc_lexer" } | 17 | rustc_lexer = { version = "716.0.0", package = "rustc-ap-rustc_lexer" } |
18 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
19 | arrayvec = "0.7" | 19 | arrayvec = "0.7" |
20 | once_cell = "1.3.1" | 20 | once_cell = "1.3.1" |