Skip to content

Commit 9d5e621

Browse files
committed
Rollup merge of #25590 - michaelsproul:enum-struct-diagnostics, r=Manishearth
Part of #24407. This covers various errors to do with struct and enum patterns.
2 parents f389662 + eccb72e commit 9d5e621

File tree

1 file changed

+158
-6
lines changed

1 file changed

+158
-6
lines changed

src/librustc_typeck/diagnostics.rs

+158-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,164 @@
1212

1313
register_long_diagnostics! {
1414

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+
E0033: r##"
150+
This error indicates that a pointer to a trait type cannot be implicitly
151+
dereferenced by a pattern. Every trait defines a type, but because the
152+
size of trait implementors isn't fixed, this type has no compile-time size.
153+
Therefore, all accesses to trait types must be through pointers. If you
154+
encounter this error you should try to avoid dereferencing the pointer.
155+
156+
```
157+
let trait_obj: &SomeTrait = ...;
158+
159+
// This tries to implicitly dereference to create an unsized local variable.
160+
let &invalid = trait_obj;
161+
162+
// You can call methods without binding to the value being pointed at.
163+
trait_obj.method_one();
164+
trait_obj.method_two();
165+
```
166+
167+
You can read more about trait objects in the Trait Object section of the
168+
Reference:
169+
170+
http://doc.rust-lang.org/reference.html#trait-objects
171+
"##,
172+
15173
E0046: r##"
16174
When trying to make some type implement a trait `Foo`, you must, at minimum,
17175
provide implementations for all of `Foo`'s required methods (meaning the
@@ -758,15 +916,9 @@ safety.md
758916
}
759917

760918
register_diagnostics! {
761-
E0023,
762-
E0024,
763-
E0025,
764-
E0026,
765-
E0027,
766919
E0029,
767920
E0030,
768921
E0031,
769-
E0033,
770922
E0034, // multiple applicable methods in scope
771923
E0035, // does not take type parameters
772924
E0036, // incorrect number of type parameters given for this method

0 commit comments

Comments
 (0)