]> git.lizzy.rs Git - rust.git/blob - src/librustc_passes/error_codes.rs
Auto merge of #65152 - tmandry:rollup-btn4a01, r=tmandry
[rust.git] / src / librustc_passes / error_codes.rs
1 syntax::register_diagnostics! {
2 /*
3 E0014: r##"
4 Constants can only be initialized by a constant value or, in a future
5 version of Rust, a call to a const function. This error indicates the use
6 of a path (like a::b, or x) denoting something other than one of these
7 allowed items. Erroneous code xample:
8
9 ```compile_fail
10 const FOO: i32 = { let x = 0; x }; // 'x' isn't a constant nor a function!
11 ```
12
13 To avoid it, you have to replace the non-constant value:
14
15 ```
16 const FOO: i32 = { const X : i32 = 0; X };
17 // or even:
18 const FOO2: i32 = { 0 }; // but brackets are useless here
19 ```
20 "##,
21 */
22
23 E0130: r##"
24 You declared a pattern as an argument in a foreign function declaration.
25 Erroneous code example:
26
27 ```compile_fail
28 extern {
29     fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
30                                 //        function declarations
31 }
32 ```
33
34 Please replace the pattern argument with a regular one. Example:
35
36 ```
37 struct SomeStruct {
38     a: u32,
39     b: u32,
40 }
41
42 extern {
43     fn foo(s: SomeStruct); // ok!
44 }
45 ```
46
47 Or:
48
49 ```
50 extern {
51     fn foo(a: (u32, u32)); // ok!
52 }
53 ```
54 "##,
55
56 E0197: r##"
57 Inherent implementations (one that do not implement a trait but provide
58 methods associated with a type) are always safe because they are not
59 implementing an unsafe trait. Removing the `unsafe` keyword from the inherent
60 implementation will resolve this error.
61
62 ```compile_fail,E0197
63 struct Foo;
64
65 // this will cause this error
66 unsafe impl Foo { }
67 // converting it to this will fix it
68 impl Foo { }
69 ```
70 "##,
71
72 E0198: r##"
73 A negative implementation is one that excludes a type from implementing a
74 particular trait. Not being able to use a trait is always a safe operation,
75 so negative implementations are always safe and never need to be marked as
76 unsafe.
77
78 ```compile_fail
79 #![feature(optin_builtin_traits)]
80
81 struct Foo;
82
83 // unsafe is unnecessary
84 unsafe impl !Clone for Foo { }
85 ```
86
87 This will compile:
88
89 ```ignore (ignore auto_trait future compatibility warning)
90 #![feature(optin_builtin_traits)]
91
92 struct Foo;
93
94 auto trait Enterprise {}
95
96 impl !Enterprise for Foo { }
97 ```
98
99 Please note that negative impls are only allowed for auto traits.
100 "##,
101
102 E0267: r##"
103 This error indicates the use of a loop keyword (`break` or `continue`) inside a
104 closure but outside of any loop. Erroneous code example:
105
106 ```compile_fail,E0267
107 let w = || { break; }; // error: `break` inside of a closure
108 ```
109
110 `break` and `continue` keywords can be used as normal inside closures as long as
111 they are also contained within a loop. To halt the execution of a closure you
112 should instead use a return statement. Example:
113
114 ```
115 let w = || {
116     for _ in 0..10 {
117         break;
118     }
119 };
120
121 w();
122 ```
123 "##,
124
125 E0268: r##"
126 This error indicates the use of a loop keyword (`break` or `continue`) outside
127 of a loop. Without a loop to break out of or continue in, no sensible action can
128 be taken. Erroneous code example:
129
130 ```compile_fail,E0268
131 fn some_func() {
132     break; // error: `break` outside of a loop
133 }
134 ```
135
136 Please verify that you are using `break` and `continue` only in loops. Example:
137
138 ```
139 fn some_func() {
140     for _ in 0..10 {
141         break; // ok!
142     }
143 }
144 ```
145 "##,
146
147 E0379: r##"
148 Trait methods cannot be declared `const` by design. For more information, see
149 [RFC 911].
150
151 [RFC 911]: https://github.com/rust-lang/rfcs/pull/911
152 "##,
153
154 E0380: r##"
155 Auto traits cannot have methods or associated items.
156 For more information see the [opt-in builtin traits RFC][RFC 19].
157
158 [RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
159 "##,
160
161 E0449: r##"
162 A visibility qualifier was used when it was unnecessary. Erroneous code
163 examples:
164
165 ```compile_fail,E0449
166 struct Bar;
167
168 trait Foo {
169     fn foo();
170 }
171
172 pub impl Bar {} // error: unnecessary visibility qualifier
173
174 pub impl Foo for Bar { // error: unnecessary visibility qualifier
175     pub fn foo() {} // error: unnecessary visibility qualifier
176 }
177 ```
178
179 To fix this error, please remove the visibility qualifier when it is not
180 required. Example:
181
182 ```
183 struct Bar;
184
185 trait Foo {
186     fn foo();
187 }
188
189 // Directly implemented methods share the visibility of the type itself,
190 // so `pub` is unnecessary here
191 impl Bar {}
192
193 // Trait methods share the visibility of the trait, so `pub` is
194 // unnecessary in either case
195 impl Foo for Bar {
196     fn foo() {}
197 }
198 ```
199 "##,
200
201
202 E0590: r##"
203 `break` or `continue` must include a label when used in the condition of a
204 `while` loop.
205
206 Example of erroneous code:
207
208 ```compile_fail
209 while break {}
210 ```
211
212 To fix this, add a label specifying which loop is being broken out of:
213 ```
214 'foo: while break 'foo {}
215 ```
216 "##,
217
218 E0571: r##"
219 A `break` statement with an argument appeared in a non-`loop` loop.
220
221 Example of erroneous code:
222
223 ```compile_fail,E0571
224 # let mut i = 1;
225 # fn satisfied(n: usize) -> bool { n % 23 == 0 }
226 let result = while true {
227     if satisfied(i) {
228         break 2*i; // error: `break` with value from a `while` loop
229     }
230     i += 1;
231 };
232 ```
233
234 The `break` statement can take an argument (which will be the value of the loop
235 expression if the `break` statement is executed) in `loop` loops, but not
236 `for`, `while`, or `while let` loops.
237
238 Make sure `break value;` statements only occur in `loop` loops:
239
240 ```
241 # let mut i = 1;
242 # fn satisfied(n: usize) -> bool { n % 23 == 0 }
243 let result = loop { // ok!
244     if satisfied(i) {
245         break 2*i;
246     }
247     i += 1;
248 };
249 ```
250 "##,
251
252 E0642: r##"
253 Trait methods currently cannot take patterns as arguments.
254
255 Example of erroneous code:
256
257 ```compile_fail,E0642
258 trait Foo {
259     fn foo((x, y): (i32, i32)); // error: patterns aren't allowed
260                                 //        in trait methods
261 }
262 ```
263
264 You can instead use a single name for the argument:
265
266 ```
267 trait Foo {
268     fn foo(x_and_y: (i32, i32)); // ok!
269 }
270 ```
271 "##,
272
273 E0695: r##"
274 A `break` statement without a label appeared inside a labeled block.
275
276 Example of erroneous code:
277
278 ```compile_fail,E0695
279 # #![feature(label_break_value)]
280 loop {
281     'a: {
282         break;
283     }
284 }
285 ```
286
287 Make sure to always label the `break`:
288
289 ```
290 # #![feature(label_break_value)]
291 'l: loop {
292     'a: {
293         break 'l;
294     }
295 }
296 ```
297
298 Or if you want to `break` the labeled block:
299
300 ```
301 # #![feature(label_break_value)]
302 loop {
303     'a: {
304         break 'a;
305     }
306     break;
307 }
308 ```
309 "##,
310
311 E0670: r##"
312 Rust 2015 does not permit the use of `async fn`.
313
314 Example of erroneous code:
315
316 ```compile_fail,E0670
317 async fn foo() {}
318 ```
319
320 Switch to the Rust 2018 edition to use `async fn`.
321 "##,
322
323 // This shouldn't really ever trigger since the repeated value error comes first
324 E0136: r##"
325 A binary can only have one entry point, and by default that entry point is the
326 function `main()`. If there are multiple such functions, please rename one.
327 "##,
328
329 E0137: r##"
330 More than one function was declared with the `#[main]` attribute.
331
332 Erroneous code example:
333
334 ```compile_fail,E0137
335 #![feature(main)]
336
337 #[main]
338 fn foo() {}
339
340 #[main]
341 fn f() {} // error: multiple functions with a `#[main]` attribute
342 ```
343
344 This error indicates that the compiler found multiple functions with the
345 `#[main]` attribute. This is an error because there must be a unique entry
346 point into a Rust program. Example:
347
348 ```
349 #![feature(main)]
350
351 #[main]
352 fn f() {} // ok!
353 ```
354 "##,
355
356 E0138: r##"
357 More than one function was declared with the `#[start]` attribute.
358
359 Erroneous code example:
360
361 ```compile_fail,E0138
362 #![feature(start)]
363
364 #[start]
365 fn foo(argc: isize, argv: *const *const u8) -> isize {}
366
367 #[start]
368 fn f(argc: isize, argv: *const *const u8) -> isize {}
369 // error: multiple 'start' functions
370 ```
371
372 This error indicates that the compiler found multiple functions with the
373 `#[start]` attribute. This is an error because there must be a unique entry
374 point into a Rust program. Example:
375
376 ```
377 #![feature(start)]
378
379 #[start]
380 fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
381 ```
382 "##,
383
384 E0601: r##"
385 No `main` function was found in a binary crate. To fix this error, add a
386 `main` function. For example:
387
388 ```
389 fn main() {
390     // Your program will start here.
391     println!("Hello world!");
392 }
393 ```
394
395 If you don't know the basics of Rust, you can go look to the Rust Book to get
396 started: https://doc.rust-lang.org/book/
397 "##,
398
399 E0591: r##"
400 Per [RFC 401][rfc401], if you have a function declaration `foo`:
401
402 ```
403 // For the purposes of this explanation, all of these
404 // different kinds of `fn` declarations are equivalent:
405 struct S;
406 fn foo(x: S) { /* ... */ }
407 # #[cfg(for_demonstration_only)]
408 extern "C" { fn foo(x: S); }
409 # #[cfg(for_demonstration_only)]
410 impl S { fn foo(self) { /* ... */ } }
411 ```
412
413 the type of `foo` is **not** `fn(S)`, as one might expect.
414 Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`.
415 However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`,
416 so you rarely notice this:
417
418 ```
419 # struct S;
420 # fn foo(_: S) {}
421 let x: fn(S) = foo; // OK, coerces
422 ```
423
424 The reason that this matter is that the type `fn(S)` is not specific to
425 any particular function: it's a function _pointer_. So calling `x()` results
426 in a virtual call, whereas `foo()` is statically dispatched, because the type
427 of `foo` tells us precisely what function is being called.
428
429 As noted above, coercions mean that most code doesn't have to be
430 concerned with this distinction. However, you can tell the difference
431 when using **transmute** to convert a fn item into a fn pointer.
432
433 This is sometimes done as part of an FFI:
434
435 ```compile_fail,E0591
436 extern "C" fn foo(userdata: Box<i32>) {
437     /* ... */
438 }
439
440 # fn callback(_: extern "C" fn(*mut i32)) {}
441 # use std::mem::transmute;
442 # unsafe {
443 let f: extern "C" fn(*mut i32) = transmute(foo);
444 callback(f);
445 # }
446 ```
447
448 Here, transmute is being used to convert the types of the fn arguments.
449 This pattern is incorrect because, because the type of `foo` is a function
450 **item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
451 is a function pointer, which is not zero-sized.
452 This pattern should be rewritten. There are a few possible ways to do this:
453
454 - change the original fn declaration to match the expected signature,
455   and do the cast in the fn body (the preferred option)
456 - cast the fn item fo a fn pointer before calling transmute, as shown here:
457
458     ```
459     # extern "C" fn foo(_: Box<i32>) {}
460     # use std::mem::transmute;
461     # unsafe {
462     let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
463     let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
464     # }
465     ```
466
467 The same applies to transmutes to `*mut fn()`, which were observed in practice.
468 Note though that use of this type is generally incorrect.
469 The intention is typically to describe a function pointer, but just `fn()`
470 alone suffices for that. `*mut fn()` is a pointer to a fn pointer.
471 (Since these values are typically just passed to C code, however, this rarely
472 makes a difference in practice.)
473
474 [rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
475 "##,
476
477 E0512: r##"
478 Transmute with two differently sized types was attempted. Erroneous code
479 example:
480
481 ```compile_fail,E0512
482 fn takes_u8(_: u8) {}
483
484 fn main() {
485     unsafe { takes_u8(::std::mem::transmute(0u16)); }
486     // error: cannot transmute between types of different sizes,
487     //        or dependently-sized types
488 }
489 ```
490
491 Please use types with same size or use the expected type directly. Example:
492
493 ```
494 fn takes_u8(_: u8) {}
495
496 fn main() {
497     unsafe { takes_u8(::std::mem::transmute(0i8)); } // ok!
498     // or:
499     unsafe { takes_u8(0u8); } // ok!
500 }
501 ```
502 "##,
503
504 ;
505     E0226, // only a single explicit lifetime bound is permitted
506     E0472, // asm! is unsupported on this target
507     E0561, // patterns aren't allowed in function pointer types
508     E0567, // auto traits can not have generic parameters
509     E0568, // auto traits can not have super traits
510     E0666, // nested `impl Trait` is illegal
511     E0667, // `impl Trait` in projections
512     E0696, // `continue` pointing to a labeled block
513     E0706, // `async fn` in trait
514 }