Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 72541dd

Browse files
committedAug 26, 2022
Rework SessionSubdiagnostic derive to support multipart_suggestion
1 parent 181ce39 commit 72541dd

File tree

4 files changed

+672
-267
lines changed

4 files changed

+672
-267
lines changed
 

‎compiler/rustc_macros/src/diagnostics/subdiagnostic.rs

Lines changed: 389 additions & 219 deletions
Large diffs are not rendered by default.

‎compiler/rustc_macros/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,13 @@ decl_derive!(
171171
suggestion_short,
172172
suggestion_hidden,
173173
suggestion_verbose,
174+
multipart_suggestion,
175+
multipart_suggestion_short,
176+
multipart_suggestion_hidden,
177+
multipart_suggestion_verbose,
174178
// field attributes
175179
skip_arg,
176180
primary_span,
181+
suggestion_part,
177182
applicability)] => diagnostics::session_subdiagnostic_derive
178183
);

‎src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,8 @@ union AC {
310310
#[derive(SessionSubdiagnostic)]
311311
#[label(parser::add_paren)]
312312
//~^ NOTE previously specified here
313-
//~^^ NOTE previously specified here
314313
#[label(parser::add_paren)]
315314
//~^ ERROR specified multiple times
316-
//~^^ ERROR specified multiple times
317315
struct AD {
318316
#[primary_span]
319317
span: Span,
@@ -517,3 +515,120 @@ struct AZ {
517515
#[primary_span]
518516
span: Span,
519517
}
518+
519+
#[derive(SessionSubdiagnostic)]
520+
#[suggestion(parser::add_paren, code = "...")]
521+
//~^ ERROR suggestion without `#[primary_span]` field
522+
struct BA {
523+
#[suggestion_part]
524+
//~^ ERROR `#[suggestion_part]` is not a valid attribute
525+
span: Span,
526+
#[suggestion_part(code = "...")]
527+
//~^ ERROR `#[suggestion_part(...)]` is not a valid attribute
528+
span2: Span,
529+
#[applicability]
530+
applicability: Applicability,
531+
var: String,
532+
}
533+
534+
#[derive(SessionSubdiagnostic)]
535+
#[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
536+
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
537+
//~| ERROR `code` is not a valid nested attribute of a `multipart_suggestion` attribute
538+
struct BBa {
539+
var: String,
540+
}
541+
542+
#[derive(SessionSubdiagnostic)]
543+
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
544+
struct BBb {
545+
#[suggestion_part]
546+
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
547+
span1: Span,
548+
}
549+
550+
#[derive(SessionSubdiagnostic)]
551+
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
552+
struct BBc {
553+
#[suggestion_part()]
554+
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
555+
span1: Span,
556+
}
557+
558+
#[derive(SessionSubdiagnostic)]
559+
#[multipart_suggestion(parser::add_paren)]
560+
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
561+
struct BC {
562+
#[primary_span]
563+
//~^ ERROR `#[primary_span]` is not a valid attribute
564+
span: Span,
565+
}
566+
567+
#[derive(SessionSubdiagnostic)]
568+
#[multipart_suggestion(parser::add_paren)]
569+
struct BD {
570+
#[suggestion_part]
571+
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
572+
span1: Span,
573+
#[suggestion_part()]
574+
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
575+
span2: Span,
576+
#[suggestion_part(foo = "bar")]
577+
//~^ ERROR `#[suggestion_part(foo = ...)]` is not a valid attribute
578+
span4: Span,
579+
#[suggestion_part(code = "...")]
580+
//~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
581+
s1: String,
582+
#[suggestion_part()]
583+
//~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
584+
s2: String,
585+
}
586+
587+
#[derive(SessionSubdiagnostic)]
588+
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
589+
struct BE {
590+
#[suggestion_part(code = "...", code = ",,,")]
591+
//~^ ERROR specified multiple times
592+
//~| NOTE previously specified here
593+
span: Span,
594+
}
595+
596+
#[derive(SessionSubdiagnostic)]
597+
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
598+
struct BF {
599+
#[suggestion_part(code = "(")]
600+
first: Span,
601+
#[suggestion_part(code = ")")]
602+
second: Span,
603+
}
604+
605+
#[derive(SessionSubdiagnostic)]
606+
#[multipart_suggestion(parser::add_paren)]
607+
struct BG {
608+
#[applicability]
609+
appl: Applicability,
610+
#[suggestion_part(code = "(")]
611+
first: Span,
612+
#[suggestion_part(code = ")")]
613+
second: Span,
614+
}
615+
616+
#[derive(SessionSubdiagnostic)]
617+
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
618+
//~^ NOTE previously specified here
619+
struct BH {
620+
#[applicability]
621+
//~^ ERROR specified multiple times
622+
appl: Applicability,
623+
#[suggestion_part(code = "(")]
624+
first: Span,
625+
#[suggestion_part(code = ")")]
626+
second: Span,
627+
}
628+
629+
#[derive(SessionSubdiagnostic)]
630+
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
631+
struct BI {
632+
#[suggestion_part(code = "")]
633+
spans: Vec<Span>,
634+
}

‎src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr

Lines changed: 161 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,16 @@ LL | #[label()]
6565
| ^^^^^^^^^^
6666

6767
error: `code` is not a valid nested attribute of a `label` attribute
68-
--> $DIR/subdiagnostic-derive.rs:137:1
68+
--> $DIR/subdiagnostic-derive.rs:137:28
6969
|
7070
LL | #[label(parser::add_paren, code = "...")]
71-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
71+
| ^^^^^^^^^^^^
7272

7373
error: `applicability` is not a valid nested attribute of a `label` attribute
74-
--> $DIR/subdiagnostic-derive.rs:146:1
74+
--> $DIR/subdiagnostic-derive.rs:146:28
7575
|
7676
LL | #[label(parser::add_paren, applicability = "machine-applicable")]
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7878

7979
error: unsupported type attribute for subdiagnostic enum
8080
--> $DIR/subdiagnostic-derive.rs:155:1
@@ -100,13 +100,11 @@ error: `#[bar = ...]` is not a valid attribute
100100
LL | #[bar = 4]
101101
| ^^^^^^^^^^
102102

103-
error: `#[bar("...")]` is not a valid attribute
104-
--> $DIR/subdiagnostic-derive.rs:205:11
103+
error: `#[bar(...)]` is not a valid attribute
104+
--> $DIR/subdiagnostic-derive.rs:205:5
105105
|
106106
LL | #[bar("...")]
107-
| ^^^^^
108-
|
109-
= help: first argument of the attribute should be the diagnostic slug
107+
| ^^^^^^^^^^^^^
110108

111109
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
112110
--> $DIR/subdiagnostic-derive.rs:217:5
@@ -163,6 +161,8 @@ error: `#[bar(...)]` is not a valid attribute
163161
|
164162
LL | #[bar("...")]
165163
| ^^^^^^^^^^^^^
164+
|
165+
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
166166

167167
error: unexpected unsupported untagged union
168168
--> $DIR/subdiagnostic-derive.rs:304:1
@@ -175,19 +175,7 @@ LL | | }
175175
| |_^
176176

177177
error: specified multiple times
178-
--> $DIR/subdiagnostic-derive.rs:314:1
179-
|
180-
LL | #[label(parser::add_paren)]
181-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
182-
|
183-
note: previously specified here
184-
--> $DIR/subdiagnostic-derive.rs:311:1
185-
|
186-
LL | #[label(parser::add_paren)]
187-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
188-
189-
error: specified multiple times
190-
--> $DIR/subdiagnostic-derive.rs:314:1
178+
--> $DIR/subdiagnostic-derive.rs:313:1
191179
|
192180
LL | #[label(parser::add_paren)]
193181
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -199,81 +187,75 @@ LL | #[label(parser::add_paren)]
199187
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
200188

201189
error: `#[label(parser::add_paren)]` is not a valid attribute
202-
--> $DIR/subdiagnostic-derive.rs:323:28
190+
--> $DIR/subdiagnostic-derive.rs:321:28
203191
|
204192
LL | #[label(parser::add_paren, parser::add_paren)]
205193
| ^^^^^^^^^^^^^^^^^
206194
|
207195
= help: a diagnostic slug must be the first argument to the attribute
208196

209197
error: specified multiple times
210-
--> $DIR/subdiagnostic-derive.rs:336:5
198+
--> $DIR/subdiagnostic-derive.rs:334:5
211199
|
212200
LL | #[primary_span]
213201
| ^^^^^^^^^^^^^^^
214202
|
215203
note: previously specified here
216-
--> $DIR/subdiagnostic-derive.rs:333:5
204+
--> $DIR/subdiagnostic-derive.rs:331:5
217205
|
218206
LL | #[primary_span]
219207
| ^^^^^^^^^^^^^^^
220208

221209
error: subdiagnostic kind not specified
222-
--> $DIR/subdiagnostic-derive.rs:342:8
210+
--> $DIR/subdiagnostic-derive.rs:340:8
223211
|
224212
LL | struct AG {
225213
| ^^
226214

227215
error: specified multiple times
228-
--> $DIR/subdiagnostic-derive.rs:379:47
216+
--> $DIR/subdiagnostic-derive.rs:377:47
229217
|
230218
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
231219
| ^^^^^^^^^^^^
232220
|
233221
note: previously specified here
234-
--> $DIR/subdiagnostic-derive.rs:379:33
222+
--> $DIR/subdiagnostic-derive.rs:377:33
235223
|
236224
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
237225
| ^^^^^^^^^^^^
238226

239227
error: specified multiple times
240-
--> $DIR/subdiagnostic-derive.rs:397:5
228+
--> $DIR/subdiagnostic-derive.rs:395:5
241229
|
242230
LL | #[applicability]
243231
| ^^^^^^^^^^^^^^^^
244232
|
245233
note: previously specified here
246-
--> $DIR/subdiagnostic-derive.rs:394:5
234+
--> $DIR/subdiagnostic-derive.rs:392:5
247235
|
248236
LL | #[applicability]
249237
| ^^^^^^^^^^^^^^^^
250238

251239
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
252-
--> $DIR/subdiagnostic-derive.rs:407:5
240+
--> $DIR/subdiagnostic-derive.rs:405:5
253241
|
254242
LL | #[applicability]
255243
| ^^^^^^^^^^^^^^^^
256244

257245
error: suggestion without `code = "..."`
258-
--> $DIR/subdiagnostic-derive.rs:420:1
246+
--> $DIR/subdiagnostic-derive.rs:418:1
259247
|
260-
LL | / #[suggestion(parser::add_paren)]
261-
LL | |
262-
LL | | struct AN {
263-
LL | | #[primary_span]
264-
... |
265-
LL | | applicability: Applicability,
266-
LL | | }
267-
| |_^
248+
LL | #[suggestion(parser::add_paren)]
249+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
268250

269251
error: invalid applicability
270-
--> $DIR/subdiagnostic-derive.rs:430:46
252+
--> $DIR/subdiagnostic-derive.rs:428:46
271253
|
272254
LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
273255
| ^^^^^^^^^^^^^^^^^^^^^
274256

275257
error: suggestion without `#[primary_span]` field
276-
--> $DIR/subdiagnostic-derive.rs:448:1
258+
--> $DIR/subdiagnostic-derive.rs:446:1
277259
|
278260
LL | / #[suggestion(parser::add_paren, code = "...")]
279261
LL | |
@@ -283,23 +265,156 @@ LL | | }
283265
| |_^
284266

285267
error: unsupported type attribute for subdiagnostic enum
286-
--> $DIR/subdiagnostic-derive.rs:462:1
268+
--> $DIR/subdiagnostic-derive.rs:460:1
287269
|
288270
LL | #[label]
289271
| ^^^^^^^^
290272

291273
error: `var` doesn't refer to a field on this type
292-
--> $DIR/subdiagnostic-derive.rs:482:39
274+
--> $DIR/subdiagnostic-derive.rs:480:39
293275
|
294276
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
295277
| ^^^^^^^
296278

297279
error: `var` doesn't refer to a field on this type
298-
--> $DIR/subdiagnostic-derive.rs:501:43
280+
--> $DIR/subdiagnostic-derive.rs:499:43
299281
|
300282
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
301283
| ^^^^^^^
302284

285+
error: `#[suggestion_part]` is not a valid attribute
286+
--> $DIR/subdiagnostic-derive.rs:523:5
287+
|
288+
LL | #[suggestion_part]
289+
| ^^^^^^^^^^^^^^^^^^
290+
|
291+
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
292+
293+
error: `#[suggestion_part(...)]` is not a valid attribute
294+
--> $DIR/subdiagnostic-derive.rs:526:5
295+
|
296+
LL | #[suggestion_part(code = "...")]
297+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
298+
|
299+
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions
300+
301+
error: suggestion without `#[primary_span]` field
302+
--> $DIR/subdiagnostic-derive.rs:520:1
303+
|
304+
LL | / #[suggestion(parser::add_paren, code = "...")]
305+
LL | |
306+
LL | | struct BA {
307+
LL | | #[suggestion_part]
308+
... |
309+
LL | | var: String,
310+
LL | | }
311+
| |_^
312+
313+
error: `code` is not a valid nested attribute of a `multipart_suggestion` attribute
314+
--> $DIR/subdiagnostic-derive.rs:535:43
315+
|
316+
LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
317+
| ^^^^^^^^^^^^
318+
319+
error: multipart suggestion without any `#[suggestion_part(...)]` fields
320+
--> $DIR/subdiagnostic-derive.rs:535:1
321+
|
322+
LL | / #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
323+
LL | |
324+
LL | |
325+
LL | | struct BBa {
326+
LL | | var: String,
327+
LL | | }
328+
| |_^
329+
330+
error: `#[suggestion_part(...)]` attribute without `code = "..."`
331+
--> $DIR/subdiagnostic-derive.rs:545:5
332+
|
333+
LL | #[suggestion_part]
334+
| ^^^^^^^^^^^^^^^^^^
335+
336+
error: `#[suggestion_part(...)]` attribute without `code = "..."`
337+
--> $DIR/subdiagnostic-derive.rs:553:5
338+
|
339+
LL | #[suggestion_part()]
340+
| ^^^^^^^^^^^^^^^^^^^^
341+
342+
error: `#[primary_span]` is not a valid attribute
343+
--> $DIR/subdiagnostic-derive.rs:562:5
344+
|
345+
LL | #[primary_span]
346+
| ^^^^^^^^^^^^^^^
347+
|
348+
= help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
349+
350+
error: multipart suggestion without any `#[suggestion_part(...)]` fields
351+
--> $DIR/subdiagnostic-derive.rs:559:1
352+
|
353+
LL | / #[multipart_suggestion(parser::add_paren)]
354+
LL | |
355+
LL | | struct BC {
356+
LL | | #[primary_span]
357+
LL | |
358+
LL | | span: Span,
359+
LL | | }
360+
| |_^
361+
362+
error: `#[suggestion_part(...)]` attribute without `code = "..."`
363+
--> $DIR/subdiagnostic-derive.rs:570:5
364+
|
365+
LL | #[suggestion_part]
366+
| ^^^^^^^^^^^^^^^^^^
367+
368+
error: `#[suggestion_part(...)]` attribute without `code = "..."`
369+
--> $DIR/subdiagnostic-derive.rs:573:5
370+
|
371+
LL | #[suggestion_part()]
372+
| ^^^^^^^^^^^^^^^^^^^^
373+
374+
error: `#[suggestion_part(foo = ...)]` is not a valid attribute
375+
--> $DIR/subdiagnostic-derive.rs:576:23
376+
|
377+
LL | #[suggestion_part(foo = "bar")]
378+
| ^^^^^^^^^^^
379+
|
380+
= help: `code` is the only valid nested attribute
381+
382+
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
383+
--> $DIR/subdiagnostic-derive.rs:579:5
384+
|
385+
LL | #[suggestion_part(code = "...")]
386+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
387+
388+
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
389+
--> $DIR/subdiagnostic-derive.rs:582:5
390+
|
391+
LL | #[suggestion_part()]
392+
| ^^^^^^^^^^^^^^^^^^^^
393+
394+
error: specified multiple times
395+
--> $DIR/subdiagnostic-derive.rs:590:37
396+
|
397+
LL | #[suggestion_part(code = "...", code = ",,,")]
398+
| ^^^^^^^^^^^^
399+
|
400+
note: previously specified here
401+
--> $DIR/subdiagnostic-derive.rs:590:23
402+
|
403+
LL | #[suggestion_part(code = "...", code = ",,,")]
404+
| ^^^^^^^^^^^^
405+
406+
error: specified multiple times
407+
--> $DIR/subdiagnostic-derive.rs:620:5
408+
|
409+
LL | #[applicability]
410+
| ^^^^^^^^^^^^^^^^
411+
|
412+
note: previously specified here
413+
--> $DIR/subdiagnostic-derive.rs:617:43
414+
|
415+
LL | #[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
416+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
417+
303418
error: cannot find attribute `foo` in this scope
304419
--> $DIR/subdiagnostic-derive.rs:63:3
305420
|
@@ -360,6 +475,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
360475
LL | #[label(slug)]
361476
| ^^^^ not found in `rustc_errors::fluent`
362477

363-
error: aborting due to 49 previous errors
478+
error: aborting due to 64 previous errors
364479

365480
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)
Please sign in to comment.