diff options
8 files changed, 200 insertions, 1 deletions
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 41be283d0..6bda04141 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -170,6 +170,15 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { | |||
170 | if p.eat(T![']']) { | 170 | if p.eat(T![']']) { |
171 | return m.complete(p, ARRAY_EXPR); | 171 | return m.complete(p, ARRAY_EXPR); |
172 | } | 172 | } |
173 | |||
174 | // test first_array_member_attributes | ||
175 | // pub const A: &[i64] = &[ | ||
176 | // #[cfg(test)] | ||
177 | // 1, | ||
178 | // 2, | ||
179 | // ]; | ||
180 | attributes::outer_attributes(p); | ||
181 | |||
173 | expr(p); | 182 | expr(p); |
174 | if p.eat(T![;]) { | 183 | if p.eat(T![;]) { |
175 | expr(p); | 184 | expr(p); |
@@ -181,6 +190,14 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { | |||
181 | if p.at(T![']']) { | 190 | if p.at(T![']']) { |
182 | break; | 191 | break; |
183 | } | 192 | } |
193 | |||
194 | // test subsequent_array_member_attributes | ||
195 | // pub const A: &[i64] = &[ | ||
196 | // 1, | ||
197 | // #[cfg(test)] | ||
198 | // 2, | ||
199 | // ]; | ||
200 | attributes::outer_attributes(p); | ||
184 | if !p.at_ts(EXPR_FIRST) { | 201 | if !p.at_ts(EXPR_FIRST) { |
185 | p.error("expected expression"); | 202 | p.error("expected expression"); |
186 | break; | 203 | break; |
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.rs new file mode 100644 index 000000000..f59e13771 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | pub const A: &[i64] = &[ | ||
2 | #[cfg(test)] | ||
3 | 1, | ||
4 | 2, | ||
5 | ]; | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.txt new file mode 100644 index 000000000..eac4f6f30 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.txt | |||
@@ -0,0 +1,51 @@ | |||
1 | SOURCE_FILE@[0; 56) | ||
2 | CONST_DEF@[0; 55) | ||
3 | VISIBILITY@[0; 3) | ||
4 | PUB_KW@[0; 3) "pub" | ||
5 | WHITESPACE@[3; 4) " " | ||
6 | CONST_KW@[4; 9) "const" | ||
7 | WHITESPACE@[9; 10) " " | ||
8 | NAME@[10; 11) | ||
9 | IDENT@[10; 11) "A" | ||
10 | COLON@[11; 12) ":" | ||
11 | WHITESPACE@[12; 13) " " | ||
12 | REFERENCE_TYPE@[13; 19) | ||
13 | AMP@[13; 14) "&" | ||
14 | SLICE_TYPE@[14; 19) | ||
15 | L_BRACK@[14; 15) "[" | ||
16 | PATH_TYPE@[15; 18) | ||
17 | PATH@[15; 18) | ||
18 | PATH_SEGMENT@[15; 18) | ||
19 | NAME_REF@[15; 18) | ||
20 | IDENT@[15; 18) "i64" | ||
21 | R_BRACK@[18; 19) "]" | ||
22 | WHITESPACE@[19; 20) " " | ||
23 | EQ@[20; 21) "=" | ||
24 | WHITESPACE@[21; 22) " " | ||
25 | REF_EXPR@[22; 54) | ||
26 | AMP@[22; 23) "&" | ||
27 | ARRAY_EXPR@[23; 54) | ||
28 | L_BRACK@[23; 24) "[" | ||
29 | WHITESPACE@[24; 28) "\n " | ||
30 | ATTR@[28; 40) | ||
31 | POUND@[28; 29) "#" | ||
32 | TOKEN_TREE@[29; 40) | ||
33 | L_BRACK@[29; 30) "[" | ||
34 | IDENT@[30; 33) "cfg" | ||
35 | TOKEN_TREE@[33; 39) | ||
36 | L_PAREN@[33; 34) "(" | ||
37 | IDENT@[34; 38) "test" | ||
38 | R_PAREN@[38; 39) ")" | ||
39 | R_BRACK@[39; 40) "]" | ||
40 | WHITESPACE@[40; 44) "\n " | ||
41 | LITERAL@[44; 45) | ||
42 | INT_NUMBER@[44; 45) "1" | ||
43 | COMMA@[45; 46) "," | ||
44 | WHITESPACE@[46; 50) "\n " | ||
45 | LITERAL@[50; 51) | ||
46 | INT_NUMBER@[50; 51) "2" | ||
47 | COMMA@[51; 52) "," | ||
48 | WHITESPACE@[52; 53) "\n" | ||
49 | R_BRACK@[53; 54) "]" | ||
50 | SEMI@[54; 55) ";" | ||
51 | WHITESPACE@[55; 56) "\n" | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.rs new file mode 100644 index 000000000..1324acb3f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | pub const A: &[i64] = &[ | ||
2 | 1, | ||
3 | #[cfg(test)] | ||
4 | 2, | ||
5 | ]; | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.txt new file mode 100644 index 000000000..6fa1b42d9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.txt | |||
@@ -0,0 +1,51 @@ | |||
1 | SOURCE_FILE@[0; 56) | ||
2 | CONST_DEF@[0; 55) | ||
3 | VISIBILITY@[0; 3) | ||
4 | PUB_KW@[0; 3) "pub" | ||
5 | WHITESPACE@[3; 4) " " | ||
6 | CONST_KW@[4; 9) "const" | ||
7 | WHITESPACE@[9; 10) " " | ||
8 | NAME@[10; 11) | ||
9 | IDENT@[10; 11) "A" | ||
10 | COLON@[11; 12) ":" | ||
11 | WHITESPACE@[12; 13) " " | ||
12 | REFERENCE_TYPE@[13; 19) | ||
13 | AMP@[13; 14) "&" | ||
14 | SLICE_TYPE@[14; 19) | ||
15 | L_BRACK@[14; 15) "[" | ||
16 | PATH_TYPE@[15; 18) | ||
17 | PATH@[15; 18) | ||
18 | PATH_SEGMENT@[15; 18) | ||
19 | NAME_REF@[15; 18) | ||
20 | IDENT@[15; 18) "i64" | ||
21 | R_BRACK@[18; 19) "]" | ||
22 | WHITESPACE@[19; 20) " " | ||
23 | EQ@[20; 21) "=" | ||
24 | WHITESPACE@[21; 22) " " | ||
25 | REF_EXPR@[22; 54) | ||
26 | AMP@[22; 23) "&" | ||
27 | ARRAY_EXPR@[23; 54) | ||
28 | L_BRACK@[23; 24) "[" | ||
29 | WHITESPACE@[24; 28) "\n " | ||
30 | LITERAL@[28; 29) | ||
31 | INT_NUMBER@[28; 29) "1" | ||
32 | COMMA@[29; 30) "," | ||
33 | WHITESPACE@[30; 34) "\n " | ||
34 | ATTR@[34; 46) | ||
35 | POUND@[34; 35) "#" | ||
36 | TOKEN_TREE@[35; 46) | ||
37 | L_BRACK@[35; 36) "[" | ||
38 | IDENT@[36; 39) "cfg" | ||
39 | TOKEN_TREE@[39; 45) | ||
40 | L_PAREN@[39; 40) "(" | ||
41 | IDENT@[40; 44) "test" | ||
42 | R_PAREN@[44; 45) ")" | ||
43 | R_BRACK@[45; 46) "]" | ||
44 | WHITESPACE@[46; 50) "\n " | ||
45 | LITERAL@[50; 51) | ||
46 | INT_NUMBER@[50; 51) "2" | ||
47 | COMMA@[51; 52) "," | ||
48 | WHITESPACE@[52; 53) "\n" | ||
49 | R_BRACK@[53; 54) "]" | ||
50 | SEMI@[54; 55) ";" | ||
51 | WHITESPACE@[55; 56) "\n" | ||
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 d16576eb1..bfb494a3a 100644 --- a/editors/code/src/utils/diagnostics/rust.ts +++ b/editors/code/src/utils/diagnostics/rust.ts | |||
@@ -103,6 +103,7 @@ function isUnusedOrUnnecessary(rd: RustDiagnostic): boolean { | |||
103 | return [ | 103 | return [ |
104 | 'dead_code', | 104 | 'dead_code', |
105 | 'unknown_lints', | 105 | 'unknown_lints', |
106 | 'unreachable_code', | ||
106 | 'unused_attributes', | 107 | 'unused_attributes', |
107 | 'unused_imports', | 108 | 'unused_imports', |
108 | 'unused_macros', | 109 | 'unused_macros', |
@@ -182,6 +183,7 @@ export function mapRustDiagnosticToVsCode( | |||
182 | const secondarySpans = rd.spans.filter(s => !s.is_primary); | 183 | const secondarySpans = rd.spans.filter(s => !s.is_primary); |
183 | 184 | ||
184 | const severity = mapLevelToSeverity(rd.level); | 185 | const severity = mapLevelToSeverity(rd.level); |
186 | let primarySpanLabel = primarySpan.label; | ||
185 | 187 | ||
186 | const vd = new vscode.Diagnostic(location.range, rd.message, severity); | 188 | const vd = new vscode.Diagnostic(location.range, rd.message, severity); |
187 | 189 | ||
@@ -220,9 +222,17 @@ export function mapRustDiagnosticToVsCode( | |||
220 | } | 222 | } |
221 | if (messageLine) { | 223 | if (messageLine) { |
222 | 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; | ||
223 | } | 229 | } |
224 | } | 230 | } |
225 | 231 | ||
232 | if (primarySpanLabel) { | ||
233 | vd.message += `\n${primarySpanLabel}`; | ||
234 | } | ||
235 | |||
226 | if (isUnusedOrUnnecessary(rd)) { | 236 | if (isUnusedOrUnnecessary(rd)) { |
227 | vd.tags = [vscode.DiagnosticTag.Unnecessary]; | 237 | vd.tags = [vscode.DiagnosticTag.Unnecessary]; |
228 | } | 238 | } |