2 // Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
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:
12 #![feature(rustc_private)]
13 #![crate_type = "lib"]
15 extern crate rustc_span;
16 use rustc_span::symbol::Ident;
19 extern crate rustc_macros;
20 use rustc_macros::{SessionDiagnostic, LintDiagnostic, SessionSubdiagnostic};
22 extern crate rustc_middle;
23 use rustc_middle::ty::Ty;
25 extern crate rustc_errors;
26 use rustc_errors::{Applicability, MultiSpan};
28 extern crate rustc_session;
30 #[derive(SessionDiagnostic)]
31 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
34 #[derive(SessionDiagnostic)]
35 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
38 #[derive(SessionDiagnostic)]
39 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
40 //~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs
41 enum SessionDiagnosticOnEnum {
46 #[derive(SessionDiagnostic)]
47 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
49 //~^ ERROR `#[diag = ...]` is not a valid attribute
50 struct WrongStructAttrStyle {}
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 {}
59 #[derive(SessionDiagnostic)]
61 //~^ ERROR `#[diag("...")]` is not a valid attribute
62 //~^^ ERROR diagnostic slug not specified
63 struct InvalidLitNestedAttr {}
65 #[derive(SessionDiagnostic)]
66 #[diag(nonsense, code = "E0123")]
67 //~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent`
68 struct InvalidNestedStructAttr {}
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 {}
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 {}
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 {}
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 {}
93 #[derive(SessionDiagnostic)]
94 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
95 struct WrongPlaceField {
97 //~^ ERROR `#[suggestion = ...]` is not a valid attribute
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 {}
108 #[derive(SessionDiagnostic)]
109 #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
110 //~^ ERROR specified multiple times
111 struct CodeSpecifiedTwice {}
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 {}
118 #[derive(SessionDiagnostic)]
119 struct KindNotProvided {} //~ ERROR diagnostic slug not specified
121 #[derive(SessionDiagnostic)]
122 #[diag(code = "E0456")]
123 //~^ ERROR diagnostic slug not specified
124 struct SlugNotProvided {}
126 #[derive(SessionDiagnostic)]
127 #[diag(typeck::ambiguous_lifetime_bound)]
128 struct CodeNotProvided {}
130 #[derive(SessionDiagnostic)]
131 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
132 struct MessageWrongType {
134 //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
138 #[derive(SessionDiagnostic)]
139 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
140 struct InvalidPathFieldAttr {
142 //~^ ERROR `#[nonsense]` is not a valid attribute
143 //~^^ ERROR cannot find attribute `nonsense` in this scope
147 #[derive(SessionDiagnostic)]
148 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
149 struct ErrorWithField {
151 #[label(typeck::label)]
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`
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),
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),
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),
191 #[derive(SessionDiagnostic)]
192 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
194 #[label(typeck::label)]
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`
206 #[derive(SessionDiagnostic)]
207 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
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),
216 #[derive(SessionDiagnostic)]
217 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
218 struct SuggestWithoutCode {
219 #[suggestion(typeck::suggestion)]
220 suggestion: (Span, Applicability),
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),
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),
239 #[derive(SessionDiagnostic)]
240 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
241 struct SuggestWithoutMsg {
242 #[suggestion(code = "bar")]
243 suggestion: (Span, Applicability),
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),
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,
261 #[derive(SessionDiagnostic)]
262 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
263 struct SuggestWithSpanOnly {
264 #[suggestion(typeck::suggestion, code = "This is suggested code")]
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),
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),
284 #[derive(SessionDiagnostic)]
285 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
286 struct WrongKindOfAnnotation {
288 //~^ ERROR `#[label = ...]` is not a valid attribute
292 #[derive(SessionDiagnostic)]
293 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
294 struct OptionsInErrors {
295 #[label(typeck::label)]
297 #[suggestion(typeck::suggestion)]
298 opt_sugg: Option<(Span, Applicability)>,
301 #[derive(SessionDiagnostic)]
302 #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
303 struct MoveOutOfBorrowError<'tcx> {
307 #[label(typeck::label)]
309 #[label(typeck::label)]
311 #[suggestion(typeck::suggestion, code = "{name}.clone()")]
312 opt_sugg: Option<(Span, Applicability)>,
315 #[derive(SessionDiagnostic)]
316 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
317 struct ErrorWithLifetime<'a> {
318 #[label(typeck::label)]
323 #[derive(SessionDiagnostic)]
324 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
325 struct ErrorWithDefaultLabelAttr<'a> {
331 #[derive(SessionDiagnostic)]
332 //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
333 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
334 struct ArgFieldWithoutSkip {
340 #[derive(SessionDiagnostic)]
341 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
342 struct ArgFieldWithSkip {
345 // `Hello` does not implement `IntoDiagnosticArg` so this would result in an error if
346 // not for `#[skip_arg]`.
351 #[derive(SessionDiagnostic)]
352 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
353 struct ErrorWithSpannedNote {
358 #[derive(SessionDiagnostic)]
359 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
360 struct ErrorWithSpannedNoteCustom {
361 #[note(typeck::note)]
365 #[derive(SessionDiagnostic)]
366 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
368 struct ErrorWithNote {
372 #[derive(SessionDiagnostic)]
373 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
374 #[note(typeck::note)]
375 struct ErrorWithNoteCustom {
379 #[derive(SessionDiagnostic)]
380 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
381 struct ErrorWithSpannedHelp {
386 #[derive(SessionDiagnostic)]
387 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
388 struct ErrorWithSpannedHelpCustom {
389 #[help(typeck::help)]
393 #[derive(SessionDiagnostic)]
394 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
396 struct ErrorWithHelp {
400 #[derive(SessionDiagnostic)]
401 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
402 #[help(typeck::help)]
403 struct ErrorWithHelpCustom {
407 #[derive(SessionDiagnostic)]
409 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
410 struct ErrorWithHelpWrongOrder {
414 #[derive(SessionDiagnostic)]
415 #[help(typeck::help)]
416 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
417 struct ErrorWithHelpCustomWrongOrder {
421 #[derive(SessionDiagnostic)]
423 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
424 struct ErrorWithNoteWrongOrder {
428 #[derive(SessionDiagnostic)]
429 #[note(typeck::note)]
430 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
431 struct ErrorWithNoteCustomWrongOrder {
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),
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
451 #[derive(SessionDiagnostic)]
452 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
453 struct ValidApplicability {
454 #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
458 #[derive(SessionDiagnostic)]
459 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
460 struct NoApplicability {
461 #[suggestion(typeck::suggestion, code = "...")]
465 #[derive(SessionSubdiagnostic)]
466 #[note(parser::add_paren)]
469 #[derive(SessionDiagnostic)]
470 #[diag(typeck::ambiguous_lifetime_bound)]
471 struct Subdiagnostic {
476 #[derive(SessionDiagnostic)]
477 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
484 #[derive(SessionDiagnostic)]
485 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
491 #[help(typeck::help)]
495 #[derive(SessionDiagnostic)]
496 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
497 struct OptUnitField {
502 #[help(typeck::help)]
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
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
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
530 #[derive(LintDiagnostic)]
531 #[diag(typeck::ambiguous_lifetime_bound)]
535 #[derive(LintDiagnostic)]
536 #[diag(typeck::ambiguous_lifetime_bound)]
537 struct PrimarySpanOnLint {
539 //~^ ERROR `#[primary_span]` is not a valid attribute
543 #[derive(SessionDiagnostic)]
544 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
545 struct ErrorWithMultiSpan {
550 #[derive(SessionDiagnostic)]
551 #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
553 struct ErrorWithWarn {
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 {}
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 {}
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 {}
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 {}