2 // Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
4 // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
5 // changing the output of this test. Since SessionDiagnostic is strictly internal to the compiler
6 // the test is just ignored on stable and beta:
10 #![feature(rustc_private)]
11 #![crate_type = "lib"]
13 extern crate rustc_span;
15 use rustc_span::symbol::Ident;
17 extern crate rustc_macros;
18 use rustc_macros::SessionDiagnostic;
20 extern crate rustc_middle;
21 use rustc_middle::ty::Ty;
23 extern crate rustc_errors;
24 use rustc_errors::Applicability;
26 extern crate rustc_session;
28 #[derive(SessionDiagnostic)]
29 #[message = "Hello, world!"]
33 #[derive(SessionDiagnostic)]
35 //~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs
36 enum SessionDiagnosticOnEnum {
41 #[derive(SessionDiagnostic)]
43 #[label = "This is in the wrong place"]
44 //~^ ERROR `#[label = ...]` is not a valid SessionDiagnostic struct attribute
47 #[derive(SessionDiagnostic)]
49 struct WrongPlaceField {
50 #[suggestion = "this is the wrong kind of attribute"]
51 //~^ ERROR `#[suggestion = ...]` is not a valid SessionDiagnostic field attribute
55 #[derive(SessionDiagnostic)]
56 #[message = "Hello, world!"]
58 #[error = "E0456"] //~ ERROR `error` specified multiple times
59 struct ErrorSpecifiedTwice {}
61 #[derive(SessionDiagnostic)]
62 #[message = "Hello, world!"]
64 #[lint = "some_useful_lint"] //~ ERROR `lint` specified when `error` was already specified
65 struct LintSpecifiedAfterError {}
67 #[derive(SessionDiagnostic)]
68 #[message = "Some lint message"]
70 struct LintButHasErrorCode {}
72 #[derive(SessionDiagnostic)]
73 struct ErrorCodeNotProvided {} //~ ERROR `code` not specified
75 // FIXME: Uncomment when emitting lints is supported.
77 #[derive(SessionDiagnostic)]
78 #[message = "Hello, world!"]
79 #[lint = "clashing_extern_declarations"]
80 #[lint = "improper_ctypes"] // FIXME: ERROR `lint` specified multiple times
81 struct LintSpecifiedTwice {}
83 #[derive(SessionDiagnostic)]
84 #[lint = "Some lint message"]
85 #[message = "Some error message"]
86 #[error = "E0123"] // ERROR `error` specified when `lint` was already specified
87 struct ErrorSpecifiedAfterLint {}
90 #[derive(SessionDiagnostic)]
92 struct ErrorWithField {
94 #[message = "This error has a field, and references {name}"]
98 #[derive(SessionDiagnostic)]
100 struct ErrorWithMessageAppliedToField {
101 #[message = "this message is applied to a String field"]
102 //~^ ERROR the `#[message = "..."]` attribute can only be applied to fields of type Span
106 #[derive(SessionDiagnostic)]
108 #[message = "This error has a field, and references {name}"]
109 //~^ ERROR `name` doesn't refer to a field on this type
110 struct ErrorWithNonexistentField {
114 #[derive(SessionDiagnostic)]
116 #[message = "This is missing a closing brace: {name"]
117 //~^ ERROR invalid format string: expected `'}'`
118 struct ErrorMissingClosingBrace {
123 #[derive(SessionDiagnostic)]
125 #[message = "This is missing an opening brace: name}"]
126 //~^ ERROR invalid format string: unmatched `}`
127 struct ErrorMissingOpeningBrace {
132 #[derive(SessionDiagnostic)]
134 #[message = "Something something"]
136 #[label = "See here"]
140 #[derive(SessionDiagnostic)]
142 #[message = "Something something"]
143 struct LabelOnNonSpan {
144 #[label = "See here"]
145 //~^ ERROR The `#[label = ...]` attribute can only be applied to fields of type Span
149 #[derive(SessionDiagnostic)]
152 #[suggestion(message = "This is a suggestion", code = "This is the suggested code")]
153 #[suggestion_short(message = "This is a suggestion", code = "This is the suggested code")]
154 #[suggestion_hidden(message = "This is a suggestion", code = "This is the suggested code")]
155 #[suggestion_verbose(message = "This is a suggestion", code = "This is the suggested code")]
156 suggestion: (Span, Applicability),
159 #[derive(SessionDiagnostic)]
161 struct SuggestWithoutCode {
162 #[suggestion(message = "This is a suggestion")]
163 suggestion: (Span, Applicability),
166 #[derive(SessionDiagnostic)]
168 struct SuggestWithBadKey {
169 #[suggestion(nonsense = "This is nonsense")]
170 //~^ ERROR `nonsense` is not a valid key for `#[suggestion(...)]`
171 suggestion: (Span, Applicability),
174 #[derive(SessionDiagnostic)]
176 struct SuggestWithShorthandMsg {
177 #[suggestion(msg = "This is a suggestion")]
178 //~^ ERROR `msg` is not a valid key for `#[suggestion(...)]`
179 suggestion: (Span, Applicability),
182 #[derive(SessionDiagnostic)]
184 struct SuggestWithoutMsg {
185 #[suggestion(code = "This is suggested code")]
186 //~^ ERROR missing suggestion message
187 suggestion: (Span, Applicability),
190 #[derive(SessionDiagnostic)]
192 struct SuggestWithTypesSwapped {
193 #[suggestion(message = "This is a message", code = "This is suggested code")]
194 suggestion: (Applicability, Span),
197 #[derive(SessionDiagnostic)]
199 struct SuggestWithWrongTypeApplicabilityOnly {
200 #[suggestion(message = "This is a message", code = "This is suggested code")]
201 //~^ ERROR wrong field type for suggestion
202 suggestion: Applicability,
205 #[derive(SessionDiagnostic)]
207 struct SuggestWithSpanOnly{
208 #[suggestion(message = "This is a message", code = "This is suggested code")]
212 #[derive(SessionDiagnostic)]
214 struct SuggestWithDuplicateSpanAndApplicability {
215 #[suggestion(message = "This is a message", code = "This is suggested code")]
216 //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one Span
217 suggestion: (Span, Span, Applicability),
220 #[derive(SessionDiagnostic)]
222 struct SuggestWithDuplicateApplicabilityAndSpan {
223 #[suggestion(message = "This is a message", code = "This is suggested code")]
224 //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one
225 suggestion: (Applicability, Applicability, Span),
228 #[derive(SessionDiagnostic)]
230 struct WrongKindOfAnnotation {
231 #[label("wrong kind of annotation for label")]
232 //~^ ERROR invalid annotation list `#[label(...)]`
236 #[derive(SessionDiagnostic)]
238 #[message = "Something something else"]
239 struct OptionsInErrors {
240 #[label = "Label message"]
242 #[suggestion(message = "suggestion message")]
243 opt_sugg: Option<(Span, Applicability)>,
246 #[derive(SessionDiagnostic)]
248 struct MoveOutOfBorrowError<'tcx> {
251 #[message = "cannot move {ty} out of borrow"]
252 #[label = "cannot move out of borrow"]
254 #[label = "`{ty}` first borrowed here"]
256 #[suggestion(message = "consider cloning here", code = "{name}.clone()")]
257 opt_sugg: Option<(Span, Applicability)>,
260 #[derive(SessionDiagnostic)]
262 struct ErrorWithLifetime<'a> {
263 #[message = "Some message that references {name}"]