Skip to content

Commit 4b52059

Browse files
author
Nick Hamann
committed
Add error explanations for E0049, E0050, E0069, E0106, E0107, E0166.
1 parent a90453a commit 4b52059

File tree

2 files changed

+181
-7
lines changed

2 files changed

+181
-7
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3268,7 +3268,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
32683268
if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
32693269
result_type, ty::mk_nil(fcx.tcx())) {
32703270
span_err!(tcx.sess, expr.span, E0069,
3271-
"`return;` in function returning non-nil");
3271+
"`return;` in a function whose return type is \
3272+
not `()`");
32723273
},
32733274
Some(ref e) => {
32743275
check_expr_coercable_to_type(fcx, &**e, result_type);

src/librustc_typeck/diagnostics.rs

Lines changed: 179 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,51 @@ methods that do not have default implementations), as well as any required
1919
trait items like associated types or constants.
2020
"##,
2121

22+
E0049: r##"
23+
This error indicates that an attempted implementation of a trait method
24+
has the wrong number of type parameters.
25+
26+
For example, the trait below has a method `foo` with a type parameter `T`,
27+
but the implementation of `foo` for the type `Bar` is missing this parameter:
28+
29+
```
30+
trait Foo {
31+
fn foo<T: Default>(T) -> Self;
32+
}
33+
34+
struct Bar;
35+
36+
// error: method `foo` has 0 type parameters but its trait declaration has 1
37+
// type parameter
38+
impl Foo for Bar {
39+
fn foo(x: bool) -> Self { Bar }
40+
}
41+
```
42+
"##,
43+
44+
E0050: r##"
45+
This error indicates that an attempted implementation of a trait method
46+
has the wrong number of function parameters.
47+
48+
For example, the trait below has a method `foo` with two function parameters
49+
(`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits
50+
the `u8` parameter:
51+
52+
```
53+
trait Foo {
54+
fn foo(&self, u8) -> bool;
55+
}
56+
57+
struct Bar;
58+
59+
// error: method `foo` has 1 parameter but the declaration in trait `Foo::foo`
60+
// has 2
61+
impl Foo for Bar {
62+
fn foo(&self) -> bool { true }
63+
}
64+
```
65+
"##,
66+
2267
E0054: r##"
2368
It is not allowed to cast to a bool. If you are trying to cast a numeric type
2469
to a bool, you can compare it with zero instead:
@@ -63,6 +108,22 @@ LinkedList::new() += 1;
63108
```
64109
"##,
65110

111+
E0069: r##"
112+
This error means that the compiler found a function whose body contains a
113+
`return;` statement but whose return type is not `()`. For example:
114+
115+
```
116+
// error
117+
fn foo() -> u8 {
118+
return;
119+
}
120+
```
121+
122+
When you omit the value from a `return` expression (that is, when you use
123+
`return;` instead of `return x;`), the value `()` gets returned. So `return;`
124+
is always incorrect for a function whose return type is not `()`.
125+
"##,
126+
66127
E0081: r##"
67128
Enum discriminants are used to differentiate enum variants stored in memory.
68129
This error indicates that the same value was used for two or more variants,
@@ -138,6 +199,110 @@ enum Empty {}
138199
```
139200
"##,
140201

202+
E0106: r##"
203+
This error indicates that a lifetime is missing from a type. If it is an error
204+
inside a function signature, the problem may be with failing to adhere to the
205+
lifetime elision rules (see below).
206+
207+
Here are some simple examples of where you'll run into this error:
208+
209+
```
210+
struct Foo { x: &bool } // error
211+
struct Foo<'a> { x: &'a bool } // correct
212+
213+
enum Bar { A(u8), B(&bool), } // error
214+
enum Bar<'a> { A(u8), B(&'a bool), } // correct
215+
216+
type MyStr = &str; // error
217+
type MyStr<'a> = &'a str; //correct
218+
219+
```
220+
221+
Lifetime elision is a special, limited kind of inference for lifetimes in
222+
function signatures which allows you to leave out lifetimes in certain cases.
223+
For example, the lifetimes on parameter in the following function signatures
224+
have been left out, but they still compile successfully:
225+
226+
```
227+
fn foo(x: &str) { }
228+
229+
fn bar(x: &str, y: &str) { }
230+
231+
fn baz(x: &str) -> &str { x }
232+
```
233+
234+
To explain the lifetime elision rules, we need to first discuss some background.
235+
The lifetime elision rules consider each lifetime in a function signature,
236+
whether it's elided or not, to be in a certain position, either *input
237+
position*, for function parameters, or *output position*, for the return type.
238+
For example, the function:
239+
240+
```
241+
fn hello<'a>(name: &'a str) -> (&'static str, &str) {
242+
("hello", name)
243+
}
244+
```
245+
246+
has a signature with one lifetime in input position and two lifetimes in output
247+
position.
248+
249+
The lifetime elision rules require that any function signature with an elided
250+
output lifetime must either have
251+
252+
- exactly one input lifetime
253+
- or, multiple input lifetimes, but the function must also be a method with a
254+
`&self` or `&mut self` receiver
255+
256+
In the first case, the output lifetime is inferred to be the same as the unique
257+
input lifetime. In the second case, the lifetime is instead inferred to be the
258+
same as the lifetime on `&self` or `&mut self`.
259+
260+
Here are some examples of elision errors:
261+
262+
```
263+
// error, no input lifetimes
264+
fn foo() -> &str { ... }
265+
266+
// error, `x` and `y` have distinct lifetimes inferred
267+
fn bar(x: &str, y: &str) -> &str { ... }
268+
269+
// error, `y`'s lifetime is inferred to be distinct from `x`'s
270+
fn baz<'a>(x: &'a str, y: &str) -> &str { ... }
271+
```
272+
"##,
273+
274+
E0107: r##"
275+
This error means that an incorrect number of lifetime parameters were provided
276+
for a type (like a struct or enum) or trait.
277+
278+
Some basic examples include:
279+
280+
```
281+
struct Foo<'a>(&'a str);
282+
enum Bar { A, B, C }
283+
284+
struct Baz<'a> {
285+
foo: Foo, // error: expected 1, found 0
286+
bar: Bar<'a>, // error: expected 0, found 1
287+
}
288+
```
289+
290+
Here's an example that is currently an error, but may work in a future version
291+
of Rust:
292+
293+
```
294+
struct Foo<'a>(&'a str);
295+
296+
trait Quux { }
297+
impl Quux for Foo { } // error: expected 1, found 0
298+
```
299+
300+
Lifetime elision in implementation headers was part of the lifetime elision
301+
RFC. It is, however, [currently unimplemented][iss15872].
302+
303+
[iss15872]: https://github.com/rust-lang/rust/issues/15872
304+
"##,
305+
141306
E0131: r##"
142307
It is not possible to define `main` with type parameters, or even with function
143308
parameters. When `main` is present, it must take no arguments and return `()`.
@@ -152,6 +317,20 @@ fn(isize, *const *const u8) -> isize
152317
```
153318
"##,
154319

320+
E0166: r##"
321+
This error means that the compiler found a return expression in a function
322+
marked as diverging. A function diverges if it has `!` in the place of the
323+
return type in its signature. For example:
324+
325+
```
326+
fn foo() -> ! { return; } // error
327+
```
328+
329+
For a function that diverges, every control path in the function must end
330+
with a call to `panic!()` or another diverging function. Attempting to return
331+
from a diverging function is an error.
332+
"##,
333+
155334
E0184: r##"
156335
Explicitly implementing both Drop and Copy for a type is currently disallowed.
157336
This feature can make some sense in theory, but the current implementation is
@@ -313,8 +492,6 @@ register_diagnostics! {
313492
E0040, // explicit use of destructor method
314493
E0044, // foreign items may not have type parameters
315494
E0045, // variadic function must have C calling convention
316-
E0049,
317-
E0050,
318495
E0053,
319496
E0055, // method has an incompatible type for trait
320497
E0057, // method has an incompatible type for trait
@@ -323,7 +500,6 @@ register_diagnostics! {
323500
E0061,
324501
E0066,
325502
E0068,
326-
E0069,
327503
E0070,
328504
E0071,
329505
E0072,
@@ -346,8 +522,6 @@ register_diagnostics! {
346522
E0102,
347523
E0103,
348524
E0104,
349-
E0106,
350-
E0107,
351525
E0116,
352526
E0117,
353527
E0118,
@@ -365,7 +539,6 @@ register_diagnostics! {
365539
E0159,
366540
E0163,
367541
E0164,
368-
E0166,
369542
E0167,
370543
E0168,
371544
E0172,

0 commit comments

Comments
 (0)