]> git.lizzy.rs Git - rust.git/blob - src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
Rollup merge of #101580 - notriddle:notriddle/div-impl-items-div, r=GuillaumeGomez
[rust.git] / src / test / ui-fulldeps / session-diagnostic / diagnostic-derive.rs
1 // check-fail
2 // Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
3
4 // normalize-stderr-test "the following other types implement trait `IntoDiagnosticArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr"
5 // normalize-stderr-test "diagnostic_builder\.rs:[0-9]+:[0-9]+" -> "diagnostic_builder.rs:LL:CC"
6 // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
7 // changing the output of this test. Since SessionDiagnostic is strictly internal to the compiler
8 // the test is just ignored on stable and beta:
9 // ignore-beta
10 // ignore-stable
11
12 #![feature(rustc_private)]
13 #![crate_type = "lib"]
14
15 extern crate rustc_span;
16 use rustc_span::symbol::Ident;
17 use rustc_span::Span;
18
19 extern crate rustc_macros;
20 use rustc_macros::{SessionDiagnostic, LintDiagnostic, SessionSubdiagnostic};
21
22 extern crate rustc_middle;
23 use rustc_middle::ty::Ty;
24
25 extern crate rustc_errors;
26 use rustc_errors::{Applicability, MultiSpan};
27
28 extern crate rustc_session;
29
30 #[derive(SessionDiagnostic)]
31 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
32 struct Hello {}
33
34 #[derive(SessionDiagnostic)]
35 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
36 struct HelloWarn {}
37
38 #[derive(SessionDiagnostic)]
39 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
40 //~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs
41 enum SessionDiagnosticOnEnum {
42     Foo,
43     Bar,
44 }
45
46 #[derive(SessionDiagnostic)]
47 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
48 #[diag = "E0123"]
49 //~^ ERROR `#[diag = ...]` is not a valid attribute
50 struct WrongStructAttrStyle {}
51
52 #[derive(SessionDiagnostic)]
53 #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
54 //~^ ERROR `#[nonsense(...)]` is not a valid attribute
55 //~^^ ERROR diagnostic slug not specified
56 //~^^^ ERROR cannot find attribute `nonsense` in this scope
57 struct InvalidStructAttr {}
58
59 #[derive(SessionDiagnostic)]
60 #[diag("E0123")]
61 //~^ ERROR `#[diag("...")]` is not a valid attribute
62 //~^^ ERROR diagnostic slug not specified
63 struct InvalidLitNestedAttr {}
64
65 #[derive(SessionDiagnostic)]
66 #[diag(nonsense, code = "E0123")]
67 //~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent`
68 struct InvalidNestedStructAttr {}
69
70 #[derive(SessionDiagnostic)]
71 #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
72 //~^ ERROR `#[diag(nonsense(...))]` is not a valid attribute
73 //~^^ ERROR diagnostic slug not specified
74 struct InvalidNestedStructAttr1 {}
75
76 #[derive(SessionDiagnostic)]
77 #[diag(nonsense = "...", code = "E0123", slug = "foo")]
78 //~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
79 //~^^ ERROR diagnostic slug not specified
80 struct InvalidNestedStructAttr2 {}
81
82 #[derive(SessionDiagnostic)]
83 #[diag(nonsense = 4, code = "E0123", slug = "foo")]
84 //~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
85 //~^^ ERROR diagnostic slug not specified
86 struct InvalidNestedStructAttr3 {}
87
88 #[derive(SessionDiagnostic)]
89 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
90 //~^ ERROR `#[diag(slug = ...)]` is not a valid attribute
91 struct InvalidNestedStructAttr4 {}
92
93 #[derive(SessionDiagnostic)]
94 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
95 struct WrongPlaceField {
96     #[suggestion = "bar"]
97     //~^ ERROR `#[suggestion = ...]` is not a valid attribute
98     sp: Span,
99 }
100
101 #[derive(SessionDiagnostic)]
102 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
103 #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
104 //~^ ERROR specified multiple times
105 //~^^ ERROR specified multiple times
106 struct DiagSpecifiedTwice {}
107
108 #[derive(SessionDiagnostic)]
109 #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
110 //~^ ERROR specified multiple times
111 struct CodeSpecifiedTwice {}
112
113 #[derive(SessionDiagnostic)]
114 #[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
115 //~^ ERROR `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
116 struct SlugSpecifiedTwice {}
117
118 #[derive(SessionDiagnostic)]
119 struct KindNotProvided {} //~ ERROR diagnostic slug not specified
120
121 #[derive(SessionDiagnostic)]
122 #[diag(code = "E0456")]
123 //~^ ERROR diagnostic slug not specified
124 struct SlugNotProvided {}
125
126 #[derive(SessionDiagnostic)]
127 #[diag(typeck::ambiguous_lifetime_bound)]
128 struct CodeNotProvided {}
129
130 #[derive(SessionDiagnostic)]
131 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
132 struct MessageWrongType {
133     #[primary_span]
134     //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
135     foo: String,
136 }
137
138 #[derive(SessionDiagnostic)]
139 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
140 struct InvalidPathFieldAttr {
141     #[nonsense]
142     //~^ ERROR `#[nonsense]` is not a valid attribute
143     //~^^ ERROR cannot find attribute `nonsense` in this scope
144     foo: String,
145 }
146
147 #[derive(SessionDiagnostic)]
148 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
149 struct ErrorWithField {
150     name: String,
151     #[label(typeck::label)]
152     span: Span,
153 }
154
155 #[derive(SessionDiagnostic)]
156 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
157 struct ErrorWithMessageAppliedToField {
158     #[label(typeck::label)]
159     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
160     name: String,
161 }
162
163 #[derive(SessionDiagnostic)]
164 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
165 struct ErrorWithNonexistentField {
166     #[suggestion(typeck::suggestion, code = "{name}")]
167     //~^ ERROR `name` doesn't refer to a field on this type
168     suggestion: (Span, Applicability),
169 }
170
171 #[derive(SessionDiagnostic)]
172 //~^ ERROR invalid format string: expected `'}'`
173 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
174 struct ErrorMissingClosingBrace {
175     #[suggestion(typeck::suggestion, code = "{name")]
176     suggestion: (Span, Applicability),
177     name: String,
178     val: usize,
179 }
180
181 #[derive(SessionDiagnostic)]
182 //~^ ERROR invalid format string: unmatched `}`
183 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
184 struct ErrorMissingOpeningBrace {
185     #[suggestion(typeck::suggestion, code = "name}")]
186     suggestion: (Span, Applicability),
187     name: String,
188     val: usize,
189 }
190
191 #[derive(SessionDiagnostic)]
192 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
193 struct LabelOnSpan {
194     #[label(typeck::label)]
195     sp: Span,
196 }
197
198 #[derive(SessionDiagnostic)]
199 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
200 struct LabelOnNonSpan {
201     #[label(typeck::label)]
202     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
203     id: u32,
204 }
205
206 #[derive(SessionDiagnostic)]
207 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
208 struct Suggest {
209     #[suggestion(typeck::suggestion, code = "This is the suggested code")]
210     #[suggestion_short(typeck::suggestion, code = "This is the suggested code")]
211     #[suggestion_hidden(typeck::suggestion, code = "This is the suggested code")]
212     #[suggestion_verbose(typeck::suggestion, code = "This is the suggested code")]
213     suggestion: (Span, Applicability),
214 }
215
216 #[derive(SessionDiagnostic)]
217 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
218 struct SuggestWithoutCode {
219     #[suggestion(typeck::suggestion)]
220     suggestion: (Span, Applicability),
221 }
222
223 #[derive(SessionDiagnostic)]
224 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
225 struct SuggestWithBadKey {
226     #[suggestion(nonsense = "bar")]
227     //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute
228     suggestion: (Span, Applicability),
229 }
230
231 #[derive(SessionDiagnostic)]
232 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
233 struct SuggestWithShorthandMsg {
234     #[suggestion(msg = "bar")]
235     //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute
236     suggestion: (Span, Applicability),
237 }
238
239 #[derive(SessionDiagnostic)]
240 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
241 struct SuggestWithoutMsg {
242     #[suggestion(code = "bar")]
243     suggestion: (Span, Applicability),
244 }
245
246 #[derive(SessionDiagnostic)]
247 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
248 struct SuggestWithTypesSwapped {
249     #[suggestion(typeck::suggestion, code = "This is suggested code")]
250     suggestion: (Applicability, Span),
251 }
252
253 #[derive(SessionDiagnostic)]
254 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
255 struct SuggestWithWrongTypeApplicabilityOnly {
256     #[suggestion(typeck::suggestion, code = "This is suggested code")]
257     //~^ ERROR wrong field type for suggestion
258     suggestion: Applicability,
259 }
260
261 #[derive(SessionDiagnostic)]
262 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
263 struct SuggestWithSpanOnly {
264     #[suggestion(typeck::suggestion, code = "This is suggested code")]
265     suggestion: Span,
266 }
267
268 #[derive(SessionDiagnostic)]
269 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
270 struct SuggestWithDuplicateSpanAndApplicability {
271     #[suggestion(typeck::suggestion, code = "This is suggested code")]
272     //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one `Span`
273     suggestion: (Span, Span, Applicability),
274 }
275
276 #[derive(SessionDiagnostic)]
277 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
278 struct SuggestWithDuplicateApplicabilityAndSpan {
279     #[suggestion(typeck::suggestion, code = "This is suggested code")]
280     //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one
281     suggestion: (Applicability, Applicability, Span),
282 }
283
284 #[derive(SessionDiagnostic)]
285 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
286 struct WrongKindOfAnnotation {
287     #[label = "bar"]
288     //~^ ERROR `#[label = ...]` is not a valid attribute
289     z: Span,
290 }
291
292 #[derive(SessionDiagnostic)]
293 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
294 struct OptionsInErrors {
295     #[label(typeck::label)]
296     label: Option<Span>,
297     #[suggestion(typeck::suggestion)]
298     opt_sugg: Option<(Span, Applicability)>,
299 }
300
301 #[derive(SessionDiagnostic)]
302 #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
303 struct MoveOutOfBorrowError<'tcx> {
304     name: Ident,
305     ty: Ty<'tcx>,
306     #[primary_span]
307     #[label(typeck::label)]
308     span: Span,
309     #[label(typeck::label)]
310     other_span: Span,
311     #[suggestion(typeck::suggestion, code = "{name}.clone()")]
312     opt_sugg: Option<(Span, Applicability)>,
313 }
314
315 #[derive(SessionDiagnostic)]
316 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
317 struct ErrorWithLifetime<'a> {
318     #[label(typeck::label)]
319     span: Span,
320     name: &'a str,
321 }
322
323 #[derive(SessionDiagnostic)]
324 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
325 struct ErrorWithDefaultLabelAttr<'a> {
326     #[label]
327     span: Span,
328     name: &'a str,
329 }
330
331 #[derive(SessionDiagnostic)]
332 //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
333 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
334 struct ArgFieldWithoutSkip {
335     #[primary_span]
336     span: Span,
337     other: Hello,
338 }
339
340 #[derive(SessionDiagnostic)]
341 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
342 struct ArgFieldWithSkip {
343     #[primary_span]
344     span: Span,
345     // `Hello` does not implement `IntoDiagnosticArg` so this would result in an error if
346     // not for `#[skip_arg]`.
347     #[skip_arg]
348     other: Hello,
349 }
350
351 #[derive(SessionDiagnostic)]
352 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
353 struct ErrorWithSpannedNote {
354     #[note]
355     span: Span,
356 }
357
358 #[derive(SessionDiagnostic)]
359 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
360 struct ErrorWithSpannedNoteCustom {
361     #[note(typeck::note)]
362     span: Span,
363 }
364
365 #[derive(SessionDiagnostic)]
366 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
367 #[note]
368 struct ErrorWithNote {
369     val: String,
370 }
371
372 #[derive(SessionDiagnostic)]
373 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
374 #[note(typeck::note)]
375 struct ErrorWithNoteCustom {
376     val: String,
377 }
378
379 #[derive(SessionDiagnostic)]
380 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
381 struct ErrorWithSpannedHelp {
382     #[help]
383     span: Span,
384 }
385
386 #[derive(SessionDiagnostic)]
387 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
388 struct ErrorWithSpannedHelpCustom {
389     #[help(typeck::help)]
390     span: Span,
391 }
392
393 #[derive(SessionDiagnostic)]
394 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
395 #[help]
396 struct ErrorWithHelp {
397     val: String,
398 }
399
400 #[derive(SessionDiagnostic)]
401 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
402 #[help(typeck::help)]
403 struct ErrorWithHelpCustom {
404     val: String,
405 }
406
407 #[derive(SessionDiagnostic)]
408 #[help]
409 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
410 struct ErrorWithHelpWrongOrder {
411     val: String,
412 }
413
414 #[derive(SessionDiagnostic)]
415 #[help(typeck::help)]
416 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
417 struct ErrorWithHelpCustomWrongOrder {
418     val: String,
419 }
420
421 #[derive(SessionDiagnostic)]
422 #[note]
423 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
424 struct ErrorWithNoteWrongOrder {
425     val: String,
426 }
427
428 #[derive(SessionDiagnostic)]
429 #[note(typeck::note)]
430 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
431 struct ErrorWithNoteCustomWrongOrder {
432     val: String,
433 }
434
435 #[derive(SessionDiagnostic)]
436 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
437 struct ApplicabilityInBoth {
438     #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
439     //~^ ERROR applicability cannot be set in both the field and attribute
440     suggestion: (Span, Applicability),
441 }
442
443 #[derive(SessionDiagnostic)]
444 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
445 struct InvalidApplicability {
446     #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
447     //~^ ERROR invalid applicability
448     suggestion: Span,
449 }
450
451 #[derive(SessionDiagnostic)]
452 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
453 struct ValidApplicability {
454     #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
455     suggestion: Span,
456 }
457
458 #[derive(SessionDiagnostic)]
459 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
460 struct NoApplicability {
461     #[suggestion(typeck::suggestion, code = "...")]
462     suggestion: Span,
463 }
464
465 #[derive(SessionSubdiagnostic)]
466 #[note(parser::add_paren)]
467 struct Note;
468
469 #[derive(SessionDiagnostic)]
470 #[diag(typeck::ambiguous_lifetime_bound)]
471 struct Subdiagnostic {
472     #[subdiagnostic]
473     note: Note,
474 }
475
476 #[derive(SessionDiagnostic)]
477 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
478 struct VecField {
479     #[primary_span]
480     #[label]
481     spans: Vec<Span>,
482 }
483
484 #[derive(SessionDiagnostic)]
485 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
486 struct UnitField {
487     #[primary_span]
488     spans: Span,
489     #[help]
490     foo: (),
491     #[help(typeck::help)]
492     bar: (),
493 }
494
495 #[derive(SessionDiagnostic)]
496 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
497 struct OptUnitField {
498     #[primary_span]
499     spans: Span,
500     #[help]
501     foo: Option<()>,
502     #[help(typeck::help)]
503     bar: Option<()>,
504 }
505
506 #[derive(SessionDiagnostic)]
507 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
508 struct LabelWithTrailingPath {
509     #[label(typeck::label, foo)]
510     //~^ ERROR `#[label(...)]` is not a valid attribute
511     span: Span,
512 }
513
514 #[derive(SessionDiagnostic)]
515 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
516 struct LabelWithTrailingNameValue {
517     #[label(typeck::label, foo = "...")]
518     //~^ ERROR `#[label(...)]` is not a valid attribute
519     span: Span,
520 }
521
522 #[derive(SessionDiagnostic)]
523 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
524 struct LabelWithTrailingList {
525     #[label(typeck::label, foo("..."))]
526     //~^ ERROR `#[label(...)]` is not a valid attribute
527     span: Span,
528 }
529
530 #[derive(LintDiagnostic)]
531 #[diag(typeck::ambiguous_lifetime_bound)]
532 struct LintsGood {
533 }
534
535 #[derive(LintDiagnostic)]
536 #[diag(typeck::ambiguous_lifetime_bound)]
537 struct PrimarySpanOnLint {
538     #[primary_span]
539     //~^ ERROR `#[primary_span]` is not a valid attribute
540     span: Span,
541 }
542
543 #[derive(SessionDiagnostic)]
544 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
545 struct ErrorWithMultiSpan {
546     #[primary_span]
547     span: MultiSpan,
548 }
549
550 #[derive(SessionDiagnostic)]
551 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
552 #[warning]
553 struct ErrorWithWarn {
554     val: String,
555 }
556
557 #[derive(SessionDiagnostic)]
558 #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
559 //~^ ERROR `#[error(...)]` is not a valid attribute
560 //~| ERROR diagnostic slug not specified
561 //~| ERROR cannot find attribute `error` in this scope
562 struct ErrorAttribute {}
563
564 #[derive(SessionDiagnostic)]
565 #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
566 //~^ ERROR `#[warn_(...)]` is not a valid attribute
567 //~| ERROR diagnostic slug not specified
568 //~| ERROR cannot find attribute `warn_` in this scope
569 struct WarnAttribute {}
570
571 #[derive(SessionDiagnostic)]
572 #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
573 //~^ ERROR `#[lint(...)]` is not a valid attribute
574 //~| ERROR diagnostic slug not specified
575 //~| ERROR cannot find attribute `lint` in this scope
576 struct LintAttributeOnSessionDiag {}
577
578 #[derive(LintDiagnostic)]
579 #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
580 //~^ ERROR `#[lint(...)]` is not a valid attribute
581 //~| ERROR diagnostic slug not specified
582 //~| ERROR cannot find attribute `lint` in this scope
583 struct LintAttributeOnLintDiag {}