diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-06-30 10:54:47 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-06-30 10:54:47 +0100 |
commit | fb2534f30089ddd796dbf52c7bb639efe5d10a3e (patch) | |
tree | b08792995d3aafe3f203372984722714c6954d2e /editors/code/src | |
parent | 950da94c3aaebb783d20be2552b6c1b77e92c7a0 (diff) | |
parent | 8f726b7db65d3d9527cdb2fb682c195ad1446dbf (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]>
Diffstat (limited to 'editors/code/src')
-rw-r--r-- | editors/code/src/test/fixtures/rust-diagnostics/error/E0308.json | 33 | ||||
-rw-r--r-- | editors/code/src/test/utils/diagnotics/rust.test.ts | 29 | ||||
-rw-r--r-- | editors/code/src/utils/diagnostics/rust.ts | 9 |
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 | } |