]>
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 | ||
d9579d0f AL |
13 | register_long_diagnostics! { |
14 | ||
62682a34 SL |
15 | E0023: r##" |
16 | A pattern used to match against an enum variant must provide a sub-pattern for | |
17 | each field of the enum variant. This error indicates that a pattern attempted to | |
18 | extract an incorrect number of fields from a variant. | |
19 | ||
20 | ``` | |
21 | enum Fruit { | |
22 | Apple(String, String) | |
23 | Pear(u32) | |
24 | } | |
25 | ``` | |
26 | ||
27 | Here the `Apple` variant has two fields, and should be matched against like so: | |
28 | ||
29 | ``` | |
30 | // Correct. | |
31 | match x { | |
32 | Apple(a, b) => ... | |
33 | } | |
34 | ``` | |
35 | ||
36 | Matching with the wrong number of fields has no sensible interpretation: | |
37 | ||
38 | ``` | |
39 | // Incorrect. | |
40 | match x { | |
41 | Apple(a) => ..., | |
42 | Apple(a, b, c) => ... | |
43 | } | |
44 | ``` | |
45 | ||
46 | Check how many fields the enum was declared with and ensure that your pattern | |
47 | uses the same number. | |
48 | "##, | |
49 | ||
50 | E0024: r##" | |
51 | This error indicates that a pattern attempted to extract the fields of an enum | |
52 | variant with no fields. Here's a tiny example of this error: | |
53 | ||
54 | ``` | |
55 | // This enum has two variants. | |
56 | enum Number { | |
57 | // This variant has no fields. | |
58 | Zero, | |
59 | // This variant has one field. | |
60 | One(u32) | |
61 | } | |
62 | ||
63 | // Assuming x is a Number we can pattern match on its contents. | |
64 | match x { | |
65 | Zero(inside) => ..., | |
66 | One(inside) => ... | |
67 | } | |
68 | ``` | |
69 | ||
70 | The pattern match `Zero(inside)` is incorrect because the `Zero` variant | |
71 | contains no fields, yet the `inside` name attempts to bind the first field of | |
72 | the enum. | |
73 | "##, | |
74 | ||
75 | E0025: r##" | |
76 | Each field of a struct can only be bound once in a pattern. Each occurrence of a | |
77 | field name binds the value of that field, so to fix this error you will have to | |
78 | remove or alter the duplicate uses of the field name. Perhaps you misspelt | |
79 | another field name? | |
80 | "##, | |
81 | ||
82 | E0026: r##" | |
83 | This error indicates that a struct pattern attempted to extract a non-existant | |
84 | field from a struct. Struct fields are identified by the name used before the | |
85 | colon `:` so struct patterns should resemble the declaration of the struct type | |
86 | being matched. | |
87 | ||
88 | ``` | |
89 | // Correct matching. | |
90 | struct Thing { | |
91 | x: u32, | |
92 | y: u32 | |
93 | } | |
94 | ||
95 | let thing = Thing { x: 1, y: 2 }; | |
96 | match thing { | |
97 | Thing { x: xfield, y: yfield } => ... | |
98 | } | |
99 | ``` | |
100 | ||
101 | If you are using shorthand field patterns but want to refer to the struct field | |
102 | by a different name, you should rename it explicitly. | |
103 | ||
104 | ``` | |
105 | // Change this: | |
106 | match thing { | |
107 | Thing { x, z } => ... | |
108 | } | |
109 | ||
110 | // To this: | |
111 | match thing { | |
112 | Thing { x, y: z } => ... | |
113 | } | |
114 | ``` | |
115 | "##, | |
116 | ||
117 | E0027: r##" | |
118 | This error indicates that a pattern for a struct fails to specify a sub-pattern | |
119 | for every one of the struct's fields. Ensure that each field from the struct's | |
120 | definition is mentioned in the pattern, or use `..` to ignore unwanted fields. | |
121 | ||
122 | For example: | |
123 | ||
124 | ``` | |
125 | struct Dog { | |
126 | name: String, | |
127 | age: u32 | |
128 | } | |
129 | ||
130 | let d = Dog { name: "Rusty".to_string(), age: 8 }; | |
131 | ||
132 | // This is incorrect. | |
133 | match d { | |
134 | Dog { age: x } => ... | |
135 | } | |
136 | ||
137 | // This is correct (explicit). | |
138 | match d { | |
139 | Dog { name: n, age: x } => ... | |
140 | } | |
141 | ||
142 | // This is also correct (ignore unused fields). | |
143 | match d { | |
144 | Dog { age: x, .. } => ... | |
145 | } | |
146 | ``` | |
147 | "##, | |
148 | ||
149 | E0029: r##" | |
150 | In a match expression, only numbers and characters can be matched against a | |
151 | range. This is because the compiler checks that the range is non-empty at | |
152 | compile-time, and is unable to evaluate arbitrary comparison functions. If you | |
153 | want to capture values of an orderable type between two end-points, you can use | |
154 | a guard. | |
155 | ||
156 | ``` | |
157 | // The ordering relation for strings can't be evaluated at compile time, | |
158 | // so this doesn't work: | |
159 | match string { | |
160 | "hello" ... "world" => ... | |
161 | _ => ... | |
162 | } | |
163 | ||
164 | // This is a more general version, using a guard: | |
165 | match string { | |
166 | s if s >= "hello" && s <= "world" => ... | |
167 | _ => ... | |
168 | } | |
169 | ``` | |
170 | "##, | |
171 | ||
172 | E0030: r##" | |
173 | When matching against a range, the compiler verifies that the range is | |
174 | non-empty. Range patterns include both end-points, so this is equivalent to | |
175 | requiring the start of the range to be less than or equal to the end of the | |
176 | range. | |
177 | ||
178 | For example: | |
179 | ||
180 | ``` | |
181 | match 5u32 { | |
182 | // This range is ok, albeit pointless. | |
183 | 1 ... 1 => ... | |
184 | // This range is empty, and the compiler can tell. | |
185 | 1000 ... 5 => ... | |
186 | } | |
187 | ``` | |
188 | "##, | |
189 | ||
190 | E0033: r##" | |
191 | This error indicates that a pointer to a trait type cannot be implicitly | |
192 | dereferenced by a pattern. Every trait defines a type, but because the | |
193 | size of trait implementors isn't fixed, this type has no compile-time size. | |
194 | Therefore, all accesses to trait types must be through pointers. If you | |
195 | encounter this error you should try to avoid dereferencing the pointer. | |
196 | ||
197 | ``` | |
198 | let trait_obj: &SomeTrait = ...; | |
199 | ||
200 | // This tries to implicitly dereference to create an unsized local variable. | |
201 | let &invalid = trait_obj; | |
202 | ||
203 | // You can call methods without binding to the value being pointed at. | |
204 | trait_obj.method_one(); | |
205 | trait_obj.method_two(); | |
206 | ``` | |
207 | ||
208 | You can read more about trait objects in the Trait Object section of the | |
209 | Reference: | |
210 | ||
211 | http://doc.rust-lang.org/reference.html#trait-objects | |
212 | "##, | |
213 | ||
214 | E0034: r##" | |
215 | The compiler doesn't know what method to call because more than one method | |
216 | has the same prototype. Example: | |
217 | ||
218 | ``` | |
219 | struct Test; | |
220 | ||
221 | trait Trait1 { | |
222 | fn foo(); | |
223 | } | |
224 | ||
225 | trait Trait2 { | |
226 | fn foo(); | |
227 | } | |
228 | ||
229 | impl Trait1 for Test { fn foo() {} } | |
230 | impl Trait2 for Test { fn foo() {} } | |
231 | ||
232 | fn main() { | |
233 | Test::foo() // error, which foo() to call? | |
234 | } | |
235 | ``` | |
236 | ||
237 | To avoid this error, you have to keep only one of them and remove the others. | |
238 | So let's take our example and fix it: | |
239 | ||
240 | ``` | |
241 | struct Test; | |
242 | ||
243 | trait Trait1 { | |
244 | fn foo(); | |
245 | } | |
246 | ||
247 | impl Trait1 for Test { fn foo() {} } | |
248 | ||
249 | fn main() { | |
250 | Test::foo() // and now that's good! | |
251 | } | |
252 | ``` | |
253 | ||
254 | However, a better solution would be using fully explicit naming of type and | |
255 | trait: | |
256 | ||
257 | ``` | |
258 | struct Test; | |
259 | ||
260 | trait Trait1 { | |
261 | fn foo(); | |
262 | } | |
263 | ||
264 | trait Trait2 { | |
265 | fn foo(); | |
266 | } | |
267 | ||
268 | impl Trait1 for Test { fn foo() {} } | |
269 | impl Trait2 for Test { fn foo() {} } | |
270 | ||
271 | fn main() { | |
272 | <Test as Trait1>::foo() | |
273 | } | |
274 | ``` | |
275 | "##, | |
276 | ||
277 | E0035: r##" | |
278 | You tried to give a type parameter where it wasn't needed. Bad example: | |
279 | ||
280 | ``` | |
281 | struct Test; | |
282 | ||
283 | impl Test { | |
284 | fn method(&self) {} | |
285 | } | |
286 | ||
287 | fn main() { | |
288 | let x = Test; | |
289 | ||
290 | x.method::<i32>(); // Error: Test::method doesn't need type parameter! | |
291 | } | |
292 | ``` | |
293 | ||
294 | To fix this error, just remove the type parameter: | |
295 | ||
296 | ``` | |
297 | struct Test; | |
298 | ||
299 | impl Test { | |
300 | fn method(&self) {} | |
301 | } | |
302 | ||
303 | fn main() { | |
304 | let x = Test; | |
305 | ||
306 | x.method(); // OK, we're good! | |
307 | } | |
308 | ``` | |
309 | "##, | |
310 | ||
311 | E0036: r##" | |
312 | This error occurrs when you pass too many or not enough type parameters to | |
313 | a method. Example: | |
314 | ||
315 | ``` | |
316 | struct Test; | |
317 | ||
318 | impl Test { | |
319 | fn method<T>(&self, v: &[T]) -> usize { | |
320 | v.len() | |
321 | } | |
322 | } | |
323 | ||
324 | fn main() { | |
325 | let x = Test; | |
326 | let v = &[0i32]; | |
327 | ||
328 | x.method::<i32, i32>(v); // error: only one type parameter is expected! | |
329 | } | |
330 | ``` | |
331 | ||
332 | To fix it, just specify a correct number of type parameters: | |
333 | ||
334 | ``` | |
335 | struct Test; | |
336 | ||
337 | impl Test { | |
338 | fn method<T>(&self, v: &[T]) -> usize { | |
339 | v.len() | |
340 | } | |
341 | } | |
342 | ||
343 | fn main() { | |
344 | let x = Test; | |
345 | let v = &[0i32]; | |
346 | ||
347 | x.method::<i32>(v); // OK, we're good! | |
348 | } | |
349 | ``` | |
350 | ||
351 | Please note on the last example that we could have called `method` like this: | |
352 | ||
353 | ``` | |
354 | x.method(v); | |
355 | ``` | |
356 | "##, | |
357 | ||
358 | E0040: r##" | |
359 | It is not allowed to manually call destructors in Rust. It is also not | |
360 | necessary to do this since `drop` is called automatically whenever a value goes | |
361 | out of scope. | |
362 | ||
363 | Here's an example of this error: | |
364 | ||
365 | ``` | |
366 | struct Foo { | |
367 | x: i32, | |
368 | } | |
369 | ||
370 | impl Drop for Foo { | |
371 | fn drop(&mut self) { | |
372 | println!("kaboom"); | |
373 | } | |
374 | } | |
375 | ||
376 | fn main() { | |
377 | let mut x = Foo { x: -7 }; | |
378 | x.drop(); // error: explicit use of destructor method | |
379 | } | |
380 | ``` | |
381 | "##, | |
382 | ||
383 | E0045: r##" | |
384 | Rust only supports variadic parameters for interoperability with C code in its | |
385 | FFI. As such, variadic parameters can only be used with functions which are | |
386 | using the C ABI. Examples of erroneous code: | |
387 | ||
388 | ``` | |
389 | extern "rust-call" { fn foo(x: u8, ...); } | |
390 | // or | |
391 | fn foo(x: u8, ...) {} | |
392 | ``` | |
393 | ||
394 | To fix such code, put them in an extern "C" block: | |
395 | ||
396 | ``` | |
397 | extern "C" fn foo (x: u8, ...); | |
398 | // or: | |
399 | extern "C" { | |
400 | fn foo (x: u8, ...); | |
401 | } | |
402 | ``` | |
403 | "##, | |
404 | ||
d9579d0f AL |
405 | E0046: r##" |
406 | When trying to make some type implement a trait `Foo`, you must, at minimum, | |
407 | provide implementations for all of `Foo`'s required methods (meaning the | |
408 | methods that do not have default implementations), as well as any required | |
409 | trait items like associated types or constants. | |
410 | "##, | |
411 | ||
412 | E0049: r##" | |
413 | This error indicates that an attempted implementation of a trait method | |
414 | has the wrong number of type parameters. | |
415 | ||
416 | For example, the trait below has a method `foo` with a type parameter `T`, | |
417 | but the implementation of `foo` for the type `Bar` is missing this parameter: | |
418 | ||
419 | ``` | |
420 | trait Foo { | |
421 | fn foo<T: Default>(x: T) -> Self; | |
422 | } | |
423 | ||
424 | struct Bar; | |
425 | ||
426 | // error: method `foo` has 0 type parameters but its trait declaration has 1 | |
427 | // type parameter | |
428 | impl Foo for Bar { | |
429 | fn foo(x: bool) -> Self { Bar } | |
430 | } | |
431 | ``` | |
432 | "##, | |
433 | ||
434 | E0050: r##" | |
435 | This error indicates that an attempted implementation of a trait method | |
436 | has the wrong number of function parameters. | |
437 | ||
438 | For example, the trait below has a method `foo` with two function parameters | |
439 | (`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits | |
440 | the `u8` parameter: | |
441 | ||
442 | ``` | |
443 | trait Foo { | |
444 | fn foo(&self, x: u8) -> bool; | |
445 | } | |
446 | ||
447 | struct Bar; | |
448 | ||
449 | // error: method `foo` has 1 parameter but the declaration in trait `Foo::foo` | |
450 | // has 2 | |
451 | impl Foo for Bar { | |
452 | fn foo(&self) -> bool { true } | |
453 | } | |
454 | ``` | |
455 | "##, | |
456 | ||
457 | E0053: r##" | |
62682a34 SL |
458 | The parameters of any trait method must match between a trait implementation |
459 | and the trait definition. | |
d9579d0f | 460 | |
62682a34 | 461 | Here are a couple examples of this error: |
d9579d0f AL |
462 | |
463 | ``` | |
62682a34 SL |
464 | trait Foo { |
465 | fn foo(x: u16); | |
466 | fn bar(&self); | |
467 | } | |
d9579d0f AL |
468 | |
469 | struct Bar; | |
470 | ||
471 | impl Foo for Bar { | |
62682a34 SL |
472 | // error, expected u16, found i16 |
473 | fn foo(x: i16) { } | |
474 | ||
475 | // error, values differ in mutability | |
476 | fn bar(&mut self) { } | |
d9579d0f | 477 | } |
62682a34 SL |
478 | ``` |
479 | "##, | |
480 | ||
481 | E0054: r##" | |
482 | It is not allowed to cast to a bool. If you are trying to cast a numeric type | |
483 | to a bool, you can compare it with zero instead: | |
d9579d0f | 484 | |
d9579d0f | 485 | ``` |
62682a34 | 486 | let x = 5; |
d9579d0f | 487 | |
62682a34 SL |
488 | // Ok |
489 | let x_is_nonzero = x != 0; | |
d9579d0f | 490 | |
62682a34 SL |
491 | // Not allowed, won't compile |
492 | let x_is_nonzero = x as bool; | |
d9579d0f | 493 | ``` |
62682a34 | 494 | "##, |
d9579d0f | 495 | |
62682a34 SL |
496 | E0055: r##" |
497 | During a method call, a value is automatically dereferenced as many times as | |
498 | needed to make the value's type match the method's receiver. The catch is that | |
499 | the compiler will only attempt to dereference a number of times up to the | |
500 | recursion limit (which can be set via the `recursion_limit` attribute). | |
d9579d0f | 501 | |
62682a34 SL |
502 | For a somewhat artificial example: |
503 | ||
504 | ``` | |
505 | #![recursion_limit="2"] | |
506 | ||
507 | struct Foo; | |
508 | ||
509 | impl Foo { | |
510 | fn foo(&self) {} | |
511 | } | |
512 | ||
513 | fn main() { | |
514 | let foo = Foo; | |
515 | let ref_foo = &&Foo; | |
516 | ||
517 | // error, reached the recursion limit while auto-dereferencing &&Foo | |
518 | ref_foo.foo(); | |
519 | } | |
520 | ``` | |
521 | ||
522 | One fix may be to increase the recursion limit. Note that it is possible to | |
523 | create an infinite recursion of dereferencing, in which case the only fix is to | |
524 | somehow break the recursion. | |
525 | "##, | |
526 | ||
527 | E0057: r##" | |
528 | When invoking closures or other implementations of the function traits `Fn`, | |
529 | `FnMut` or `FnOnce` using call notation, the number of parameters passed to the | |
530 | function must match its definition. | |
531 | ||
532 | An example using a closure: | |
533 | ||
534 | ``` | |
535 | let f = |x| x * 3; | |
536 | let a = f(); // invalid, too few parameters | |
537 | let b = f(4); // this works! | |
538 | let c = f(2, 3); // invalid, too many parameters | |
539 | ``` | |
540 | ||
541 | A generic function must be treated similarly: | |
542 | ||
543 | ``` | |
544 | fn foo<F: Fn()>(f: F) { | |
545 | f(); // this is valid, but f(3) would not work | |
d9579d0f | 546 | } |
62682a34 SL |
547 | ``` |
548 | "##, | |
549 | ||
550 | E0059: r##" | |
551 | The built-in function traits are generic over a tuple of the function arguments. | |
552 | If one uses angle-bracket notation (`Fn<(T,), Output=U>`) instead of parentheses | |
553 | (`Fn(T) -> U`) to denote the function trait, the type parameter should be a | |
554 | tuple. Otherwise function call notation cannot be used and the trait will not be | |
555 | implemented by closures. | |
d9579d0f | 556 | |
62682a34 SL |
557 | The most likely source of this error is using angle-bracket notation without |
558 | wrapping the function argument type into a tuple, for example: | |
559 | ||
560 | ``` | |
561 | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) } | |
d9579d0f AL |
562 | ``` |
563 | ||
62682a34 SL |
564 | It can be fixed by adjusting the trait bound like this: |
565 | ||
566 | ``` | |
567 | fn foo<F: Fn<(i32,)>>(f: F) -> F::Output { f(3) } | |
568 | ``` | |
d9579d0f | 569 | |
62682a34 SL |
570 | Note that `(T,)` always denotes the type of a 1-tuple containing an element of |
571 | type `T`. The comma is necessary for syntactic disambiguation. | |
d9579d0f AL |
572 | "##, |
573 | ||
62682a34 SL |
574 | E0060: r##" |
575 | External C functions are allowed to be variadic. However, a variadic function | |
576 | takes a minimum number of arguments. For example, consider C's variadic `printf` | |
577 | function: | |
d9579d0f AL |
578 | |
579 | ``` | |
62682a34 SL |
580 | extern crate libc; |
581 | use libc::{ c_char, c_int }; | |
d9579d0f | 582 | |
62682a34 SL |
583 | extern "C" { |
584 | fn printf(_: *const c_char, ...) -> c_int; | |
585 | } | |
586 | ``` | |
587 | ||
588 | Using this declaration, it must be called with at least one argument, so | |
589 | simply calling `printf()` is illegal. But the following uses are allowed: | |
d9579d0f | 590 | |
d9579d0f | 591 | ``` |
62682a34 SL |
592 | unsafe { |
593 | use std::ffi::CString; | |
594 | ||
595 | printf(CString::new("test\n").unwrap().as_ptr()); | |
596 | printf(CString::new("number = %d\n").unwrap().as_ptr(), 3); | |
597 | printf(CString::new("%d, %d\n").unwrap().as_ptr(), 10, 5); | |
598 | } | |
599 | ``` | |
600 | "##, | |
601 | ||
602 | E0061: r##" | |
603 | The number of arguments passed to a function must match the number of arguments | |
604 | specified in the function signature. | |
605 | ||
606 | For example, a function like | |
607 | ||
608 | ``` | |
609 | fn f(a: u16, b: &str) {} | |
610 | ``` | |
611 | ||
612 | must always be called with exactly two arguments, e.g. `f(2, "test")`. | |
613 | ||
614 | Note, that Rust does not have a notion of optional function arguments or | |
615 | variadic functions (except for its C-FFI). | |
d9579d0f AL |
616 | "##, |
617 | ||
618 | E0062: r##" | |
619 | This error indicates that during an attempt to build a struct or struct-like | |
620 | enum variant, one of the fields was specified more than once. Each field should | |
621 | be specified exactly one time. | |
622 | "##, | |
623 | ||
624 | E0063: r##" | |
625 | This error indicates that during an attempt to build a struct or struct-like | |
62682a34 SL |
626 | enum variant, one of the fields was not provided. Each field should be |
627 | specified exactly once. | |
d9579d0f AL |
628 | "##, |
629 | ||
630 | E0066: r##" | |
631 | Box placement expressions (like C++'s "placement new") do not yet support any | |
632 | place expression except the exchange heap (i.e. `std::boxed::HEAP`). | |
633 | Furthermore, the syntax is changing to use `in` instead of `box`. See [RFC 470] | |
634 | and [RFC 809] for more details. | |
635 | ||
636 | [RFC 470]: https://github.com/rust-lang/rfcs/pull/470 | |
637 | [RFC 809]: https://github.com/rust-lang/rfcs/pull/809 | |
638 | "##, | |
639 | ||
640 | E0067: r##" | |
62682a34 SL |
641 | The left-hand side of a compound assignment expression must be an lvalue |
642 | expression. An lvalue expression represents a memory location and includes | |
643 | item paths (ie, namespaced variables), dereferences, indexing expressions, | |
644 | and field references. | |
d9579d0f | 645 | |
62682a34 | 646 | Let's start with some bad examples: |
d9579d0f AL |
647 | ``` |
648 | use std::collections::LinkedList; | |
649 | ||
d9579d0f AL |
650 | // Bad: assignment to non-lvalue expression |
651 | LinkedList::new() += 1; | |
62682a34 SL |
652 | |
653 | // ... | |
654 | ||
655 | fn some_func(i: &mut i32) { | |
656 | i += 12; // Error : '+=' operation cannot be applied on a reference ! | |
657 | } | |
658 | ||
659 | And now some good examples: | |
660 | ``` | |
661 | let mut i : i32 = 0; | |
662 | ||
663 | i += 12; // Good ! | |
664 | ||
665 | // ... | |
666 | ||
667 | fn some_func(i: &mut i32) { | |
668 | *i += 12; // Good ! | |
669 | } | |
670 | ||
d9579d0f AL |
671 | ``` |
672 | "##, | |
673 | ||
674 | E0069: r##" | |
675 | The compiler found a function whose body contains a `return;` statement but | |
676 | whose return type is not `()`. An example of this is: | |
677 | ||
678 | ``` | |
679 | // error | |
680 | fn foo() -> u8 { | |
681 | return; | |
682 | } | |
683 | ``` | |
684 | ||
685 | Since `return;` is just like `return ();`, there is a mismatch between the | |
686 | function's return type and the value being returned. | |
687 | "##, | |
688 | ||
62682a34 SL |
689 | E0070: r##" |
690 | The left-hand side of an assignment operator must be an lvalue expression. An | |
691 | lvalue expression represents a memory location and can be a variable (with | |
692 | optional namespacing), a dereference, an indexing expression or a field | |
693 | reference. | |
694 | ||
695 | More details can be found here: | |
696 | https://doc.rust-lang.org/reference.html#lvalues,-rvalues-and-temporaries | |
697 | ||
698 | Now, we can go further. Here are some bad examples: | |
699 | ``` | |
700 | struct SomeStruct { | |
701 | x: i32, | |
702 | y: i32 | |
703 | } | |
704 | const SOME_CONST : i32 = 12; | |
705 | ||
706 | fn some_other_func() {} | |
707 | ||
708 | fn some_function() { | |
709 | SOME_CONST = 14; // error : a constant value cannot be changed! | |
710 | 1 = 3; // error : 1 isn't a valid lvalue! | |
711 | some_other_func() = 4; // error : we can't assign value to a function! | |
712 | SomeStruct.x = 12; // error : SomeStruct a structure name but it is used | |
713 | // like a variable! | |
714 | } | |
715 | ``` | |
716 | ||
717 | And now let's give good examples: | |
718 | ||
719 | ``` | |
720 | struct SomeStruct { | |
721 | x: i32, | |
722 | y: i32 | |
723 | } | |
724 | let mut s = SomeStruct {x: 0, y: 0}; | |
725 | ||
726 | s.x = 3; // that's good ! | |
727 | ||
728 | // ... | |
729 | ||
730 | fn some_func(x: &mut i32) { | |
731 | *x = 12; // that's good ! | |
732 | } | |
733 | ``` | |
734 | "##, | |
735 | ||
736 | E0072: r##" | |
737 | When defining a recursive struct or enum, any use of the type being defined | |
738 | from inside the definition must occur behind a pointer (like `Box` or `&`). | |
739 | This is because structs and enums must have a well-defined size, and without | |
740 | the pointer the size of the type would need to be unbounded. | |
741 | ||
742 | Consider the following erroneous definition of a type for a list of bytes: | |
743 | ||
744 | ``` | |
745 | // error, illegal recursive struct type | |
746 | struct ListNode { | |
747 | head: u8, | |
748 | tail: Option<ListNode>, | |
749 | } | |
750 | ``` | |
751 | ||
752 | This type cannot have a well-defined size, because it needs to be arbitrarily | |
753 | large (since we would be able to nest `ListNode`s to any depth). Specifically, | |
754 | ||
755 | ```plain | |
756 | size of `ListNode` = 1 byte for `head` | |
757 | + 1 byte for the discriminant of the `Option` | |
758 | + size of `ListNode` | |
759 | ``` | |
760 | ||
761 | One way to fix this is by wrapping `ListNode` in a `Box`, like so: | |
762 | ||
763 | ``` | |
764 | struct ListNode { | |
765 | head: u8, | |
766 | tail: Option<Box<ListNode>>, | |
767 | } | |
768 | ``` | |
769 | ||
770 | This works because `Box` is a pointer, so its size is well-known. | |
771 | "##, | |
772 | ||
773 | E0073: r##" | |
774 | You cannot define a struct (or enum) `Foo` that requires an instance of `Foo` | |
775 | in order to make a new `Foo` value. This is because there would be no way a | |
776 | first instance of `Foo` could be made to initialize another instance! | |
777 | ||
778 | Here's an example of a struct that has this problem: | |
779 | ||
780 | ``` | |
781 | struct Foo { x: Box<Foo> } // error | |
782 | ``` | |
783 | ||
784 | One fix is to use `Option`, like so: | |
785 | ||
786 | ``` | |
787 | struct Foo { x: Option<Box<Foo>> } | |
788 | ``` | |
789 | ||
790 | Now it's possible to create at least one instance of `Foo`: `Foo { x: None }`. | |
791 | "##, | |
792 | ||
d9579d0f AL |
793 | E0081: r##" |
794 | Enum discriminants are used to differentiate enum variants stored in memory. | |
795 | This error indicates that the same value was used for two or more variants, | |
796 | making them impossible to tell apart. | |
797 | ||
798 | ``` | |
799 | // Good. | |
800 | enum Enum { | |
801 | P, | |
802 | X = 3, | |
803 | Y = 5 | |
804 | } | |
805 | ||
806 | // Bad. | |
807 | enum Enum { | |
808 | P = 3, | |
809 | X = 3, | |
810 | Y = 5 | |
811 | } | |
812 | ``` | |
813 | ||
814 | Note that variants without a manually specified discriminant are numbered from | |
815 | top to bottom starting from 0, so clashes can occur with seemingly unrelated | |
816 | variants. | |
817 | ||
818 | ``` | |
819 | enum Bad { | |
820 | X, | |
821 | Y = 0 | |
822 | } | |
823 | ``` | |
824 | ||
825 | Here `X` will have already been assigned the discriminant 0 by the time `Y` is | |
826 | encountered, so a conflict occurs. | |
827 | "##, | |
828 | ||
829 | E0082: r##" | |
830 | The default type for enum discriminants is `isize`, but it can be adjusted by | |
831 | adding the `repr` attribute to the enum declaration. This error indicates that | |
832 | an integer literal given as a discriminant is not a member of the discriminant | |
833 | type. For example: | |
834 | ||
835 | ``` | |
836 | #[repr(u8)] | |
837 | enum Thing { | |
838 | A = 1024, | |
839 | B = 5 | |
840 | } | |
841 | ``` | |
842 | ||
843 | Here, 1024 lies outside the valid range for `u8`, so the discriminant for `A` is | |
844 | invalid. You may want to change representation types to fix this, or else change | |
845 | invalid discriminant values so that they fit within the existing type. | |
846 | ||
847 | Note also that without a representation manually defined, the compiler will | |
848 | optimize by using the smallest integer type possible. | |
849 | "##, | |
850 | ||
851 | E0083: r##" | |
852 | At present, it's not possible to define a custom representation for an enum with | |
853 | a single variant. As a workaround you can add a `Dummy` variant. | |
854 | ||
855 | See: https://github.com/rust-lang/rust/issues/10292 | |
856 | "##, | |
857 | ||
858 | E0084: r##" | |
859 | It is impossible to define an integer type to be used to represent zero-variant | |
860 | enum values because there are no zero-variant enum values. There is no way to | |
861 | construct an instance of the following type using only safe code: | |
862 | ||
863 | ``` | |
864 | enum Empty {} | |
865 | ``` | |
866 | "##, | |
867 | ||
62682a34 SL |
868 | E0087: r##" |
869 | Too many type parameters were supplied for a function. For example: | |
870 | ||
871 | ``` | |
872 | fn foo<T>() {} | |
873 | ||
874 | fn main() { | |
875 | foo::<f64, bool>(); // error, expected 1 parameter, found 2 parameters | |
876 | } | |
877 | ``` | |
878 | ||
879 | The number of supplied parameters much exactly match the number of defined type | |
880 | parameters. | |
881 | "##, | |
882 | ||
883 | E0089: r##" | |
884 | Not enough type parameters were supplied for a function. For example: | |
885 | ||
886 | ``` | |
887 | fn foo<T, U>() {} | |
888 | ||
889 | fn main() { | |
890 | foo::<f64>(); // error, expected 2 parameters, found 1 parameter | |
891 | } | |
892 | ``` | |
893 | ||
894 | Note that if a function takes multiple type parameters but you want the compiler | |
895 | to infer some of them, you can use type placeholders: | |
896 | ||
897 | ``` | |
898 | fn foo<T, U>(x: T) {} | |
899 | ||
900 | fn main() { | |
901 | let x: bool = true; | |
902 | foo::<f64>(x); // error, expected 2 parameters, found 1 parameter | |
903 | foo::<_, f64>(x); // same as `foo::<bool, f64>(x)` | |
904 | } | |
905 | ``` | |
906 | "##, | |
907 | ||
d9579d0f AL |
908 | E0106: r##" |
909 | This error indicates that a lifetime is missing from a type. If it is an error | |
910 | inside a function signature, the problem may be with failing to adhere to the | |
911 | lifetime elision rules (see below). | |
912 | ||
913 | Here are some simple examples of where you'll run into this error: | |
914 | ||
915 | ``` | |
916 | struct Foo { x: &bool } // error | |
917 | struct Foo<'a> { x: &'a bool } // correct | |
918 | ||
919 | enum Bar { A(u8), B(&bool), } // error | |
920 | enum Bar<'a> { A(u8), B(&'a bool), } // correct | |
921 | ||
922 | type MyStr = &str; // error | |
923 | type MyStr<'a> = &'a str; //correct | |
924 | ||
925 | ``` | |
926 | ||
927 | Lifetime elision is a special, limited kind of inference for lifetimes in | |
928 | function signatures which allows you to leave out lifetimes in certain cases. | |
929 | For more background on lifetime elision see [the book][book-le]. | |
930 | ||
931 | The lifetime elision rules require that any function signature with an elided | |
932 | output lifetime must either have | |
933 | ||
934 | - exactly one input lifetime | |
935 | - or, multiple input lifetimes, but the function must also be a method with a | |
936 | `&self` or `&mut self` receiver | |
937 | ||
938 | In the first case, the output lifetime is inferred to be the same as the unique | |
939 | input lifetime. In the second case, the lifetime is instead inferred to be the | |
940 | same as the lifetime on `&self` or `&mut self`. | |
941 | ||
942 | Here are some examples of elision errors: | |
943 | ||
944 | ``` | |
945 | // error, no input lifetimes | |
946 | fn foo() -> &str { ... } | |
947 | ||
948 | // error, `x` and `y` have distinct lifetimes inferred | |
949 | fn bar(x: &str, y: &str) -> &str { ... } | |
950 | ||
951 | // error, `y`'s lifetime is inferred to be distinct from `x`'s | |
952 | fn baz<'a>(x: &'a str, y: &str) -> &str { ... } | |
953 | ``` | |
954 | ||
955 | [book-le]: http://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision | |
956 | "##, | |
957 | ||
958 | E0107: r##" | |
959 | This error means that an incorrect number of lifetime parameters were provided | |
960 | for a type (like a struct or enum) or trait. | |
961 | ||
962 | Some basic examples include: | |
963 | ||
964 | ``` | |
965 | struct Foo<'a>(&'a str); | |
966 | enum Bar { A, B, C } | |
967 | ||
968 | struct Baz<'a> { | |
969 | foo: Foo, // error: expected 1, found 0 | |
970 | bar: Bar<'a>, // error: expected 0, found 1 | |
971 | } | |
972 | ``` | |
973 | ||
974 | Here's an example that is currently an error, but may work in a future version | |
975 | of Rust: | |
976 | ||
977 | ``` | |
978 | struct Foo<'a>(&'a str); | |
979 | ||
980 | trait Quux { } | |
981 | impl Quux for Foo { } // error: expected 1, found 0 | |
982 | ``` | |
983 | ||
984 | Lifetime elision in implementation headers was part of the lifetime elision | |
985 | RFC. It is, however, [currently unimplemented][iss15872]. | |
986 | ||
987 | [iss15872]: https://github.com/rust-lang/rust/issues/15872 | |
988 | "##, | |
989 | ||
62682a34 SL |
990 | E0116: r##" |
991 | You can only define an inherent implementation for a type in the same crate | |
992 | where the type was defined. For example, an `impl` block as below is not allowed | |
993 | since `Vec` is defined in the standard library: | |
994 | ||
995 | ``` | |
996 | impl Vec<u8> { ... } // error | |
997 | ``` | |
998 | ||
999 | To fix this problem, you can do either of these things: | |
1000 | ||
1001 | - define a trait that has the desired associated functions/types/constants and | |
1002 | implement the trait for the type in question | |
1003 | - define a new type wrapping the type and define an implementation on the new | |
1004 | type | |
1005 | ||
1006 | Note that using the `type` keyword does not work here because `type` only | |
1007 | introduces a type alias: | |
1008 | ||
1009 | ``` | |
1010 | type Bytes = Vec<u8>; | |
1011 | ||
1012 | impl Bytes { ... } // error, same as above | |
1013 | ``` | |
1014 | "##, | |
1015 | ||
1016 | E0121: r##" | |
1017 | In order to be consistent with Rust's lack of global type inference, type | |
1018 | placeholders are disallowed by design in item signatures. | |
1019 | ||
1020 | Examples of this error include: | |
1021 | ||
1022 | ``` | |
1023 | fn foo() -> _ { 5 } // error, explicitly write out the return type instead | |
1024 | ||
1025 | static BAR: _ = "test"; // error, explicitly write out the type instead | |
1026 | ``` | |
1027 | "##, | |
1028 | ||
d9579d0f AL |
1029 | E0131: r##" |
1030 | It is not possible to define `main` with type parameters, or even with function | |
1031 | parameters. When `main` is present, it must take no arguments and return `()`. | |
1032 | "##, | |
1033 | ||
1034 | E0132: r##" | |
1035 | It is not possible to declare type parameters on a function that has the `start` | |
1036 | attribute. Such a function must have the following type signature: | |
1037 | ||
1038 | ``` | |
1039 | fn(isize, *const *const u8) -> isize | |
1040 | ``` | |
1041 | "##, | |
1042 | ||
1043 | E0166: r##" | |
1044 | This error means that the compiler found a return expression in a function | |
1045 | marked as diverging. A function diverges if it has `!` in the place of the | |
1046 | return type in its signature. For example: | |
1047 | ||
1048 | ``` | |
1049 | fn foo() -> ! { return; } // error | |
1050 | ``` | |
1051 | ||
1052 | For a function that diverges, every control path in the function must never | |
1053 | return, for example with a `loop` that never breaks or a call to another | |
1054 | diverging function (such as `panic!()`). | |
1055 | "##, | |
1056 | ||
62682a34 SL |
1057 | E0178: r##" |
1058 | In types, the `+` type operator has low precedence, so it is often necessary | |
1059 | to use parentheses. | |
1060 | ||
1061 | For example: | |
1062 | ||
1063 | ``` | |
1064 | trait Foo {} | |
1065 | ||
1066 | struct Bar<'a> { | |
1067 | w: &'a Foo + Copy, // error, use &'a (Foo + Copy) | |
1068 | x: &'a Foo + 'a, // error, use &'a (Foo + 'a) | |
1069 | y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a) | |
1070 | z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a) | |
1071 | } | |
1072 | ``` | |
1073 | ||
1074 | More details can be found in [RFC 438]. | |
1075 | ||
1076 | [RFC 438]: https://github.com/rust-lang/rfcs/pull/438 | |
1077 | "##, | |
1078 | ||
d9579d0f AL |
1079 | E0184: r##" |
1080 | Explicitly implementing both Drop and Copy for a type is currently disallowed. | |
1081 | This feature can make some sense in theory, but the current implementation is | |
1082 | incorrect and can lead to memory unsafety (see [issue #20126][iss20126]), so | |
1083 | it has been disabled for now. | |
1084 | ||
1085 | [iss20126]: https://github.com/rust-lang/rust/issues/20126 | |
1086 | "##, | |
1087 | ||
62682a34 SL |
1088 | E0185: r##" |
1089 | An associated function for a trait was defined to be static, but an | |
1090 | implementation of the trait declared the same function to be a method (i.e. to | |
1091 | take a `self` parameter). | |
1092 | ||
1093 | Here's an example of this error: | |
1094 | ||
1095 | ``` | |
1096 | trait Foo { | |
1097 | fn foo(); | |
1098 | } | |
1099 | ||
1100 | struct Bar; | |
1101 | ||
1102 | impl Foo for Bar { | |
1103 | // error, method `foo` has a `&self` declaration in the impl, but not in | |
1104 | // the trait | |
1105 | fn foo(&self) {} | |
1106 | } | |
1107 | "##, | |
1108 | ||
1109 | E0186: r##" | |
1110 | An associated function for a trait was defined to be a method (i.e. to take a | |
1111 | `self` parameter), but an implementation of the trait declared the same function | |
1112 | to be static. | |
1113 | ||
1114 | Here's an example of this error: | |
1115 | ||
1116 | ``` | |
1117 | trait Foo { | |
1118 | fn foo(&self); | |
1119 | } | |
1120 | ||
1121 | struct Bar; | |
1122 | ||
1123 | impl Foo for Bar { | |
1124 | // error, method `foo` has a `&self` declaration in the trait, but not in | |
1125 | // the impl | |
1126 | fn foo() {} | |
1127 | } | |
1128 | "##, | |
1129 | ||
1130 | E0192: r##" | |
1131 | Negative impls are only allowed for traits with default impls. For more | |
1132 | information see the [opt-in builtin traits RFC](https://github.com/rust-lang/ | |
1133 | rfcs/blob/master/text/0019-opt-in-builtin-traits.md). | |
1134 | "##, | |
1135 | ||
d9579d0f AL |
1136 | E0197: r##" |
1137 | Inherent implementations (one that do not implement a trait but provide | |
1138 | methods associated with a type) are always safe because they are not | |
1139 | implementing an unsafe trait. Removing the `unsafe` keyword from the inherent | |
1140 | implementation will resolve this error. | |
1141 | ||
1142 | ``` | |
1143 | struct Foo; | |
1144 | ||
1145 | // this will cause this error | |
1146 | unsafe impl Foo { } | |
1147 | // converting it to this will fix it | |
1148 | impl Foo { } | |
1149 | ``` | |
1150 | ||
1151 | "##, | |
1152 | ||
1153 | E0198: r##" | |
1154 | A negative implementation is one that excludes a type from implementing a | |
1155 | particular trait. Not being able to use a trait is always a safe operation, | |
1156 | so negative implementations are always safe and never need to be marked as | |
1157 | unsafe. | |
1158 | ||
1159 | ``` | |
1160 | struct Foo; | |
1161 | ||
1162 | // unsafe is unnecessary | |
1163 | unsafe impl !Clone for Foo { } | |
1164 | // this will compile | |
1165 | impl !Clone for Foo { } | |
1166 | ``` | |
1167 | ||
1168 | "##, | |
1169 | ||
1170 | E0199: r##" | |
1171 | Safe traits should not have unsafe implementations, therefore marking an | |
1172 | implementation for a safe trait unsafe will cause a compiler error. Removing the | |
1173 | unsafe marker on the trait noted in the error will resolve this problem. | |
1174 | ||
1175 | ``` | |
1176 | struct Foo; | |
1177 | ||
1178 | trait Bar { } | |
1179 | ||
1180 | // this won't compile because Bar is safe | |
1181 | unsafe impl Bar for Foo { } | |
1182 | // this will compile | |
1183 | impl Bar for Foo { } | |
1184 | ``` | |
1185 | ||
1186 | "##, | |
1187 | ||
1188 | E0200: r##" | |
1189 | Unsafe traits must have unsafe implementations. This error occurs when an | |
1190 | implementation for an unsafe trait isn't marked as unsafe. This may be resolved | |
1191 | by marking the unsafe implementation as unsafe. | |
1192 | ||
1193 | ``` | |
1194 | struct Foo; | |
1195 | ||
1196 | unsafe trait Bar { } | |
1197 | ||
1198 | // this won't compile because Bar is unsafe and impl isn't unsafe | |
1199 | impl Bar for Foo { } | |
1200 | // this will compile | |
1201 | unsafe impl Bar for Foo { } | |
1202 | ``` | |
1203 | ||
1204 | "##, | |
1205 | ||
1206 | E0201: r##" | |
62682a34 | 1207 | It is an error to define an associated function more than once. |
d9579d0f | 1208 | |
62682a34 | 1209 | For example: |
d9579d0f AL |
1210 | |
1211 | ``` | |
1212 | struct Foo(u8); | |
1213 | ||
1214 | impl Foo { | |
62682a34 SL |
1215 | fn bar(&self) -> bool { self.0 > 5 } |
1216 | ||
1217 | // error: duplicate associated function | |
d9579d0f | 1218 | fn bar() {} |
62682a34 SL |
1219 | } |
1220 | ||
1221 | trait Baz { | |
1222 | fn baz(&self) -> bool; | |
1223 | } | |
1224 | ||
1225 | impl Baz for Foo { | |
1226 | fn baz(&self) -> bool { true } | |
d9579d0f AL |
1227 | |
1228 | // error: duplicate method | |
62682a34 | 1229 | fn baz(&self) -> bool { self.0 > 5 } |
d9579d0f AL |
1230 | } |
1231 | ``` | |
1232 | "##, | |
1233 | ||
62682a34 SL |
1234 | E0202: r##" |
1235 | Inherent associated types were part of [RFC 195] but are not yet implemented. | |
1236 | See [the tracking issue][iss8995] for the status of this implementation. | |
1237 | ||
1238 | [RFC 195]: https://github.com/rust-lang/rfcs/pull/195 | |
1239 | [iss8995]: https://github.com/rust-lang/rust/issues/8995 | |
1240 | "##, | |
1241 | ||
d9579d0f AL |
1242 | E0204: r##" |
1243 | An attempt to implement the `Copy` trait for a struct failed because one of the | |
1244 | fields does not implement `Copy`. To fix this, you must implement `Copy` for the | |
1245 | mentioned field. Note that this may not be possible, as in the example of | |
1246 | ||
1247 | ``` | |
1248 | struct Foo { | |
1249 | foo : Vec<u32>, | |
1250 | } | |
1251 | ||
1252 | impl Copy for Foo { } | |
1253 | ``` | |
1254 | ||
1255 | This fails because `Vec<T>` does not implement `Copy` for any `T`. | |
1256 | ||
1257 | Here's another example that will fail: | |
1258 | ||
1259 | ``` | |
1260 | #[derive(Copy)] | |
1261 | struct Foo<'a> { | |
1262 | ty: &'a mut bool, | |
1263 | } | |
1264 | ``` | |
1265 | ||
1266 | This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this | |
1267 | differs from the behavior for `&T`, which is always `Copy`). | |
1268 | "##, | |
1269 | ||
1270 | E0205: r##" | |
1271 | An attempt to implement the `Copy` trait for an enum failed because one of the | |
1272 | variants does not implement `Copy`. To fix this, you must implement `Copy` for | |
1273 | the mentioned variant. Note that this may not be possible, as in the example of | |
1274 | ||
1275 | ``` | |
1276 | enum Foo { | |
1277 | Bar(Vec<u32>), | |
1278 | Baz, | |
1279 | } | |
1280 | ||
1281 | impl Copy for Foo { } | |
1282 | ``` | |
1283 | ||
1284 | This fails because `Vec<T>` does not implement `Copy` for any `T`. | |
1285 | ||
1286 | Here's another example that will fail: | |
1287 | ||
1288 | ``` | |
1289 | #[derive(Copy)] | |
1290 | enum Foo<'a> { | |
1291 | Bar(&'a mut bool), | |
1292 | Baz | |
1293 | } | |
1294 | ``` | |
1295 | ||
1296 | This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this | |
1297 | differs from the behavior for `&T`, which is always `Copy`). | |
1298 | "##, | |
1299 | ||
1300 | E0206: r##" | |
1301 | You can only implement `Copy` for a struct or enum. Both of the following | |
1302 | examples will fail, because neither `i32` (primitive type) nor `&'static Bar` | |
1303 | (reference to `Bar`) is a struct or enum: | |
1304 | ||
1305 | ``` | |
1306 | type Foo = i32; | |
1307 | impl Copy for Foo { } // error | |
1308 | ||
1309 | #[derive(Copy, Clone)] | |
1310 | struct Bar; | |
1311 | impl Copy for &'static Bar { } // error | |
1312 | ``` | |
1313 | "##, | |
1314 | ||
1315 | E0243: r##" | |
1316 | This error indicates that not enough type parameters were found in a type or | |
1317 | trait. | |
1318 | ||
1319 | For example, the `Foo` struct below is defined to be generic in `T`, but the | |
1320 | type parameter is missing in the definition of `Bar`: | |
1321 | ||
1322 | ``` | |
1323 | struct Foo<T> { x: T } | |
1324 | ||
1325 | struct Bar { x: Foo } | |
1326 | ``` | |
1327 | "##, | |
1328 | ||
1329 | E0244: r##" | |
1330 | This error indicates that too many type parameters were found in a type or | |
1331 | trait. | |
1332 | ||
1333 | For example, the `Foo` struct below has no type parameters, but is supplied | |
1334 | with two in the definition of `Bar`: | |
1335 | ||
1336 | ``` | |
1337 | struct Foo { x: bool } | |
1338 | ||
1339 | struct Bar<S, T> { x: Foo<S, T> } | |
1340 | ``` | |
1341 | "##, | |
1342 | ||
1343 | E0249: r##" | |
1344 | This error indicates a constant expression for the array length was found, but | |
1345 | it was not an integer (signed or unsigned) expression. | |
1346 | ||
1347 | Some examples of code that produces this error are: | |
1348 | ||
1349 | ``` | |
1350 | const A: [u32; "hello"] = []; // error | |
1351 | const B: [u32; true] = []; // error | |
1352 | const C: [u32; 0.0] = []; // error | |
1353 | "##, | |
1354 | ||
1355 | E0250: r##" | |
62682a34 SL |
1356 | There was an error while evaluating the expression for the length of a fixed- |
1357 | size array type. | |
d9579d0f | 1358 | |
62682a34 | 1359 | Some examples of this error are: |
d9579d0f AL |
1360 | |
1361 | ``` | |
1362 | // divide by zero in the length expression | |
1363 | const A: [u32; 1/0] = []; | |
1364 | ||
1365 | // Rust currently will not evaluate the function `foo` at compile time | |
1366 | fn foo() -> usize { 12 } | |
1367 | const B: [u32; foo()] = []; | |
1368 | ||
1369 | // it is an error to try to add `u8` and `f64` | |
1370 | use std::{f64, u8}; | |
1371 | const C: [u32; u8::MAX + f64::EPSILON] = []; | |
1372 | ``` | |
1373 | "##, | |
1374 | ||
62682a34 SL |
1375 | E0318: r##" |
1376 | Default impls for a trait must be located in the same crate where the trait was | |
1377 | defined. For more information see the [opt-in builtin traits RFC](https://github | |
1378 | .com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md). | |
1379 | "##, | |
1380 | ||
d9579d0f AL |
1381 | E0322: r##" |
1382 | The `Sized` trait is a special trait built-in to the compiler for types with a | |
1383 | constant size known at compile-time. This trait is automatically implemented | |
1384 | for types as needed by the compiler, and it is currently disallowed to | |
1385 | explicitly implement it for a type. | |
1386 | "##, | |
1387 | ||
62682a34 SL |
1388 | E0326: r##" |
1389 | The types of any associated constants in a trait implementation must match the | |
1390 | types in the trait definition. This error indicates that there was a mismatch. | |
1391 | ||
1392 | Here's an example of this error: | |
1393 | ||
1394 | ``` | |
1395 | trait Foo { | |
1396 | const BAR: bool; | |
1397 | } | |
1398 | ||
1399 | struct Bar; | |
1400 | ||
1401 | impl Foo for Bar { | |
1402 | const BAR: u32 = 5; // error, expected bool, found u32 | |
1403 | } | |
1404 | ``` | |
1405 | "##, | |
1406 | ||
d9579d0f AL |
1407 | E0368: r##" |
1408 | This error indicates that a binary assignment operator like `+=` or `^=` was | |
62682a34 | 1409 | applied to the wrong types. For example: |
d9579d0f AL |
1410 | |
1411 | ``` | |
1412 | let mut x: u16 = 5; | |
1413 | x ^= true; // error, `^=` cannot be applied to types `u16` and `bool` | |
1414 | x += (); // error, `+=` cannot be applied to types `u16` and `()` | |
1415 | ``` | |
1416 | ||
1417 | Another problem you might be facing is this: suppose you've overloaded the `+` | |
1418 | operator for some type `Foo` by implementing the `std::ops::Add` trait for | |
1419 | `Foo`, but you find that using `+=` does not work, as in this example: | |
1420 | ||
1421 | ``` | |
1422 | use std::ops::Add; | |
1423 | ||
1424 | struct Foo(u32); | |
1425 | ||
1426 | impl Add for Foo { | |
1427 | type Output = Foo; | |
1428 | ||
1429 | fn add(self, rhs: Foo) -> Foo { | |
1430 | Foo(self.0 + rhs.0) | |
1431 | } | |
1432 | } | |
1433 | ||
1434 | fn main() { | |
1435 | let mut x: Foo = Foo(5); | |
1436 | x += Foo(7); // error, `+= cannot be applied to types `Foo` and `Foo` | |
1437 | } | |
1438 | ``` | |
1439 | ||
1440 | This is because the binary assignment operators currently do not work off of | |
1441 | traits, so it is not possible to overload them. See [RFC 953] for a proposal | |
1442 | to change this. | |
1443 | ||
1444 | [RFC 953]: https://github.com/rust-lang/rfcs/pull/953 | |
62682a34 SL |
1445 | "##, |
1446 | ||
1447 | E0371: r##" | |
1448 | When `Trait2` is a subtrait of `Trait1` (for example, when `Trait2` has a | |
1449 | definition like `trait Trait2: Trait1 { ... }`), it is not allowed to implement | |
1450 | `Trait1` for `Trait2`. This is because `Trait2` already implements `Trait1` by | |
1451 | definition, so it is not useful to do this. | |
1452 | ||
1453 | Example: | |
1454 | ||
1455 | ``` | |
1456 | trait Foo { fn foo(&self) { } } | |
1457 | trait Bar: Foo { } | |
1458 | trait Baz: Bar { } | |
1459 | ||
1460 | impl Bar for Baz { } // error, `Baz` implements `Bar` by definition | |
1461 | impl Foo for Baz { } // error, `Baz` implements `Bar` which implements `Foo` | |
1462 | impl Baz for Baz { } // error, `Baz` (trivially) implements `Baz` | |
1463 | impl Baz for Bar { } // Note: This is OK | |
1464 | ``` | |
1465 | "##, | |
1466 | ||
1467 | E0372: r##" | |
1468 | Trying to implement a trait for a trait object (as in `impl Trait1 for | |
1469 | Trait2 { ... }`) does not work if the trait is not object-safe. Please see the | |
1470 | [RFC 255] for more details on object safety rules. | |
1471 | ||
1472 | [RFC 255]: https://github.com/rust-lang/rfcs/pull/255 | |
1473 | "##, | |
1474 | ||
1475 | E0379: r##" | |
1476 | Trait methods cannot be declared `const` by design. For more information, see | |
1477 | [RFC 911]. | |
1478 | ||
1479 | [RFC 911]: https://github.com/rust-lang/rfcs/pull/911 | |
1480 | "##, | |
1481 | ||
1482 | E0380: r##" | |
1483 | Default impls are only allowed for traits with no methods or associated items. | |
1484 | For more information see the [opt-in builtin traits RFC](https://github.com/rust | |
1485 | -lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md). | |
d9579d0f AL |
1486 | "## |
1487 | ||
1488 | } | |
1489 | ||
1a4d82fc | 1490 | register_diagnostics! { |
d9579d0f | 1491 | E0044, // foreign items may not have type parameters |
1a4d82fc | 1492 | E0068, |
1a4d82fc | 1493 | E0071, |
1a4d82fc JJ |
1494 | E0074, |
1495 | E0075, | |
1496 | E0076, | |
1497 | E0077, | |
1a4d82fc JJ |
1498 | E0085, |
1499 | E0086, | |
1a4d82fc | 1500 | E0088, |
1a4d82fc JJ |
1501 | E0090, |
1502 | E0091, | |
1503 | E0092, | |
1504 | E0093, | |
1505 | E0094, | |
1a4d82fc JJ |
1506 | E0101, |
1507 | E0102, | |
1508 | E0103, | |
1509 | E0104, | |
1a4d82fc JJ |
1510 | E0117, |
1511 | E0118, | |
1512 | E0119, | |
1513 | E0120, | |
1a4d82fc | 1514 | E0122, |
c34b1796 | 1515 | E0123, |
1a4d82fc JJ |
1516 | E0124, |
1517 | E0127, | |
1518 | E0128, | |
1519 | E0129, | |
1520 | E0130, | |
1a4d82fc | 1521 | E0141, |
1a4d82fc | 1522 | E0159, |
1a4d82fc JJ |
1523 | E0163, |
1524 | E0164, | |
1a4d82fc JJ |
1525 | E0167, |
1526 | E0168, | |
1a4d82fc JJ |
1527 | E0172, |
1528 | E0173, // manual implementations of unboxed closure traits are experimental | |
1529 | E0174, // explicit use of unboxed closure methods are experimental | |
1a4d82fc JJ |
1530 | E0182, |
1531 | E0183, | |
85aaf69f | 1532 | E0187, // can't infer the kind of the closure |
62682a34 SL |
1533 | E0188, // can not cast a immutable reference to a mutable pointer |
1534 | E0189, // deprecated: can only cast a boxed pointer to a boxed object | |
1535 | E0190, // deprecated: can only cast a &-pointer to an &-object | |
85aaf69f | 1536 | E0191, // value of the associated type must be specified |
85aaf69f SL |
1537 | E0193, // cannot bound type where clause bounds may only be attached to types |
1538 | // involving type parameters | |
1539 | E0194, | |
1540 | E0195, // lifetime parameters or bounds on method do not match the trait declaration | |
1541 | E0196, // cannot determine a type for this closure | |
85aaf69f SL |
1542 | E0203, // type parameter has more than one relaxed default bound, |
1543 | // and only one is supported | |
85aaf69f SL |
1544 | E0207, // type parameter is not constrained by the impl trait, self type, or predicate |
1545 | E0208, | |
1546 | E0209, // builtin traits can only be implemented on structs or enums | |
1547 | E0210, // type parameter is not constrained by any local type | |
1548 | E0211, | |
1549 | E0212, // cannot extract an associated type from a higher-ranked trait bound | |
1550 | E0213, // associated types are not accepted in this context | |
1551 | E0214, // parenthesized parameters may only be used with a trait | |
1552 | E0215, // angle-bracket notation is not stable with `Fn` | |
1553 | E0216, // parenthetical notation is only stable with `Fn` | |
1554 | E0217, // ambiguous associated type, defined in multiple supertraits | |
1555 | E0218, // no associated type defined | |
1556 | E0219, // associated type defined in higher-ranked supertrait | |
1557 | E0220, // associated type not found for type parameter | |
1558 | E0221, // ambiguous associated type in bounds | |
62682a34 SL |
1559 | //E0222, // Error code E0045 (variadic function must have C calling |
1560 | // convention) duplicate | |
85aaf69f SL |
1561 | E0223, // ambiguous associated type |
1562 | E0224, // at least one non-builtin train is required for an object type | |
1563 | E0225, // only the builtin traits can be used as closure or object bounds | |
1564 | E0226, // only a single explicit lifetime bound is permitted | |
1565 | E0227, // ambiguous lifetime bound, explicit lifetime bound required | |
1566 | E0228, // explicit lifetime bound required | |
1567 | E0229, // associated type bindings are not allowed here | |
1568 | E0230, // there is no type parameter on trait | |
1569 | E0231, // only named substitution parameters are allowed | |
1570 | E0232, // this attribute must have a value | |
1571 | E0233, | |
d9579d0f | 1572 | E0234, |
85aaf69f SL |
1573 | E0235, // structure constructor specifies a structure of type but |
1574 | E0236, // no lang item for range syntax | |
1575 | E0237, // no lang item for range syntax | |
1576 | E0238, // parenthesized parameters may only be used with a trait | |
1577 | E0239, // `next` method of `Iterator` trait has unexpected type | |
1578 | E0240, | |
1579 | E0241, | |
1580 | E0242, // internal error looking up a definition | |
85aaf69f SL |
1581 | E0245, // not a trait |
1582 | E0246, // illegal recursive type | |
1583 | E0247, // found module name used as a type | |
1584 | E0248, // found value name used as a type | |
c34b1796 AL |
1585 | E0319, // trait impls for defaulted traits allowed just for structs/enums |
1586 | E0320, // recursive overflow during dropck | |
1587 | E0321, // extended coherence rules for defaulted traits violated | |
d9579d0f AL |
1588 | E0323, // implemented an associated const when another trait item expected |
1589 | E0324, // implemented a method when another trait item expected | |
1590 | E0325, // implemented an associated type when another trait item expected | |
d9579d0f AL |
1591 | E0327, // referred to method instead of constant in match pattern |
1592 | E0328, // cannot implement Unsize explicitly | |
62682a34 | 1593 | E0329, // associated const depends on type parameter or Self. |
c34b1796 AL |
1594 | E0366, // dropck forbid specialization to concrete type or region |
1595 | E0367, // dropck forbid specialization to predicate not in struct/enum | |
9346a6ac | 1596 | E0369, // binary operation `<op>` cannot be applied to types |
d9579d0f AL |
1597 | E0374, // the trait `CoerceUnsized` may only be implemented for a coercion |
1598 | // between structures with one field being coerced, none found | |
1599 | E0375, // the trait `CoerceUnsized` may only be implemented for a coercion | |
1600 | // between structures with one field being coerced, but multiple | |
1601 | // fields need coercions | |
1602 | E0376, // the trait `CoerceUnsized` may only be implemented for a coercion | |
1603 | // between structures | |
62682a34 | 1604 | E0377, // the trait `CoerceUnsized` may only be implemented for a coercion |
d9579d0f | 1605 | // between structures with the same definition |
62682a34 SL |
1606 | E0390, // only a single inherent implementation marked with |
1607 | // `#[lang = \"{}\"]` is allowed for the `{}` primitive | |
1608 | E0391, // unsupported cyclic reference between types/traits detected | |
1609 | E0392, // parameter `{}` is never used | |
1610 | E0393 // the type parameter `{}` must be explicitly specified in an object | |
1611 | // type because its default value `{}` references the type `Self`" | |
1a4d82fc | 1612 | } |