aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-06-30 10:54:47 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-06-30 10:54:47 +0100
commitfb2534f30089ddd796dbf52c7bb639efe5d10a3e (patch)
treeb08792995d3aafe3f203372984722714c6954d2e
parent950da94c3aaebb783d20be2552b6c1b77e92c7a0 (diff)
parent8f726b7db65d3d9527cdb2fb682c195ad1446dbf (diff)
Merge #1459
1459: Include primary span label in VS Code diagnostics r=matklad a=etaoins In most cases the primary label span repeats information found elsewhere in the diagnostic. For example, with E0061: ```json { "message": "this function takes 2 parameters but 3 parameters were supplied", "spans": [{"label": "expected 2 parameters"}] } ``` However, with some mismatched type errors (E0308) the expected type only appears in the primary span's label, e.g.: ```json { "message": "mismatched types", "spans": [{"label": "expected usize, found u32"}] } ``` I initially added the primary span label to the message unconditionally. However, for most error types the child diagnostics repeat the primary span label with more detail. `rustc` also renders the duplicate text but because the span label and child diagnostics appear in visually distinct places it's not as confusing. This takes a heuristic approach where it will only add the primary span label if there are no child message lines. For most error types the child messages repeat the primary span label with more detail. Co-authored-by: Ryan Cumming <[email protected]>
-rw-r--r--editors/code/src/test/fixtures/rust-diagnostics/error/E0308.json33
-rw-r--r--editors/code/src/test/utils/diagnotics/rust.test.ts29
-rw-r--r--editors/code/src/utils/diagnostics/rust.ts9
3 files changed, 70 insertions, 1 deletions
diff --git a/editors/code/src/test/fixtures/rust-diagnostics/error/E0308.json b/editors/code/src/test/fixtures/rust-diagnostics/error/E0308.json
new file mode 100644
index 000000000..fb23824a3
--- /dev/null
+++ b/editors/code/src/test/fixtures/rust-diagnostics/error/E0308.json
@@ -0,0 +1,33 @@
1{
2 "message": "mismatched types",
3 "code": {
4 "code": "E0308",
5 "explanation": "\nThis error occurs when the compiler was unable to infer the concrete type of a\nvariable. It can occur for several cases, the most common of which is a\nmismatch in the expected type that the compiler inferred for a variable's\ninitializing expression, and the actual type explicitly assigned to the\nvariable.\n\nFor example:\n\n```compile_fail,E0308\nlet x: i32 = \"I am not a number!\";\n// ~~~ ~~~~~~~~~~~~~~~~~~~~\n// | |\n// | initializing expression;\n// | compiler infers type `&str`\n// |\n// type `i32` assigned to variable `x`\n```\n"
6 },
7 "level": "error",
8 "spans": [
9 {
10 "file_name": "runtime/compiler_support.rs",
11 "byte_start": 1589,
12 "byte_end": 1594,
13 "line_start": 48,
14 "line_end": 48,
15 "column_start": 65,
16 "column_end": 70,
17 "is_primary": true,
18 "text": [
19 {
20 "text": " let layout = alloc::Layout::from_size_align_unchecked(size, align);",
21 "highlight_start": 65,
22 "highlight_end": 70
23 }
24 ],
25 "label": "expected usize, found u32",
26 "suggested_replacement": null,
27 "suggestion_applicability": null,
28 "expansion": null
29 }
30 ],
31 "children": [],
32 "rendered": "error[E0308]: mismatched types\n --> runtime/compiler_support.rs:48:65\n |\n48 | let layout = alloc::Layout::from_size_align_unchecked(size, align);\n | ^^^^^ expected usize, found u32\n\n"
33}
diff --git a/editors/code/src/test/utils/diagnotics/rust.test.ts b/editors/code/src/test/utils/diagnotics/rust.test.ts
index b555a4819..7fb003fe2 100644
--- a/editors/code/src/test/utils/diagnotics/rust.test.ts
+++ b/editors/code/src/test/utils/diagnotics/rust.test.ts
@@ -108,7 +108,10 @@ describe('mapRustDiagnosticToVsCode', () => {
108 ); 108 );
109 assert.strictEqual( 109 assert.strictEqual(
110 diagnostic.message, 110 diagnostic.message,
111 'this function takes 2 parameters but 3 parameters were supplied' 111 [
112 'this function takes 2 parameters but 3 parameters were supplied',
113 'expected 2 parameters'
114 ].join('\n')
112 ); 115 );
113 assert.strictEqual(diagnostic.code, 'E0061'); 116 assert.strictEqual(diagnostic.code, 'E0061');
114 assert.strictEqual(diagnostic.source, 'rustc'); 117 assert.strictEqual(diagnostic.source, 'rustc');
@@ -170,4 +173,28 @@ describe('mapRustDiagnosticToVsCode', () => {
170 SuggestionApplicability.Unspecified 173 SuggestionApplicability.Unspecified
171 ); 174 );
172 }); 175 });
176
177 it('should map a mismatched type error', () => {
178 const { diagnostic, suggestedFixes } = mapFixtureToVsCode(
179 'error/E0308'
180 );
181
182 assert.strictEqual(
183 diagnostic.severity,
184 vscode.DiagnosticSeverity.Error
185 );
186 assert.strictEqual(
187 diagnostic.message,
188 ['mismatched types', 'expected usize, found u32'].join('\n')
189 );
190 assert.strictEqual(diagnostic.code, 'E0308');
191 assert.strictEqual(diagnostic.source, 'rustc');
192 assert.strictEqual(diagnostic.tags, undefined);
193
194 // No related information
195 assert.deepStrictEqual(diagnostic.relatedInformation, []);
196
197 // There are no suggested fixes
198 assert.strictEqual(suggestedFixes.length, 0);
199 });
173}); 200});
diff --git a/editors/code/src/utils/diagnostics/rust.ts b/editors/code/src/utils/diagnostics/rust.ts
index 5e2d6b6ff..bfb494a3a 100644
--- a/editors/code/src/utils/diagnostics/rust.ts
+++ b/editors/code/src/utils/diagnostics/rust.ts
@@ -183,6 +183,7 @@ export function mapRustDiagnosticToVsCode(
183 const secondarySpans = rd.spans.filter(s => !s.is_primary); 183 const secondarySpans = rd.spans.filter(s => !s.is_primary);
184 184
185 const severity = mapLevelToSeverity(rd.level); 185 const severity = mapLevelToSeverity(rd.level);
186 let primarySpanLabel = primarySpan.label;
186 187
187 const vd = new vscode.Diagnostic(location.range, rd.message, severity); 188 const vd = new vscode.Diagnostic(location.range, rd.message, severity);
188 189
@@ -221,9 +222,17 @@ export function mapRustDiagnosticToVsCode(
221 } 222 }
222 if (messageLine) { 223 if (messageLine) {
223 vd.message += `\n${messageLine}`; 224 vd.message += `\n${messageLine}`;
225
226 // These secondary messages usually duplicate the content of the
227 // primary span label.
228 primarySpanLabel = undefined;
224 } 229 }
225 } 230 }
226 231
232 if (primarySpanLabel) {
233 vd.message += `\n${primarySpanLabel}`;
234 }
235
227 if (isUnusedOrUnnecessary(rd)) { 236 if (isUnusedOrUnnecessary(rd)) {
228 vd.tags = [vscode.DiagnosticTag.Unnecessary]; 237 vd.tags = [vscode.DiagnosticTag.Unnecessary];
229 } 238 }