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