]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | #![allow(non_snake_case)] | |
12 | ||
9346a6ac AL |
13 | // Error messages for EXXXX errors. |
14 | // Each message should start and end with a new line, and be wrapped to 80 characters. | |
15 | // In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. | |
85aaf69f | 16 | register_long_diagnostics! { |
d9579d0f AL |
17 | E0020: r##" |
18 | This error indicates that an attempt was made to divide by zero (or take the | |
e9174d1e SL |
19 | remainder of a zero divisor) in a static or constant expression. Erroneous |
20 | code example: | |
21 | ||
7453a54e | 22 | ```compile_fail |
3157f602 XL |
23 | #[deny(const_err)] |
24 | ||
e9174d1e | 25 | const X: i32 = 42 / 0; |
5bcae85e | 26 | // error: attempt to divide by zero in a constant expression |
e9174d1e | 27 | ``` |
d9579d0f AL |
28 | "##, |
29 | ||
7453a54e | 30 | E0038: r##" |
c1a9b12d SL |
31 | Trait objects like `Box<Trait>` can only be constructed when certain |
32 | requirements are satisfied by the trait in question. | |
33 | ||
34 | Trait objects are a form of dynamic dispatch and use a dynamically sized type | |
35 | for the inner type. So, for a given trait `Trait`, when `Trait` is treated as a | |
36 | type, as in `Box<Trait>`, the inner type is 'unsized'. In such cases the boxed | |
37 | pointer is a 'fat pointer' that contains an extra pointer to a table of methods | |
38 | (among other things) for dynamic dispatch. This design mandates some | |
39 | restrictions on the types of traits that are allowed to be used in trait | |
40 | objects, which are collectively termed as 'object safety' rules. | |
41 | ||
42 | Attempting to create a trait object for a non object-safe trait will trigger | |
43 | this error. | |
44 | ||
45 | There are various rules: | |
46 | ||
47 | ### The trait cannot require `Self: Sized` | |
48 | ||
49 | When `Trait` is treated as a type, the type does not implement the special | |
50 | `Sized` trait, because the type does not have a known size at compile time and | |
51 | can only be accessed behind a pointer. Thus, if we have a trait like the | |
52 | following: | |
53 | ||
54 | ``` | |
55 | trait Foo where Self: Sized { | |
56 | ||
57 | } | |
58 | ``` | |
59 | ||
7453a54e | 60 | We cannot create an object of type `Box<Foo>` or `&Foo` since in this case |
c1a9b12d SL |
61 | `Self` would not be `Sized`. |
62 | ||
63 | Generally, `Self : Sized` is used to indicate that the trait should not be used | |
64 | as a trait object. If the trait comes from your own crate, consider removing | |
65 | this restriction. | |
66 | ||
67 | ### Method references the `Self` type in its arguments or return type | |
68 | ||
69 | This happens when a trait has a method like the following: | |
70 | ||
3157f602 | 71 | ``` |
c1a9b12d SL |
72 | trait Trait { |
73 | fn foo(&self) -> Self; | |
74 | } | |
75 | ||
76 | impl Trait for String { | |
77 | fn foo(&self) -> Self { | |
78 | "hi".to_owned() | |
79 | } | |
80 | } | |
81 | ||
82 | impl Trait for u8 { | |
83 | fn foo(&self) -> Self { | |
84 | 1 | |
85 | } | |
86 | } | |
87 | ``` | |
88 | ||
89 | (Note that `&self` and `&mut self` are okay, it's additional `Self` types which | |
7453a54e | 90 | cause this problem.) |
c1a9b12d SL |
91 | |
92 | In such a case, the compiler cannot predict the return type of `foo()` in a | |
93 | situation like the following: | |
94 | ||
7453a54e SL |
95 | ```compile_fail |
96 | trait Trait { | |
97 | fn foo(&self) -> Self; | |
98 | } | |
99 | ||
c1a9b12d SL |
100 | fn call_foo(x: Box<Trait>) { |
101 | let y = x.foo(); // What type is y? | |
102 | // ... | |
103 | } | |
104 | ``` | |
105 | ||
106 | If only some methods aren't object-safe, you can add a `where Self: Sized` bound | |
107 | on them to mark them as explicitly unavailable to trait objects. The | |
108 | functionality will still be available to all other implementers, including | |
109 | `Box<Trait>` which is itself sized (assuming you `impl Trait for Box<Trait>`). | |
110 | ||
111 | ``` | |
112 | trait Trait { | |
113 | fn foo(&self) -> Self where Self: Sized; | |
114 | // more functions | |
115 | } | |
116 | ``` | |
117 | ||
118 | Now, `foo()` can no longer be called on a trait object, but you will now be | |
119 | allowed to make a trait object, and that will be able to call any object-safe | |
a7813a04 | 120 | methods. With such a bound, one can still call `foo()` on types implementing |
c1a9b12d SL |
121 | that trait that aren't behind trait objects. |
122 | ||
123 | ### Method has generic type parameters | |
124 | ||
125 | As mentioned before, trait objects contain pointers to method tables. So, if we | |
126 | have: | |
127 | ||
128 | ``` | |
129 | trait Trait { | |
130 | fn foo(&self); | |
131 | } | |
7453a54e | 132 | |
c1a9b12d SL |
133 | impl Trait for String { |
134 | fn foo(&self) { | |
135 | // implementation 1 | |
136 | } | |
137 | } | |
7453a54e | 138 | |
c1a9b12d SL |
139 | impl Trait for u8 { |
140 | fn foo(&self) { | |
141 | // implementation 2 | |
142 | } | |
143 | } | |
144 | // ... | |
145 | ``` | |
146 | ||
147 | At compile time each implementation of `Trait` will produce a table containing | |
148 | the various methods (and other items) related to the implementation. | |
149 | ||
150 | This works fine, but when the method gains generic parameters, we can have a | |
151 | problem. | |
152 | ||
153 | Usually, generic parameters get _monomorphized_. For example, if I have | |
154 | ||
155 | ``` | |
156 | fn foo<T>(x: T) { | |
157 | // ... | |
158 | } | |
159 | ``` | |
160 | ||
7453a54e | 161 | The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any |
c1a9b12d SL |
162 | other type substitution is different. Hence the compiler generates the |
163 | implementation on-demand. If you call `foo()` with a `bool` parameter, the | |
164 | compiler will only generate code for `foo::<bool>()`. When we have additional | |
165 | type parameters, the number of monomorphized implementations the compiler | |
166 | generates does not grow drastically, since the compiler will only generate an | |
167 | implementation if the function is called with unparametrized substitutions | |
168 | (i.e., substitutions where none of the substituted types are themselves | |
169 | parametrized). | |
170 | ||
171 | However, with trait objects we have to make a table containing _every_ object | |
172 | that implements the trait. Now, if it has type parameters, we need to add | |
173 | implementations for every type that implements the trait, and there could | |
174 | theoretically be an infinite number of types. | |
175 | ||
176 | For example, with: | |
177 | ||
178 | ``` | |
179 | trait Trait { | |
180 | fn foo<T>(&self, on: T); | |
181 | // more methods | |
182 | } | |
7453a54e | 183 | |
c1a9b12d SL |
184 | impl Trait for String { |
185 | fn foo<T>(&self, on: T) { | |
186 | // implementation 1 | |
187 | } | |
188 | } | |
7453a54e | 189 | |
c1a9b12d SL |
190 | impl Trait for u8 { |
191 | fn foo<T>(&self, on: T) { | |
192 | // implementation 2 | |
193 | } | |
194 | } | |
7453a54e | 195 | |
c1a9b12d SL |
196 | // 8 more implementations |
197 | ``` | |
198 | ||
199 | Now, if we have the following code: | |
200 | ||
7453a54e | 201 | ```ignore |
c1a9b12d SL |
202 | fn call_foo(thing: Box<Trait>) { |
203 | thing.foo(true); // this could be any one of the 8 types above | |
204 | thing.foo(1); | |
205 | thing.foo("hello"); | |
206 | } | |
207 | ``` | |
208 | ||
7453a54e | 209 | We don't just need to create a table of all implementations of all methods of |
c1a9b12d SL |
210 | `Trait`, we need to create such a table, for each different type fed to |
211 | `foo()`. In this case this turns out to be (10 types implementing `Trait`)*(3 | |
212 | types being fed to `foo()`) = 30 implementations! | |
213 | ||
214 | With real world traits these numbers can grow drastically. | |
215 | ||
216 | To fix this, it is suggested to use a `where Self: Sized` bound similar to the | |
217 | fix for the sub-error above if you do not intend to call the method with type | |
218 | parameters: | |
219 | ||
220 | ``` | |
221 | trait Trait { | |
222 | fn foo<T>(&self, on: T) where Self: Sized; | |
223 | // more methods | |
224 | } | |
225 | ``` | |
226 | ||
227 | If this is not an option, consider replacing the type parameter with another | |
228 | trait object (e.g. if `T: OtherTrait`, use `on: Box<OtherTrait>`). If the number | |
229 | of types you intend to feed to this method is limited, consider manually listing | |
230 | out the methods of different types. | |
231 | ||
232 | ### Method has no receiver | |
233 | ||
234 | Methods that do not take a `self` parameter can't be called since there won't be | |
7453a54e | 235 | a way to get a pointer to the method table for them. |
c1a9b12d SL |
236 | |
237 | ``` | |
238 | trait Foo { | |
239 | fn foo() -> u8; | |
240 | } | |
241 | ``` | |
242 | ||
243 | This could be called as `<Foo as Foo>::foo()`, which would not be able to pick | |
244 | an implementation. | |
245 | ||
246 | Adding a `Self: Sized` bound to these methods will generally make this compile. | |
247 | ||
248 | ``` | |
249 | trait Foo { | |
250 | fn foo() -> u8 where Self: Sized; | |
251 | } | |
252 | ``` | |
253 | ||
254 | ### The trait cannot use `Self` as a type parameter in the supertrait listing | |
255 | ||
256 | This is similar to the second sub-error, but subtler. It happens in situations | |
257 | like the following: | |
258 | ||
7453a54e | 259 | ```compile_fail |
c1a9b12d SL |
260 | trait Super<A> {} |
261 | ||
262 | trait Trait: Super<Self> { | |
263 | } | |
264 | ||
265 | struct Foo; | |
266 | ||
267 | impl Super<Foo> for Foo{} | |
268 | ||
269 | impl Trait for Foo {} | |
270 | ``` | |
271 | ||
272 | Here, the supertrait might have methods as follows: | |
273 | ||
274 | ``` | |
275 | trait Super<A> { | |
276 | fn get_a(&self) -> A; // note that this is object safe! | |
277 | } | |
278 | ``` | |
279 | ||
280 | If the trait `Foo` was deriving from something like `Super<String>` or | |
281 | `Super<T>` (where `Foo` itself is `Foo<T>`), this is okay, because given a type | |
282 | `get_a()` will definitely return an object of that type. | |
283 | ||
284 | However, if it derives from `Super<Self>`, even though `Super` is object safe, | |
285 | the method `get_a()` would return an object of unknown type when called on the | |
286 | function. `Self` type parameters let us make object safe traits no longer safe, | |
287 | so they are forbidden when specifying supertraits. | |
288 | ||
289 | There's no easy fix for this, generally code will need to be refactored so that | |
290 | you no longer need to derive from `Super<Self>`. | |
7453a54e SL |
291 | "##, |
292 | ||
293 | E0072: r##" | |
294 | When defining a recursive struct or enum, any use of the type being defined | |
295 | from inside the definition must occur behind a pointer (like `Box` or `&`). | |
296 | This is because structs and enums must have a well-defined size, and without | |
a7813a04 | 297 | the pointer, the size of the type would need to be unbounded. |
7453a54e SL |
298 | |
299 | Consider the following erroneous definition of a type for a list of bytes: | |
300 | ||
3157f602 | 301 | ```compile_fail,E0072 |
7453a54e SL |
302 | // error, invalid recursive struct type |
303 | struct ListNode { | |
304 | head: u8, | |
305 | tail: Option<ListNode>, | |
306 | } | |
307 | ``` | |
308 | ||
309 | This type cannot have a well-defined size, because it needs to be arbitrarily | |
310 | large (since we would be able to nest `ListNode`s to any depth). Specifically, | |
311 | ||
312 | ```plain | |
313 | size of `ListNode` = 1 byte for `head` | |
314 | + 1 byte for the discriminant of the `Option` | |
315 | + size of `ListNode` | |
316 | ``` | |
317 | ||
318 | One way to fix this is by wrapping `ListNode` in a `Box`, like so: | |
319 | ||
320 | ``` | |
321 | struct ListNode { | |
322 | head: u8, | |
323 | tail: Option<Box<ListNode>>, | |
324 | } | |
325 | ``` | |
326 | ||
327 | This works because `Box` is a pointer, so its size is well-known. | |
328 | "##, | |
c1a9b12d | 329 | |
32a655c1 SL |
330 | E0106: r##" |
331 | This error indicates that a lifetime is missing from a type. If it is an error | |
332 | inside a function signature, the problem may be with failing to adhere to the | |
333 | lifetime elision rules (see below). | |
334 | ||
335 | Here are some simple examples of where you'll run into this error: | |
336 | ||
337 | ```compile_fail,E0106 | |
338 | struct Foo { x: &bool } // error | |
339 | struct Foo<'a> { x: &'a bool } // correct | |
340 | ||
341 | enum Bar { A(u8), B(&bool), } // error | |
342 | enum Bar<'a> { A(u8), B(&'a bool), } // correct | |
343 | ||
344 | type MyStr = &str; // error | |
345 | type MyStr<'a> = &'a str; // correct | |
346 | ``` | |
347 | ||
348 | Lifetime elision is a special, limited kind of inference for lifetimes in | |
349 | function signatures which allows you to leave out lifetimes in certain cases. | |
350 | For more background on lifetime elision see [the book][book-le]. | |
351 | ||
352 | The lifetime elision rules require that any function signature with an elided | |
353 | output lifetime must either have | |
354 | ||
355 | - exactly one input lifetime | |
356 | - or, multiple input lifetimes, but the function must also be a method with a | |
357 | `&self` or `&mut self` receiver | |
358 | ||
359 | In the first case, the output lifetime is inferred to be the same as the unique | |
360 | input lifetime. In the second case, the lifetime is instead inferred to be the | |
361 | same as the lifetime on `&self` or `&mut self`. | |
362 | ||
363 | Here are some examples of elision errors: | |
364 | ||
365 | ```compile_fail,E0106 | |
366 | // error, no input lifetimes | |
367 | fn foo() -> &str { } | |
368 | ||
369 | // error, `x` and `y` have distinct lifetimes inferred | |
370 | fn bar(x: &str, y: &str) -> &str { } | |
371 | ||
372 | // error, `y`'s lifetime is inferred to be distinct from `x`'s | |
373 | fn baz<'a>(x: &'a str, y: &str) -> &str { } | |
374 | ``` | |
375 | ||
376 | Here's an example that is currently an error, but may work in a future version | |
377 | of Rust: | |
378 | ||
379 | ```compile_fail,E0106 | |
380 | struct Foo<'a>(&'a str); | |
381 | ||
382 | trait Quux { } | |
383 | impl Quux for Foo { } | |
384 | ``` | |
385 | ||
386 | Lifetime elision in implementation headers was part of the lifetime elision | |
387 | RFC. It is, however, [currently unimplemented][iss15872]. | |
388 | ||
389 | [book-le]: https://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision | |
390 | [iss15872]: https://github.com/rust-lang/rust/issues/15872 | |
391 | "##, | |
392 | ||
d9579d0f | 393 | E0133: r##" |
3157f602 XL |
394 | Unsafe code was used outside of an unsafe function or block. |
395 | ||
396 | Erroneous code example: | |
397 | ||
398 | ```compile_fail,E0133 | |
399 | unsafe fn f() { return; } // This is the unsafe code | |
400 | ||
401 | fn main() { | |
402 | f(); // error: call to unsafe function requires unsafe function or block | |
403 | } | |
404 | ``` | |
405 | ||
7453a54e SL |
406 | Using unsafe functionality is potentially dangerous and disallowed by safety |
407 | checks. Examples: | |
e9174d1e | 408 | |
7453a54e SL |
409 | * Dereferencing raw pointers |
410 | * Calling functions via FFI | |
411 | * Calling functions marked unsafe | |
e9174d1e | 412 | |
7453a54e SL |
413 | These safety checks can be relaxed for a section of the code by wrapping the |
414 | unsafe instructions with an `unsafe` block. For instance: | |
d9579d0f AL |
415 | |
416 | ``` | |
417 | unsafe fn f() { return; } | |
418 | ||
419 | fn main() { | |
3157f602 | 420 | unsafe { f(); } // ok! |
d9579d0f AL |
421 | } |
422 | ``` | |
423 | ||
c1a9b12d SL |
424 | See also https://doc.rust-lang.org/book/unsafe.html |
425 | "##, | |
426 | ||
427 | // This shouldn't really ever trigger since the repeated value error comes first | |
428 | E0136: r##" | |
429 | A binary can only have one entry point, and by default that entry point is the | |
430 | function `main()`. If there are multiple such functions, please rename one. | |
d9579d0f AL |
431 | "##, |
432 | ||
433 | E0137: r##" | |
3157f602 XL |
434 | More than one function was declared with the `#[main]` attribute. |
435 | ||
436 | Erroneous code example: | |
437 | ||
438 | ```compile_fail,E0137 | |
439 | #![feature(main)] | |
440 | ||
441 | #[main] | |
442 | fn foo() {} | |
443 | ||
444 | #[main] | |
445 | fn f() {} // error: multiple functions with a #[main] attribute | |
446 | ``` | |
447 | ||
d9579d0f AL |
448 | This error indicates that the compiler found multiple functions with the |
449 | `#[main]` attribute. This is an error because there must be a unique entry | |
3157f602 XL |
450 | point into a Rust program. Example: |
451 | ||
452 | ``` | |
453 | #![feature(main)] | |
454 | ||
455 | #[main] | |
456 | fn f() {} // ok! | |
457 | ``` | |
d9579d0f AL |
458 | "##, |
459 | ||
c1a9b12d | 460 | E0138: r##" |
3157f602 XL |
461 | More than one function was declared with the `#[start]` attribute. |
462 | ||
463 | Erroneous code example: | |
464 | ||
465 | ```compile_fail,E0138 | |
466 | #![feature(start)] | |
467 | ||
468 | #[start] | |
469 | fn foo(argc: isize, argv: *const *const u8) -> isize {} | |
470 | ||
471 | #[start] | |
472 | fn f(argc: isize, argv: *const *const u8) -> isize {} | |
473 | // error: multiple 'start' functions | |
474 | ``` | |
475 | ||
c1a9b12d SL |
476 | This error indicates that the compiler found multiple functions with the |
477 | `#[start]` attribute. This is an error because there must be a unique entry | |
3157f602 XL |
478 | point into a Rust program. Example: |
479 | ||
480 | ``` | |
481 | #![feature(start)] | |
482 | ||
483 | #[start] | |
484 | fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok! | |
485 | ``` | |
c1a9b12d SL |
486 | "##, |
487 | ||
3157f602 | 488 | // isn't thrown anymore |
c1a9b12d SL |
489 | E0139: r##" |
490 | There are various restrictions on transmuting between types in Rust; for example | |
491 | types being transmuted must have the same size. To apply all these restrictions, | |
492 | the compiler must know the exact types that may be transmuted. When type | |
493 | parameters are involved, this cannot always be done. | |
494 | ||
495 | So, for example, the following is not allowed: | |
496 | ||
3157f602 XL |
497 | ``` |
498 | use std::mem::transmute; | |
499 | ||
7453a54e | 500 | struct Foo<T>(Vec<T>); |
c1a9b12d SL |
501 | |
502 | fn foo<T>(x: Vec<T>) { | |
3157f602 | 503 | // we are transmuting between Vec<T> and Foo<F> here |
c1a9b12d SL |
504 | let y: Foo<T> = unsafe { transmute(x) }; |
505 | // do something with y | |
506 | } | |
507 | ``` | |
508 | ||
509 | In this specific case there's a good chance that the transmute is harmless (but | |
510 | this is not guaranteed by Rust). However, when alignment and enum optimizations | |
511 | come into the picture, it's quite likely that the sizes may or may not match | |
512 | with different type parameter substitutions. It's not possible to check this for | |
513 | _all_ possible types, so `transmute()` simply only accepts types without any | |
514 | unsubstituted type parameters. | |
515 | ||
516 | If you need this, there's a good chance you're doing something wrong. Keep in | |
517 | mind that Rust doesn't guarantee much about the layout of different structs | |
518 | (even two structs with identical declarations may have different layouts). If | |
519 | there is a solution that avoids the transmute entirely, try it instead. | |
520 | ||
521 | If it's possible, hand-monomorphize the code by writing the function for each | |
522 | possible type substitution. It's possible to use traits to do this cleanly, | |
523 | for example: | |
524 | ||
7453a54e SL |
525 | ```ignore |
526 | struct Foo<T>(Vec<T>); | |
527 | ||
c1a9b12d | 528 | trait MyTransmutableType { |
7453a54e | 529 | fn transmute(Vec<Self>) -> Foo<Self>; |
c1a9b12d SL |
530 | } |
531 | ||
532 | impl MyTransmutableType for u8 { | |
533 | fn transmute(x: Foo<u8>) -> Vec<u8> { | |
534 | transmute(x) | |
535 | } | |
536 | } | |
7453a54e | 537 | |
c1a9b12d SL |
538 | impl MyTransmutableType for String { |
539 | fn transmute(x: Foo<String>) -> Vec<String> { | |
540 | transmute(x) | |
541 | } | |
542 | } | |
7453a54e | 543 | |
c1a9b12d SL |
544 | // ... more impls for the types you intend to transmute |
545 | ||
546 | fn foo<T: MyTransmutableType>(x: Vec<T>) { | |
547 | let y: Foo<T> = <T as MyTransmutableType>::transmute(x); | |
548 | // do something with y | |
549 | } | |
550 | ``` | |
551 | ||
552 | Each impl will be checked for a size match in the transmute as usual, and since | |
553 | there are no unbound type parameters involved, this should compile unless there | |
554 | is a size mismatch in one of the impls. | |
555 | ||
556 | It is also possible to manually transmute: | |
557 | ||
7453a54e | 558 | ```ignore |
e9174d1e | 559 | ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType` |
c1a9b12d | 560 | ``` |
92a42be0 SL |
561 | |
562 | Note that this does not move `v` (unlike `transmute`), and may need a | |
563 | call to `mem::forget(v)` in case you want to avoid destructors being called. | |
c1a9b12d SL |
564 | "##, |
565 | ||
d9579d0f | 566 | E0152: r##" |
3157f602 XL |
567 | A lang item was redefined. |
568 | ||
569 | Erroneous code example: | |
570 | ||
571 | ```compile_fail,E0152 | |
572 | #![feature(lang_items)] | |
573 | ||
574 | #[lang = "panic_fmt"] | |
575 | struct Foo; // error: duplicate lang item found: `panic_fmt` | |
576 | ``` | |
577 | ||
d9579d0f AL |
578 | Lang items are already implemented in the standard library. Unless you are |
579 | writing a free-standing application (e.g. a kernel), you do not need to provide | |
580 | them yourself. | |
581 | ||
582 | You can build a free-standing crate by adding `#![no_std]` to the crate | |
583 | attributes: | |
584 | ||
8bb4bdeb | 585 | ```ignore |
d9579d0f AL |
586 | #![no_std] |
587 | ``` | |
588 | ||
589 | See also https://doc.rust-lang.org/book/no-stdlib.html | |
590 | "##, | |
591 | ||
62682a34 SL |
592 | E0261: r##" |
593 | When using a lifetime like `'a` in a type, it must be declared before being | |
594 | used. | |
595 | ||
596 | These two examples illustrate the problem: | |
597 | ||
3157f602 | 598 | ```compile_fail,E0261 |
62682a34 SL |
599 | // error, use of undeclared lifetime name `'a` |
600 | fn foo(x: &'a str) { } | |
601 | ||
602 | struct Foo { | |
603 | // error, use of undeclared lifetime name `'a` | |
604 | x: &'a str, | |
605 | } | |
606 | ``` | |
607 | ||
608 | These can be fixed by declaring lifetime parameters: | |
609 | ||
610 | ``` | |
7453a54e | 611 | fn foo<'a>(x: &'a str) {} |
62682a34 SL |
612 | |
613 | struct Foo<'a> { | |
614 | x: &'a str, | |
615 | } | |
616 | ``` | |
617 | "##, | |
618 | ||
619 | E0262: r##" | |
620 | Declaring certain lifetime names in parameters is disallowed. For example, | |
621 | because the `'static` lifetime is a special built-in lifetime name denoting | |
622 | the lifetime of the entire program, this is an error: | |
623 | ||
3157f602 | 624 | ```compile_fail,E0262 |
c1a9b12d | 625 | // error, invalid lifetime parameter name `'static` |
62682a34 SL |
626 | fn foo<'static>(x: &'static str) { } |
627 | ``` | |
628 | "##, | |
629 | ||
630 | E0263: r##" | |
631 | A lifetime name cannot be declared more than once in the same scope. For | |
632 | example: | |
633 | ||
3157f602 | 634 | ```compile_fail,E0263 |
62682a34 SL |
635 | // error, lifetime name `'a` declared twice in the same scope |
636 | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } | |
637 | ``` | |
638 | "##, | |
639 | ||
92a42be0 SL |
640 | E0264: r##" |
641 | An unknown external lang item was used. Erroneous code example: | |
642 | ||
3157f602 | 643 | ```compile_fail,E0264 |
92a42be0 SL |
644 | #![feature(lang_items)] |
645 | ||
646 | extern "C" { | |
647 | #[lang = "cake"] // error: unknown external lang item: `cake` | |
648 | fn cake(); | |
649 | } | |
650 | ``` | |
651 | ||
652 | A list of available external lang items is available in | |
653 | `src/librustc/middle/weak_lang_items.rs`. Example: | |
654 | ||
655 | ``` | |
656 | #![feature(lang_items)] | |
657 | ||
658 | extern "C" { | |
659 | #[lang = "panic_fmt"] // ok! | |
660 | fn cake(); | |
661 | } | |
662 | ``` | |
663 | "##, | |
664 | ||
d9579d0f AL |
665 | E0271: r##" |
666 | This is because of a type mismatch between the associated type of some | |
667 | trait (e.g. `T::Bar`, where `T` implements `trait Quux { type Bar; }`) | |
668 | and another type `U` that is required to be equal to `T::Bar`, but is not. | |
669 | Examples follow. | |
670 | ||
671 | Here is a basic example: | |
672 | ||
3157f602 | 673 | ```compile_fail,E0271 |
d9579d0f | 674 | trait Trait { type AssociatedType; } |
7453a54e | 675 | |
d9579d0f AL |
676 | fn foo<T>(t: T) where T: Trait<AssociatedType=u32> { |
677 | println!("in foo"); | |
678 | } | |
7453a54e | 679 | |
d9579d0f | 680 | impl Trait for i8 { type AssociatedType = &'static str; } |
7453a54e | 681 | |
d9579d0f AL |
682 | foo(3_i8); |
683 | ``` | |
684 | ||
685 | Here is that same example again, with some explanatory comments: | |
686 | ||
7453a54e | 687 | ```ignore |
d9579d0f AL |
688 | trait Trait { type AssociatedType; } |
689 | ||
690 | fn foo<T>(t: T) where T: Trait<AssociatedType=u32> { | |
691 | // ~~~~~~~~ ~~~~~~~~~~~~~~~~~~ | |
692 | // | | | |
693 | // This says `foo` can | | |
694 | // only be used with | | |
695 | // some type that | | |
696 | // implements `Trait`. | | |
697 | // | | |
698 | // This says not only must | |
699 | // `T` be an impl of `Trait` | |
700 | // but also that the impl | |
701 | // must assign the type `u32` | |
702 | // to the associated type. | |
703 | println!("in foo"); | |
704 | } | |
705 | ||
706 | impl Trait for i8 { type AssociatedType = &'static str; } | |
707 | ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
708 | // | | | |
709 | // `i8` does have | | |
710 | // implementation | | |
711 | // of `Trait`... | | |
712 | // ... but it is an implementation | |
713 | // that assigns `&'static str` to | |
714 | // the associated type. | |
715 | ||
716 | foo(3_i8); | |
717 | // Here, we invoke `foo` with an `i8`, which does not satisfy | |
62682a34 | 718 | // the constraint `<i8 as Trait>::AssociatedType=u32`, and |
d9579d0f AL |
719 | // therefore the type-checker complains with this error code. |
720 | ``` | |
721 | ||
722 | Here is a more subtle instance of the same problem, that can | |
723 | arise with for-loops in Rust: | |
724 | ||
7453a54e | 725 | ```compile_fail |
d9579d0f AL |
726 | let vs: Vec<i32> = vec![1, 2, 3, 4]; |
727 | for v in &vs { | |
728 | match v { | |
7453a54e SL |
729 | 1 => {}, |
730 | _ => {}, | |
d9579d0f AL |
731 | } |
732 | } | |
733 | ``` | |
734 | ||
735 | The above fails because of an analogous type mismatch, | |
736 | though may be harder to see. Again, here are some | |
737 | explanatory comments for the same example: | |
738 | ||
7453a54e | 739 | ```ignore |
d9579d0f AL |
740 | { |
741 | let vs = vec![1, 2, 3, 4]; | |
742 | ||
743 | // `for`-loops use a protocol based on the `Iterator` | |
744 | // trait. Each item yielded in a `for` loop has the | |
9cc50fc6 | 745 | // type `Iterator::Item` -- that is, `Item` is the |
d9579d0f AL |
746 | // associated type of the concrete iterator impl. |
747 | for v in &vs { | |
748 | // ~ ~~~ | |
749 | // | | | |
750 | // | We borrow `vs`, iterating over a sequence of | |
751 | // | *references* of type `&Elem` (where `Elem` is | |
752 | // | vector's element type). Thus, the associated | |
753 | // | type `Item` must be a reference `&`-type ... | |
754 | // | | |
755 | // ... and `v` has the type `Iterator::Item`, as dictated by | |
756 | // the `for`-loop protocol ... | |
757 | ||
758 | match v { | |
759 | 1 => {} | |
760 | // ~ | |
761 | // | | |
762 | // ... but *here*, `v` is forced to have some integral type; | |
763 | // only types like `u8`,`i8`,`u16`,`i16`, et cetera can | |
764 | // match the pattern `1` ... | |
765 | ||
766 | _ => {} | |
767 | } | |
768 | ||
769 | // ... therefore, the compiler complains, because it sees | |
770 | // an attempt to solve the equations | |
771 | // `some integral-type` = type-of-`v` | |
772 | // = `Iterator::Item` | |
773 | // = `&Elem` (i.e. `some reference type`) | |
774 | // | |
775 | // which cannot possibly all be true. | |
776 | ||
777 | } | |
778 | } | |
779 | ``` | |
780 | ||
781 | To avoid those issues, you have to make the types match correctly. | |
782 | So we can fix the previous examples like this: | |
783 | ||
784 | ``` | |
785 | // Basic Example: | |
786 | trait Trait { type AssociatedType; } | |
7453a54e | 787 | |
d9579d0f AL |
788 | fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> { |
789 | println!("in foo"); | |
790 | } | |
7453a54e | 791 | |
d9579d0f | 792 | impl Trait for i8 { type AssociatedType = &'static str; } |
7453a54e | 793 | |
d9579d0f AL |
794 | foo(3_i8); |
795 | ||
796 | // For-Loop Example: | |
797 | let vs = vec![1, 2, 3, 4]; | |
798 | for v in &vs { | |
799 | match v { | |
800 | &1 => {} | |
801 | _ => {} | |
802 | } | |
803 | } | |
804 | ``` | |
805 | "##, | |
806 | ||
c1a9b12d SL |
807 | E0272: r##" |
808 | The `#[rustc_on_unimplemented]` attribute lets you specify a custom error | |
809 | message for when a particular trait isn't implemented on a type placed in a | |
810 | position that needs that trait. For example, when the following code is | |
811 | compiled: | |
812 | ||
7453a54e | 813 | ```compile_fail |
3157f602 XL |
814 | #![feature(on_unimplemented)] |
815 | ||
c1a9b12d SL |
816 | fn foo<T: Index<u8>>(x: T){} |
817 | ||
818 | #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] | |
54a0048b | 819 | trait Index<Idx> { /* ... */ } |
c1a9b12d SL |
820 | |
821 | foo(true); // `bool` does not implement `Index<u8>` | |
822 | ``` | |
823 | ||
7453a54e | 824 | There will be an error about `bool` not implementing `Index<u8>`, followed by a |
c1a9b12d SL |
825 | note saying "the type `bool` cannot be indexed by `u8`". |
826 | ||
7453a54e SL |
827 | As you can see, you can specify type parameters in curly braces for |
828 | substitution with the actual types (using the regular format string syntax) in | |
829 | a given situation. Furthermore, `{Self}` will substitute to the type (in this | |
830 | case, `bool`) that we tried to use. | |
c1a9b12d SL |
831 | |
832 | This error appears when the curly braces contain an identifier which doesn't | |
7453a54e SL |
833 | match with any of the type parameters or the string `Self`. This might happen |
834 | if you misspelled a type parameter, or if you intended to use literal curly | |
835 | braces. If it is the latter, escape the curly braces with a second curly brace | |
836 | of the same type; e.g. a literal `{` is `{{`. | |
c1a9b12d SL |
837 | "##, |
838 | ||
839 | E0273: r##" | |
840 | The `#[rustc_on_unimplemented]` attribute lets you specify a custom error | |
841 | message for when a particular trait isn't implemented on a type placed in a | |
842 | position that needs that trait. For example, when the following code is | |
843 | compiled: | |
844 | ||
7453a54e | 845 | ```compile_fail |
3157f602 XL |
846 | #![feature(on_unimplemented)] |
847 | ||
c1a9b12d SL |
848 | fn foo<T: Index<u8>>(x: T){} |
849 | ||
850 | #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] | |
54a0048b | 851 | trait Index<Idx> { /* ... */ } |
c1a9b12d SL |
852 | |
853 | foo(true); // `bool` does not implement `Index<u8>` | |
854 | ``` | |
855 | ||
856 | there will be an error about `bool` not implementing `Index<u8>`, followed by a | |
857 | note saying "the type `bool` cannot be indexed by `u8`". | |
858 | ||
7453a54e SL |
859 | As you can see, you can specify type parameters in curly braces for |
860 | substitution with the actual types (using the regular format string syntax) in | |
861 | a given situation. Furthermore, `{Self}` will substitute to the type (in this | |
862 | case, `bool`) that we tried to use. | |
c1a9b12d SL |
863 | |
864 | This error appears when the curly braces do not contain an identifier. Please | |
865 | add one of the same name as a type parameter. If you intended to use literal | |
866 | braces, use `{{` and `}}` to escape them. | |
867 | "##, | |
868 | ||
869 | E0274: r##" | |
870 | The `#[rustc_on_unimplemented]` attribute lets you specify a custom error | |
871 | message for when a particular trait isn't implemented on a type placed in a | |
872 | position that needs that trait. For example, when the following code is | |
873 | compiled: | |
874 | ||
7453a54e | 875 | ```compile_fail |
3157f602 XL |
876 | #![feature(on_unimplemented)] |
877 | ||
c1a9b12d SL |
878 | fn foo<T: Index<u8>>(x: T){} |
879 | ||
880 | #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] | |
54a0048b | 881 | trait Index<Idx> { /* ... */ } |
c1a9b12d SL |
882 | |
883 | foo(true); // `bool` does not implement `Index<u8>` | |
884 | ``` | |
885 | ||
886 | there will be an error about `bool` not implementing `Index<u8>`, followed by a | |
887 | note saying "the type `bool` cannot be indexed by `u8`". | |
888 | ||
889 | For this to work, some note must be specified. An empty attribute will not do | |
890 | anything, please remove the attribute or add some helpful note for users of the | |
891 | trait. | |
892 | "##, | |
893 | ||
894 | E0275: r##" | |
895 | This error occurs when there was a recursive trait requirement that overflowed | |
7453a54e SL |
896 | before it could be evaluated. Often this means that there is unbounded |
897 | recursion in resolving some type bounds. | |
c1a9b12d | 898 | |
7453a54e | 899 | For example, in the following code: |
c1a9b12d | 900 | |
3157f602 | 901 | ```compile_fail,E0275 |
c1a9b12d SL |
902 | trait Foo {} |
903 | ||
904 | struct Bar<T>(T); | |
905 | ||
906 | impl<T> Foo for T where Bar<T>: Foo {} | |
907 | ``` | |
908 | ||
7453a54e SL |
909 | To determine if a `T` is `Foo`, we need to check if `Bar<T>` is `Foo`. However, |
910 | to do this check, we need to determine that `Bar<Bar<T>>` is `Foo`. To | |
911 | determine this, we check if `Bar<Bar<Bar<T>>>` is `Foo`, and so on. This is | |
912 | clearly a recursive requirement that can't be resolved directly. | |
c1a9b12d SL |
913 | |
914 | Consider changing your trait bounds so that they're less self-referential. | |
915 | "##, | |
916 | ||
917 | E0276: r##" | |
918 | This error occurs when a bound in an implementation of a trait does not match | |
919 | the bounds specified in the original trait. For example: | |
920 | ||
3157f602 | 921 | ```compile_fail,E0276 |
c1a9b12d | 922 | trait Foo { |
7453a54e | 923 | fn foo<T>(x: T); |
c1a9b12d SL |
924 | } |
925 | ||
926 | impl Foo for bool { | |
7453a54e | 927 | fn foo<T>(x: T) where T: Copy {} |
c1a9b12d SL |
928 | } |
929 | ``` | |
930 | ||
931 | Here, all types implementing `Foo` must have a method `foo<T>(x: T)` which can | |
932 | take any type `T`. However, in the `impl` for `bool`, we have added an extra | |
933 | bound that `T` is `Copy`, which isn't compatible with the original trait. | |
934 | ||
935 | Consider removing the bound from the method or adding the bound to the original | |
936 | method definition in the trait. | |
937 | "##, | |
938 | ||
939 | E0277: r##" | |
940 | You tried to use a type which doesn't implement some trait in a place which | |
941 | expected that trait. Erroneous code example: | |
942 | ||
3157f602 | 943 | ```compile_fail,E0277 |
c1a9b12d SL |
944 | // here we declare the Foo trait with a bar method |
945 | trait Foo { | |
946 | fn bar(&self); | |
947 | } | |
948 | ||
949 | // we now declare a function which takes an object implementing the Foo trait | |
950 | fn some_func<T: Foo>(foo: T) { | |
951 | foo.bar(); | |
952 | } | |
953 | ||
954 | fn main() { | |
955 | // we now call the method with the i32 type, which doesn't implement | |
956 | // the Foo trait | |
54a0048b | 957 | some_func(5i32); // error: the trait bound `i32 : Foo` is not satisfied |
c1a9b12d SL |
958 | } |
959 | ``` | |
960 | ||
961 | In order to fix this error, verify that the type you're using does implement | |
962 | the trait. Example: | |
963 | ||
964 | ``` | |
965 | trait Foo { | |
966 | fn bar(&self); | |
967 | } | |
968 | ||
969 | fn some_func<T: Foo>(foo: T) { | |
970 | foo.bar(); // we can now use this method since i32 implements the | |
971 | // Foo trait | |
972 | } | |
973 | ||
974 | // we implement the trait on the i32 type | |
975 | impl Foo for i32 { | |
976 | fn bar(&self) {} | |
977 | } | |
978 | ||
979 | fn main() { | |
980 | some_func(5i32); // ok! | |
981 | } | |
982 | ``` | |
54a0048b SL |
983 | |
984 | Or in a generic context, an erroneous code example would look like: | |
3157f602 XL |
985 | |
986 | ```compile_fail,E0277 | |
54a0048b SL |
987 | fn some_func<T>(foo: T) { |
988 | println!("{:?}", foo); // error: the trait `core::fmt::Debug` is not | |
989 | // implemented for the type `T` | |
990 | } | |
991 | ||
992 | fn main() { | |
993 | // We now call the method with the i32 type, | |
994 | // which *does* implement the Debug trait. | |
995 | some_func(5i32); | |
996 | } | |
997 | ``` | |
998 | ||
999 | Note that the error here is in the definition of the generic function: Although | |
1000 | we only call it with a parameter that does implement `Debug`, the compiler | |
1001 | still rejects the function: It must work with all possible input types. In | |
1002 | order to make this example compile, we need to restrict the generic type we're | |
1003 | accepting: | |
3157f602 | 1004 | |
54a0048b SL |
1005 | ``` |
1006 | use std::fmt; | |
1007 | ||
1008 | // Restrict the input type to types that implement Debug. | |
1009 | fn some_func<T: fmt::Debug>(foo: T) { | |
1010 | println!("{:?}", foo); | |
1011 | } | |
1012 | ||
1013 | fn main() { | |
1014 | // Calling the method is still fine, as i32 implements Debug. | |
1015 | some_func(5i32); | |
1016 | ||
1017 | // This would fail to compile now: | |
1018 | // struct WithoutDebug; | |
1019 | // some_func(WithoutDebug); | |
1020 | } | |
3157f602 | 1021 | ``` |
54a0048b SL |
1022 | |
1023 | Rust only looks at the signature of the called function, as such it must | |
1024 | already specify all requirements that will be used for every type parameter. | |
c1a9b12d SL |
1025 | "##, |
1026 | ||
e9174d1e SL |
1027 | E0281: r##" |
1028 | You tried to supply a type which doesn't implement some trait in a location | |
1029 | which expected that trait. This error typically occurs when working with | |
1030 | `Fn`-based types. Erroneous code example: | |
1031 | ||
3157f602 | 1032 | ```compile_fail,E0281 |
e9174d1e SL |
1033 | fn foo<F: Fn()>(x: F) { } |
1034 | ||
1035 | fn main() { | |
1036 | // type mismatch: the type ... implements the trait `core::ops::Fn<(_,)>`, | |
1037 | // but the trait `core::ops::Fn<()>` is required (expected (), found tuple | |
1038 | // [E0281] | |
1039 | foo(|y| { }); | |
1040 | } | |
1041 | ``` | |
1042 | ||
1043 | The issue in this case is that `foo` is defined as accepting a `Fn` with no | |
1044 | arguments, but the closure we attempted to pass to it requires one argument. | |
1045 | "##, | |
1046 | ||
d9579d0f AL |
1047 | E0282: r##" |
1048 | This error indicates that type inference did not result in one unique possible | |
1049 | type, and extra information is required. In most cases this can be provided | |
1050 | by adding a type annotation. Sometimes you need to specify a generic type | |
1051 | parameter manually. | |
1052 | ||
1053 | A common example is the `collect` method on `Iterator`. It has a generic type | |
1054 | parameter with a `FromIterator` bound, which for a `char` iterator is | |
1055 | implemented by `Vec` and `String` among others. Consider the following snippet | |
1056 | that reverses the characters of a string: | |
1057 | ||
3157f602 | 1058 | ```compile_fail,E0282 |
d9579d0f AL |
1059 | let x = "hello".chars().rev().collect(); |
1060 | ``` | |
1061 | ||
1062 | In this case, the compiler cannot infer what the type of `x` should be: | |
1063 | `Vec<char>` and `String` are both suitable candidates. To specify which type to | |
1064 | use, you can use a type annotation on `x`: | |
1065 | ||
1066 | ``` | |
1067 | let x: Vec<char> = "hello".chars().rev().collect(); | |
1068 | ``` | |
1069 | ||
1070 | It is not necessary to annotate the full type. Once the ambiguity is resolved, | |
1071 | the compiler can infer the rest: | |
1072 | ||
1073 | ``` | |
1074 | let x: Vec<_> = "hello".chars().rev().collect(); | |
1075 | ``` | |
1076 | ||
1077 | Another way to provide the compiler with enough information, is to specify the | |
1078 | generic type parameter: | |
1079 | ||
1080 | ``` | |
1081 | let x = "hello".chars().rev().collect::<Vec<char>>(); | |
1082 | ``` | |
1083 | ||
1084 | Again, you need not specify the full type if the compiler can infer it: | |
1085 | ||
1086 | ``` | |
1087 | let x = "hello".chars().rev().collect::<Vec<_>>(); | |
1088 | ``` | |
1089 | ||
1090 | Apart from a method or function with a generic type parameter, this error can | |
1091 | occur when a type parameter of a struct or trait cannot be inferred. In that | |
1092 | case it is not always possible to use a type annotation, because all candidates | |
1093 | have the same return type. For instance: | |
1094 | ||
3157f602 | 1095 | ```compile_fail,E0282 |
d9579d0f | 1096 | struct Foo<T> { |
7453a54e | 1097 | num: T, |
d9579d0f AL |
1098 | } |
1099 | ||
1100 | impl<T> Foo<T> { | |
1101 | fn bar() -> i32 { | |
1102 | 0 | |
1103 | } | |
1104 | ||
1105 | fn baz() { | |
1106 | let number = Foo::bar(); | |
1107 | } | |
1108 | } | |
1109 | ``` | |
1110 | ||
1111 | This will fail because the compiler does not know which instance of `Foo` to | |
1112 | call `bar` on. Change `Foo::bar()` to `Foo::<T>::bar()` to resolve the error. | |
1113 | "##, | |
1114 | ||
9cc50fc6 SL |
1115 | E0283: r##" |
1116 | This error occurs when the compiler doesn't have enough information | |
1117 | to unambiguously choose an implementation. | |
1118 | ||
1119 | For example: | |
1120 | ||
3157f602 | 1121 | ```compile_fail,E0283 |
9cc50fc6 SL |
1122 | trait Generator { |
1123 | fn create() -> u32; | |
1124 | } | |
1125 | ||
1126 | struct Impl; | |
7453a54e | 1127 | |
9cc50fc6 SL |
1128 | impl Generator for Impl { |
1129 | fn create() -> u32 { 1 } | |
1130 | } | |
1131 | ||
1132 | struct AnotherImpl; | |
7453a54e | 1133 | |
9cc50fc6 SL |
1134 | impl Generator for AnotherImpl { |
1135 | fn create() -> u32 { 2 } | |
1136 | } | |
1137 | ||
1138 | fn main() { | |
1139 | let cont: u32 = Generator::create(); | |
1140 | // error, impossible to choose one of Generator trait implementation | |
1141 | // Impl or AnotherImpl? Maybe anything else? | |
1142 | } | |
1143 | ``` | |
1144 | ||
1145 | To resolve this error use the concrete type: | |
1146 | ||
1147 | ``` | |
7453a54e SL |
1148 | trait Generator { |
1149 | fn create() -> u32; | |
1150 | } | |
1151 | ||
1152 | struct AnotherImpl; | |
1153 | ||
1154 | impl Generator for AnotherImpl { | |
1155 | fn create() -> u32 { 2 } | |
1156 | } | |
1157 | ||
9cc50fc6 SL |
1158 | fn main() { |
1159 | let gen1 = AnotherImpl::create(); | |
1160 | ||
1161 | // if there are multiple methods with same name (different traits) | |
1162 | let gen2 = <AnotherImpl as Generator>::create(); | |
1163 | } | |
1164 | ``` | |
1165 | "##, | |
1166 | ||
d9579d0f AL |
1167 | E0296: r##" |
1168 | This error indicates that the given recursion limit could not be parsed. Ensure | |
3157f602 XL |
1169 | that the value provided is a positive integer between quotes. |
1170 | ||
1171 | Erroneous code example: | |
1172 | ||
1173 | ```compile_fail,E0296 | |
1174 | #![recursion_limit] | |
1175 | ||
1176 | fn main() {} | |
1177 | ``` | |
1178 | ||
1179 | And a working example: | |
d9579d0f AL |
1180 | |
1181 | ``` | |
1182 | #![recursion_limit="1000"] | |
3157f602 XL |
1183 | |
1184 | fn main() {} | |
d9579d0f | 1185 | ``` |
85aaf69f SL |
1186 | "##, |
1187 | ||
d9579d0f AL |
1188 | E0308: r##" |
1189 | This error occurs when the compiler was unable to infer the concrete type of a | |
c1a9b12d | 1190 | variable. It can occur for several cases, the most common of which is a |
d9579d0f AL |
1191 | mismatch in the expected type that the compiler inferred for a variable's |
1192 | initializing expression, and the actual type explicitly assigned to the | |
1193 | variable. | |
1194 | ||
1195 | For example: | |
1196 | ||
3157f602 | 1197 | ```compile_fail,E0308 |
d9579d0f AL |
1198 | let x: i32 = "I am not a number!"; |
1199 | // ~~~ ~~~~~~~~~~~~~~~~~~~~ | |
1200 | // | | | |
1201 | // | initializing expression; | |
1202 | // | compiler infers type `&str` | |
1203 | // | | |
1204 | // type `i32` assigned to variable `x` | |
1205 | ``` | |
1206 | "##, | |
1207 | ||
1208 | E0309: r##" | |
1209 | Types in type definitions have lifetimes associated with them that represent | |
1210 | how long the data stored within them is guaranteed to be live. This lifetime | |
1211 | must be as long as the data needs to be alive, and missing the constraint that | |
1212 | denotes this will cause this error. | |
1213 | ||
3157f602 | 1214 | ```compile_fail,E0309 |
d9579d0f AL |
1215 | // This won't compile because T is not constrained, meaning the data |
1216 | // stored in it is not guaranteed to last as long as the reference | |
1217 | struct Foo<'a, T> { | |
1218 | foo: &'a T | |
1219 | } | |
7453a54e | 1220 | ``` |
d9579d0f | 1221 | |
7453a54e SL |
1222 | This will compile, because it has the constraint on the type parameter: |
1223 | ||
1224 | ``` | |
d9579d0f AL |
1225 | struct Foo<'a, T: 'a> { |
1226 | foo: &'a T | |
1227 | } | |
1228 | ``` | |
32a655c1 SL |
1229 | |
1230 | To see why this is important, consider the case where `T` is itself a reference | |
1231 | (e.g., `T = &str`). If we don't include the restriction that `T: 'a`, the | |
1232 | following code would be perfectly legal: | |
1233 | ||
1234 | ```compile_fail,E0309 | |
1235 | struct Foo<'a, T> { | |
1236 | foo: &'a T | |
1237 | } | |
1238 | ||
1239 | fn main() { | |
1240 | let v = "42".to_string(); | |
1241 | let f = Foo{foo: &v}; | |
1242 | drop(v); | |
1243 | println!("{}", f.foo); // but we've already dropped v! | |
1244 | } | |
1245 | ``` | |
d9579d0f AL |
1246 | "##, |
1247 | ||
1248 | E0310: r##" | |
1249 | Types in type definitions have lifetimes associated with them that represent | |
1250 | how long the data stored within them is guaranteed to be live. This lifetime | |
1251 | must be as long as the data needs to be alive, and missing the constraint that | |
1252 | denotes this will cause this error. | |
1253 | ||
3157f602 | 1254 | ```compile_fail,E0310 |
d9579d0f AL |
1255 | // This won't compile because T is not constrained to the static lifetime |
1256 | // the reference needs | |
1257 | struct Foo<T> { | |
1258 | foo: &'static T | |
1259 | } | |
3157f602 | 1260 | ``` |
d9579d0f | 1261 | |
7453a54e | 1262 | This will compile, because it has the constraint on the type parameter: |
62682a34 SL |
1263 | |
1264 | ``` | |
7453a54e SL |
1265 | struct Foo<T: 'static> { |
1266 | foo: &'static T | |
62682a34 SL |
1267 | } |
1268 | ``` | |
62682a34 SL |
1269 | "##, |
1270 | ||
5bcae85e SL |
1271 | E0312: r##" |
1272 | A lifetime of reference outlives lifetime of borrowed content. | |
1273 | ||
1274 | Erroneous code example: | |
1275 | ||
1276 | ```compile_fail,E0312 | |
1277 | fn make_child<'human, 'elve>(x: &mut &'human isize, y: &mut &'elve isize) { | |
1278 | *x = *y; | |
1279 | // error: lifetime of reference outlives lifetime of borrowed content | |
1280 | } | |
1281 | ``` | |
1282 | ||
1283 | The compiler cannot determine if the `human` lifetime will live long enough | |
1284 | to keep up on the elve one. To solve this error, you have to give an | |
1285 | explicit lifetime hierarchy: | |
1286 | ||
1287 | ``` | |
1288 | fn make_child<'human, 'elve: 'human>(x: &mut &'human isize, | |
1289 | y: &mut &'elve isize) { | |
1290 | *x = *y; // ok! | |
1291 | } | |
1292 | ``` | |
1293 | ||
1294 | Or use the same lifetime for every variable: | |
1295 | ||
1296 | ``` | |
1297 | fn make_child<'elve>(x: &mut &'elve isize, y: &mut &'elve isize) { | |
1298 | *x = *y; // ok! | |
1299 | } | |
1300 | ``` | |
1301 | "##, | |
1302 | ||
c30ab7b3 SL |
1303 | E0317: r##" |
1304 | This error occurs when an `if` expression without an `else` block is used in a | |
1305 | context where a type other than `()` is expected, for example a `let` | |
1306 | expression: | |
1307 | ||
1308 | ```compile_fail,E0317 | |
1309 | fn main() { | |
1310 | let x = 5; | |
1311 | let a = if x == 5 { 1 }; | |
1312 | } | |
1313 | ``` | |
1314 | ||
1315 | An `if` expression without an `else` block has the type `()`, so this is a type | |
1316 | error. To resolve it, add an `else` block having the same type as the `if` | |
1317 | block. | |
1318 | "##, | |
1319 | ||
8bb4bdeb XL |
1320 | E0391: r##" |
1321 | This error indicates that some types or traits depend on each other | |
1322 | and therefore cannot be constructed. | |
1323 | ||
1324 | The following example contains a circular dependency between two traits: | |
1325 | ||
1326 | ```compile_fail,E0391 | |
1327 | trait FirstTrait : SecondTrait { | |
1328 | ||
1329 | } | |
1330 | ||
1331 | trait SecondTrait : FirstTrait { | |
1332 | ||
1333 | } | |
1334 | ``` | |
1335 | "##, | |
1336 | ||
62682a34 | 1337 | E0398: r##" |
7453a54e SL |
1338 | In Rust 1.3, the default object lifetime bounds are expected to change, as |
1339 | described in RFC #1156 [1]. You are getting a warning because the compiler | |
1340 | thinks it is possible that this change will cause a compilation error in your | |
1341 | code. It is possible, though unlikely, that this is a false alarm. | |
1342 | ||
1343 | The heart of the change is that where `&'a Box<SomeTrait>` used to default to | |
1344 | `&'a Box<SomeTrait+'a>`, it now defaults to `&'a Box<SomeTrait+'static>` (here, | |
1345 | `SomeTrait` is the name of some trait type). Note that the only types which are | |
1346 | affected are references to boxes, like `&Box<SomeTrait>` or | |
1347 | `&[Box<SomeTrait>]`. More common types like `&SomeTrait` or `Box<SomeTrait>` | |
1348 | are unaffected. | |
1349 | ||
1350 | To silence this warning, edit your code to use an explicit bound. Most of the | |
1351 | time, this means that you will want to change the signature of a function that | |
1352 | you are calling. For example, if the error is reported on a call like `foo(x)`, | |
1353 | and `foo` is defined as follows: | |
1354 | ||
1355 | ```ignore | |
62682a34 SL |
1356 | fn foo(arg: &Box<SomeTrait>) { ... } |
1357 | ``` | |
1358 | ||
7453a54e | 1359 | You might change it to: |
62682a34 | 1360 | |
7453a54e | 1361 | ```ignore |
62682a34 SL |
1362 | fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... } |
1363 | ``` | |
1364 | ||
7453a54e SL |
1365 | This explicitly states that you expect the trait object `SomeTrait` to contain |
1366 | references (with a maximum lifetime of `'a`). | |
62682a34 SL |
1367 | |
1368 | [1]: https://github.com/rust-lang/rfcs/pull/1156 | |
b039eaaf SL |
1369 | "##, |
1370 | ||
92a42be0 SL |
1371 | E0452: r##" |
1372 | An invalid lint attribute has been given. Erroneous code example: | |
b039eaaf | 1373 | |
3157f602 | 1374 | ```compile_fail,E0452 |
92a42be0 | 1375 | #![allow(foo = "")] // error: malformed lint attribute |
b039eaaf SL |
1376 | ``` |
1377 | ||
92a42be0 SL |
1378 | Lint attributes only accept a list of identifiers (where each identifier is a |
1379 | lint name). Ensure the attribute is of this form: | |
1380 | ||
1381 | ``` | |
1382 | #![allow(foo)] // ok! | |
1383 | // or: | |
1384 | #![allow(foo, foo2)] // ok! | |
1385 | ``` | |
b039eaaf SL |
1386 | "##, |
1387 | ||
3157f602 XL |
1388 | E0453: r##" |
1389 | A lint check attribute was overruled by a `forbid` directive set as an | |
1390 | attribute on an enclosing scope, or on the command line with the `-F` option. | |
1391 | ||
1392 | Example of erroneous code: | |
1393 | ||
1394 | ```compile_fail,E0453 | |
1395 | #![forbid(non_snake_case)] | |
1396 | ||
1397 | #[allow(non_snake_case)] | |
1398 | fn main() { | |
1399 | let MyNumber = 2; // error: allow(non_snake_case) overruled by outer | |
1400 | // forbid(non_snake_case) | |
1401 | } | |
1402 | ``` | |
1403 | ||
1404 | The `forbid` lint setting, like `deny`, turns the corresponding compiler | |
1405 | warning into a hard error. Unlike `deny`, `forbid` prevents itself from being | |
1406 | overridden by inner attributes. | |
1407 | ||
1408 | If you're sure you want to override the lint check, you can change `forbid` to | |
1409 | `deny` (or use `-D` instead of `-F` if the `forbid` setting was given as a | |
1410 | command-line option) to allow the inner lint check attribute: | |
1411 | ||
1412 | ``` | |
1413 | #![deny(non_snake_case)] | |
1414 | ||
1415 | #[allow(non_snake_case)] | |
1416 | fn main() { | |
1417 | let MyNumber = 2; // ok! | |
1418 | } | |
1419 | ``` | |
1420 | ||
1421 | Otherwise, edit the code to pass the lint check, and remove the overruled | |
1422 | attribute: | |
1423 | ||
1424 | ``` | |
1425 | #![forbid(non_snake_case)] | |
1426 | ||
1427 | fn main() { | |
1428 | let my_number = 2; | |
1429 | } | |
1430 | ``` | |
1431 | "##, | |
1432 | ||
9e0c209e SL |
1433 | E0478: r##" |
1434 | A lifetime bound was not satisfied. | |
1435 | ||
1436 | Erroneous code example: | |
1437 | ||
1438 | ```compile_fail,E0478 | |
1439 | // Check that the explicit lifetime bound (`'SnowWhite`, in this example) must | |
1440 | // outlive all the superbounds from the trait (`'kiss`, in this example). | |
1441 | ||
1442 | trait Wedding<'t>: 't { } | |
1443 | ||
1444 | struct Prince<'kiss, 'SnowWhite> { | |
1445 | child: Box<Wedding<'kiss> + 'SnowWhite>, | |
1446 | // error: lifetime bound not satisfied | |
1447 | } | |
1448 | ``` | |
1449 | ||
1450 | In this example, the `'SnowWhite` lifetime is supposed to outlive the `'kiss` | |
1451 | lifetime but the declaration of the `Prince` struct doesn't enforce it. To fix | |
1452 | this issue, you need to specify it: | |
1453 | ||
1454 | ``` | |
1455 | trait Wedding<'t>: 't { } | |
1456 | ||
1457 | struct Prince<'kiss, 'SnowWhite: 'kiss> { // You say here that 'kiss must live | |
1458 | // longer than 'SnowWhite. | |
1459 | child: Box<Wedding<'kiss> + 'SnowWhite>, // And now it's all good! | |
1460 | } | |
1461 | ``` | |
1462 | "##, | |
1463 | ||
32a655c1 SL |
1464 | E0491: r##" |
1465 | A reference has a longer lifetime than the data it references. | |
1466 | ||
1467 | Erroneous code example: | |
1468 | ||
1469 | ```compile_fail,E0491 | |
1470 | // struct containing a reference requires a lifetime parameter, | |
1471 | // because the data the reference points to must outlive the struct (see E0106) | |
1472 | struct Struct<'a> { | |
1473 | ref_i32: &'a i32, | |
1474 | } | |
1475 | ||
1476 | // However, a nested struct like this, the signature itself does not tell | |
1477 | // whether 'a outlives 'b or the other way around. | |
1478 | // So it could be possible that 'b of reference outlives 'a of the data. | |
1479 | struct Nested<'a, 'b> { | |
1480 | ref_struct: &'b Struct<'a>, // compile error E0491 | |
1481 | } | |
1482 | ``` | |
1483 | ||
1484 | To fix this issue, you can specify a bound to the lifetime like below: | |
1485 | ||
1486 | ``` | |
1487 | struct Struct<'a> { | |
1488 | ref_i32: &'a i32, | |
1489 | } | |
1490 | ||
1491 | // 'a: 'b means 'a outlives 'b | |
1492 | struct Nested<'a: 'b, 'b> { | |
1493 | ref_struct: &'b Struct<'a>, | |
1494 | } | |
1495 | ``` | |
1496 | "##, | |
1497 | ||
b039eaaf SL |
1498 | E0496: r##" |
1499 | A lifetime name is shadowing another lifetime name. Erroneous code example: | |
1500 | ||
3157f602 | 1501 | ```compile_fail,E0496 |
b039eaaf SL |
1502 | struct Foo<'a> { |
1503 | a: &'a i32, | |
1504 | } | |
1505 | ||
1506 | impl<'a> Foo<'a> { | |
1507 | fn f<'a>(x: &'a i32) { // error: lifetime name `'a` shadows a lifetime | |
1508 | // name that is already in scope | |
1509 | } | |
1510 | } | |
1511 | ``` | |
1512 | ||
1513 | Please change the name of one of the lifetimes to remove this error. Example: | |
1514 | ||
b039eaaf SL |
1515 | ``` |
1516 | struct Foo<'a> { | |
1517 | a: &'a i32, | |
1518 | } | |
1519 | ||
1520 | impl<'a> Foo<'a> { | |
1521 | fn f<'b>(x: &'b i32) { // ok! | |
1522 | } | |
1523 | } | |
1524 | ||
1525 | fn main() { | |
1526 | } | |
1527 | ``` | |
1528 | "##, | |
1529 | ||
1530 | E0497: r##" | |
1531 | A stability attribute was used outside of the standard library. Erroneous code | |
1532 | example: | |
1533 | ||
7453a54e | 1534 | ```compile_fail |
b039eaaf SL |
1535 | #[stable] // error: stability attributes may not be used outside of the |
1536 | // standard library | |
1537 | fn foo() {} | |
1538 | ``` | |
1539 | ||
1540 | It is not possible to use stability attributes outside of the standard library. | |
1541 | Also, for now, it is not possible to write deprecation messages either. | |
1542 | "##, | |
9346a6ac | 1543 | |
54a0048b SL |
1544 | E0512: r##" |
1545 | Transmute with two differently sized types was attempted. Erroneous code | |
1546 | example: | |
1547 | ||
3157f602 | 1548 | ```compile_fail,E0512 |
54a0048b SL |
1549 | fn takes_u8(_: u8) {} |
1550 | ||
1551 | fn main() { | |
1552 | unsafe { takes_u8(::std::mem::transmute(0u16)); } | |
1553 | // error: transmute called with differently sized types | |
1554 | } | |
1555 | ``` | |
1556 | ||
1557 | Please use types with same size or use the expected type directly. Example: | |
1558 | ||
1559 | ``` | |
1560 | fn takes_u8(_: u8) {} | |
1561 | ||
1562 | fn main() { | |
1563 | unsafe { takes_u8(::std::mem::transmute(0i8)); } // ok! | |
1564 | // or: | |
1565 | unsafe { takes_u8(0u8); } // ok! | |
1566 | } | |
1567 | ``` | |
1568 | "##, | |
1569 | ||
92a42be0 | 1570 | E0517: r##" |
7453a54e SL |
1571 | This error indicates that a `#[repr(..)]` attribute was placed on an |
1572 | unsupported item. | |
92a42be0 SL |
1573 | |
1574 | Examples of erroneous code: | |
1575 | ||
3157f602 | 1576 | ```compile_fail,E0517 |
92a42be0 SL |
1577 | #[repr(C)] |
1578 | type Foo = u8; | |
1579 | ||
1580 | #[repr(packed)] | |
1581 | enum Foo {Bar, Baz} | |
1582 | ||
1583 | #[repr(u8)] | |
1584 | struct Foo {bar: bool, baz: bool} | |
1585 | ||
1586 | #[repr(C)] | |
1587 | impl Foo { | |
7453a54e | 1588 | // ... |
92a42be0 SL |
1589 | } |
1590 | ``` | |
1591 | ||
7453a54e SL |
1592 | * The `#[repr(C)]` attribute can only be placed on structs and enums. |
1593 | * The `#[repr(packed)]` and `#[repr(simd)]` attributes only work on structs. | |
1594 | * The `#[repr(u8)]`, `#[repr(i16)]`, etc attributes only work on enums. | |
92a42be0 SL |
1595 | |
1596 | These attributes do not work on typedefs, since typedefs are just aliases. | |
1597 | ||
1598 | Representations like `#[repr(u8)]`, `#[repr(i64)]` are for selecting the | |
7453a54e SL |
1599 | discriminant size for C-like enums (when there is no associated data, e.g. |
1600 | `enum Color {Red, Blue, Green}`), effectively setting the size of the enum to | |
1601 | the size of the provided type. Such an enum can be cast to a value of the same | |
1602 | type as well. In short, `#[repr(u8)]` makes the enum behave like an integer | |
1603 | with a constrained set of allowed values. | |
92a42be0 SL |
1604 | |
1605 | Only C-like enums can be cast to numerical primitives, so this attribute will | |
1606 | not apply to structs. | |
1607 | ||
1608 | `#[repr(packed)]` reduces padding to make the struct size smaller. The | |
7453a54e SL |
1609 | representation of enums isn't strictly defined in Rust, and this attribute |
1610 | won't work on enums. | |
92a42be0 SL |
1611 | |
1612 | `#[repr(simd)]` will give a struct consisting of a homogenous series of machine | |
1613 | types (i.e. `u8`, `i32`, etc) a representation that permits vectorization via | |
1614 | SIMD. This doesn't make much sense for enums since they don't consist of a | |
1615 | single list of data. | |
1616 | "##, | |
1617 | ||
1618 | E0518: r##" | |
7453a54e SL |
1619 | This error indicates that an `#[inline(..)]` attribute was incorrectly placed |
1620 | on something other than a function or method. | |
92a42be0 SL |
1621 | |
1622 | Examples of erroneous code: | |
1623 | ||
3157f602 | 1624 | ```compile_fail,E0518 |
92a42be0 SL |
1625 | #[inline(always)] |
1626 | struct Foo; | |
1627 | ||
1628 | #[inline(never)] | |
1629 | impl Foo { | |
7453a54e | 1630 | // ... |
92a42be0 SL |
1631 | } |
1632 | ``` | |
1633 | ||
1634 | `#[inline]` hints the compiler whether or not to attempt to inline a method or | |
1635 | function. By default, the compiler does a pretty good job of figuring this out | |
1636 | itself, but if you feel the need for annotations, `#[inline(always)]` and | |
1637 | `#[inline(never)]` can override or force the compiler's decision. | |
1638 | ||
1639 | If you wish to apply this attribute to all methods in an impl, manually annotate | |
1640 | each method; it is not possible to annotate the entire impl with an `#[inline]` | |
1641 | attribute. | |
1642 | "##, | |
1643 | ||
54a0048b SL |
1644 | E0522: r##" |
1645 | The lang attribute is intended for marking special items that are built-in to | |
1646 | Rust itself. This includes special traits (like `Copy` and `Sized`) that affect | |
1647 | how the compiler behaves, as well as special functions that may be automatically | |
1648 | invoked (such as the handler for out-of-bounds accesses when indexing a slice). | |
1649 | Erroneous code example: | |
1650 | ||
3157f602 | 1651 | ```compile_fail,E0522 |
54a0048b SL |
1652 | #![feature(lang_items)] |
1653 | ||
1654 | #[lang = "cookie"] | |
1655 | fn cookie() -> ! { // error: definition of an unknown language item: `cookie` | |
1656 | loop {} | |
1657 | } | |
1658 | ``` | |
1659 | "##, | |
1660 | ||
9e0c209e | 1661 | E0525: r##" |
32a655c1 | 1662 | A closure was used but didn't implement the expected trait. |
9e0c209e SL |
1663 | |
1664 | Erroneous code example: | |
1665 | ||
1666 | ```compile_fail,E0525 | |
1667 | struct X; | |
1668 | ||
1669 | fn foo<T>(_: T) {} | |
1670 | fn bar<T: Fn(u32)>(_: T) {} | |
1671 | ||
1672 | fn main() { | |
1673 | let x = X; | |
1674 | let closure = |_| foo(x); // error: expected a closure that implements | |
1675 | // the `Fn` trait, but this closure only | |
1676 | // implements `FnOnce` | |
1677 | bar(closure); | |
1678 | } | |
1679 | ``` | |
1680 | ||
1681 | In the example above, `closure` is an `FnOnce` closure whereas the `bar` | |
1682 | function expected an `Fn` closure. In this case, it's simple to fix the issue, | |
1683 | you just have to implement `Copy` and `Clone` traits on `struct X` and it'll | |
1684 | be ok: | |
1685 | ||
1686 | ``` | |
1687 | #[derive(Clone, Copy)] // We implement `Clone` and `Copy` traits. | |
1688 | struct X; | |
1689 | ||
1690 | fn foo<T>(_: T) {} | |
1691 | fn bar<T: Fn(u32)>(_: T) {} | |
1692 | ||
1693 | fn main() { | |
1694 | let x = X; | |
1695 | let closure = |_| foo(x); | |
1696 | bar(closure); // ok! | |
1697 | } | |
1698 | ``` | |
1699 | ||
1700 | To understand better how closures work in Rust, read: | |
1701 | https://doc.rust-lang.org/book/closures.html | |
1702 | "##, | |
1703 | ||
32a655c1 SL |
1704 | E0580: r##" |
1705 | The `main` function was incorrectly declared. | |
1706 | ||
1707 | Erroneous code example: | |
1708 | ||
1709 | ```compile_fail,E0580 | |
1710 | fn main() -> i32 { // error: main function has wrong type | |
1711 | 0 | |
1712 | } | |
1713 | ``` | |
1714 | ||
1715 | The `main` function prototype should never take arguments or return type. | |
1716 | Example: | |
1717 | ||
1718 | ``` | |
1719 | fn main() { | |
1720 | // your code | |
1721 | } | |
1722 | ``` | |
1723 | ||
1724 | If you want to get command-line arguments, use `std::env::args`. To exit with a | |
1725 | specified exit code, use `std::process::exit`. | |
1726 | "##, | |
1727 | ||
8bb4bdeb XL |
1728 | E0591: r##" |
1729 | Per [RFC 401][rfc401], if you have a function declaration `foo`: | |
1730 | ||
1731 | ```rust,ignore | |
1732 | // For the purposes of this explanation, all of these | |
1733 | // different kinds of `fn` declarations are equivalent: | |
1734 | fn foo(x: i32) { ... } | |
1735 | extern "C" fn foo(x: i32); | |
1736 | impl i32 { fn foo(x: self) { ... } } | |
1737 | ``` | |
1738 | ||
1739 | the type of `foo` is **not** `fn(i32)`, as one might expect. | |
1740 | Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`. | |
1741 | However, `typeof(foo)` can be _coerced_ to a function pointer `fn(i32)`, | |
1742 | so you rarely notice this: | |
1743 | ||
1744 | ```rust,ignore | |
1745 | let x: fn(i32) = foo; // OK, coerces | |
1746 | ``` | |
1747 | ||
1748 | The reason that this matter is that the type `fn(i32)` is not specific to | |
1749 | any particular function: it's a function _pointer_. So calling `x()` results | |
1750 | in a virtual call, whereas `foo()` is statically dispatched, because the type | |
1751 | of `foo` tells us precisely what function is being called. | |
1752 | ||
1753 | As noted above, coercions mean that most code doesn't have to be | |
1754 | concerned with this distinction. However, you can tell the difference | |
1755 | when using **transmute** to convert a fn item into a fn pointer. | |
1756 | ||
1757 | This is sometimes done as part of an FFI: | |
1758 | ||
1759 | ```rust,ignore | |
1760 | extern "C" fn foo(userdata: Box<i32>) { | |
1761 | ... | |
1762 | } | |
1763 | ||
1764 | let f: extern "C" fn(*mut i32) = transmute(foo); | |
1765 | callback(f); | |
1766 | ||
1767 | ``` | |
1768 | ||
1769 | Here, transmute is being used to convert the types of the fn arguments. | |
1770 | This pattern is incorrect because, because the type of `foo` is a function | |
1771 | **item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`) | |
1772 | is a function pointer, which is not zero-sized. | |
1773 | This pattern should be rewritten. There are a few possible ways to do this: | |
1774 | - change the original fn declaration to match the expected signature, | |
1775 | and do the cast in the fn body (the prefered option) | |
1776 | - cast the fn item fo a fn pointer before calling transmute, as shown here: | |
1777 | - `let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_))` | |
1778 | - `let f: extern "C" fn(*mut i32) = transmute(foo as usize) /* works too */` | |
1779 | ||
1780 | The same applies to transmutes to `*mut fn()`, which were observedin practice. | |
1781 | Note though that use of this type is generally incorrect. | |
1782 | The intention is typically to describe a function pointer, but just `fn()` | |
1783 | alone suffices for that. `*mut fn()` is a pointer to a fn pointer. | |
1784 | (Since these values are typically just passed to C code, however, this rarely | |
1785 | makes a difference in practice.) | |
1786 | ||
1787 | [rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md | |
1788 | "##, | |
1789 | ||
85aaf69f | 1790 | } |
1a4d82fc | 1791 | |
d9579d0f | 1792 | |
1a4d82fc | 1793 | register_diagnostics! { |
7453a54e | 1794 | // E0006 // merged with E0005 |
c1a9b12d SL |
1795 | // E0134, |
1796 | // E0135, | |
85aaf69f SL |
1797 | E0278, // requirement is not satisfied |
1798 | E0279, // requirement is not satisfied | |
1799 | E0280, // requirement is not satisfied | |
85aaf69f | 1800 | E0284, // cannot resolve type |
7453a54e | 1801 | // E0285, // overflow evaluation builtin bounds |
7453a54e SL |
1802 | // E0300, // unexpanded macro |
1803 | // E0304, // expected signed integer constant | |
1804 | // E0305, // expected constant | |
85aaf69f | 1805 | E0311, // thing may not live long enough |
85aaf69f SL |
1806 | E0313, // lifetime of borrowed pointer outlives lifetime of captured variable |
1807 | E0314, // closure outlives stack frame | |
1808 | E0315, // cannot invoke closure outside of its lifetime | |
c34b1796 | 1809 | E0316, // nested quantification of lifetimes |
b039eaaf SL |
1810 | E0473, // dereference of reference outside its lifetime |
1811 | E0474, // captured variable `..` does not outlive the enclosing closure | |
1812 | E0475, // index of slice outside its lifetime | |
1813 | E0476, // lifetime of the source pointer does not outlive lifetime bound... | |
1814 | E0477, // the type `..` does not fulfill the required lifetime... | |
b039eaaf SL |
1815 | E0479, // the type `..` (provided as the value of a type parameter) is... |
1816 | E0480, // lifetime of method receiver does not outlive the method call | |
1817 | E0481, // lifetime of function argument does not outlive the function call | |
1818 | E0482, // lifetime of return value does not outlive the function call | |
1819 | E0483, // lifetime of operand does not outlive the operation | |
1820 | E0484, // reference is not valid at the time of borrow | |
1821 | E0485, // automatically reference is not valid at the time of borrow | |
1822 | E0486, // type of expression contains references that are not valid during... | |
1823 | E0487, // unsafe use of destructor: destructor might be called while... | |
1824 | E0488, // lifetime of variable does not enclose its declaration | |
1825 | E0489, // type/lifetime parameter not in scope here | |
1826 | E0490, // a value of type `..` is borrowed for too long | |
b039eaaf | 1827 | E0495, // cannot infer an appropriate lifetime due to conflicting requirements |
9e0c209e | 1828 | E0566 // conflicting representation hints |
1a4d82fc | 1829 | } |