Skip to content

Add E0102, E0412, E0413, E0415, E0416, E0419, E0423 and E0435 error explanation #27378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Aug 7, 2015
Merged
187 changes: 178 additions & 9 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,114 @@ impl Bar {
```
"##,

E0412: r##"
An undeclared type name was used. Example of erroneous codes:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to say something about generics, e.g. fn foo(x: T) {} needing to be fn foo<T>(x: T) {}.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done !


```
impl Something {} // error: use of undeclared type name `Something`
// or:
trait Foo {
fn bar(N); // error: use of undeclared type name `N`
}
// or:
fn foo(x: T) {} // error: use of undeclared type name `T`
```

To fix this error, please verify you didn't misspell the type name,
you did declare it or imported it into the scope. Examples:

```
struct Something;

impl Something {} // ok!
// or:
trait Foo {
type N;

fn bar(Self::N); // ok!
}
//or:
fn foo<T>(x: T) {} // ok!
```
"##,

E0413: r##"
A declaration shadows an enum variant or unit-like struct in scope.
Example of erroneous code:

```
struct Foo;

let Foo = 12i32; // error: declaration of `Foo` shadows an enum variant or
// unit-like struct in scope
```


To fix this error, rename the variable such that it doesn't shadow any enum
variable or structure in scope. Example:

```
struct Foo;

let foo = 12i32; // ok!
```

Or:

```
struct FooStruct;

let Foo = 12i32; // ok!
```

The goal here is to avoid a conflict of names.
"##,

E0415: r##"
More than one function parameter have the same name. Example of erroneous
code:

```
fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than
// once in this parameter list
```

Please verify you didn't misspell parameters' name. Example:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again misspelling isn't exactly right there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I'll leave it like this. :)


```
fn foo(f: i32, g: i32) {} // ok!
```
"##,

E0416: r##"
An identifier is bound more than once in a pattern. Example of erroneous
code:

```
match (1, 2) {
(x, x) => {} // error: identifier `x` is bound more than once in the
// same pattern
}
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "did you mean to unify? consider using a guard".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure to follow you here...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GuillaumeGomez some people, when first using pattern-matching, think that they can write

match (A, B, C) {
    (x, x, see) => { /* A and B are equal, do one thing */ }
    (y, z, see) => { /* A and B unequal; do another thing */ }
}

There are programming languages (e.g. logic PL's like Prolog) that support the above. But Rust is not one of them.

So @arielb1 is suggesting that if someone is using the same identifier more than once, they might be trying "unify" the two parts; i.e., make the pattern predicated on those two parts being equal.

A way to encode this in Rust is to use two distinct identifiers, and then add a guard to the pattern so that the arm fires only if the two identifiers are actually bound to equal values, like so:

match (A, B, C) {
    (x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ }
    (y, z, see) => { /* A and B unequal; do another thing */ }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh okay ! I was totally away from this. I add a precision and an example then !

Please verify you didn't misspell identifiers' name. Example:

```
match (1, 2) {
(x, y) => {} // ok!
}
```

Or maybe did you mean to unify? Consider using a guard:

```
match (A, B, C) {
(x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ }
(y, z, see) => { /* A and B unequal; do another thing */ }
}
```
"##,

E0417: r##"
A static variable was referenced in a pattern. Example of erroneous code:

Expand Down Expand Up @@ -425,6 +533,55 @@ match 0 {
```
"##,

E0419: r##"
An unknown enum variant, struct or const was used. Example of
erroneous code:

```
match 0 {
Something::Foo => {} // error: unresolved enum variant, struct
// or const `Foo`
}
```

Please verify you didn't misspell it and the enum variant, struct or const has
been declared and imported into scope. Example:

```
enum Something {
Foo,
NotFoo,
}

match Something::NotFoo {
Something::Foo => {} // ok!
_ => {}
}
```
"##,

E0423: r##"
A `struct` variant name was used like a function name. Example of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct “variant”? Interestingly it was called so by yourself in c5f7c19. Stable and beta emit a better error message in this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should I change it or not ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m fine with merging this as it is currently and changing the explanation in the PR which updates the error message.

erroneous code:

```
struct Foo { a: bool};

let f = Foo();
// error: `Foo` is a struct variant name, but this expression uses
// it like a function name
```

Please verify you didn't misspell the name of what you actually wanted
to use here. Example:

```
fn Foo() -> u32 { 0 }

let f = Foo(); // ok!
```
"##,

E0424: r##"
The `self` keyword was used in a static method. Example of erroneous code:

Expand Down Expand Up @@ -582,6 +739,27 @@ use something_which_doesnt_exist;
Please verify you didn't misspell the import's name.
"##,

E0435: r##"
A non-constant value was used to initialise a constant. Example of erroneous
code:

```
let foo = 42u32;
const FOO : u32 = foo; // error: attempt to use a non-constant value in a
// constant
```

To fix this error, please replace the value with a constant. Example:

```
const FOO : u32 = 42u32; // ok!

// or:
const OTHER_FOO : u32 = 42u32;
const FOO : u32 = OTHER_FOO; // ok!
```
"##,

E0437: r##"
Trait impls can only implement associated types that are members of the trait in
question. This error indicates that you attempted to implement an associated
Expand Down Expand Up @@ -649,21 +827,12 @@ register_diagnostics! {
// pattern #1
E0410, // variable from pattern is not bound in pattern 1
E0411, // use of `Self` outside of an impl or trait
E0412, // use of undeclared
E0413, // declaration of shadows an enum variant or unit-like struct in
// scope
E0414, // only irrefutable patterns allowed here
E0415, // identifier is bound more than once in this parameter list
E0416, // identifier is bound more than once in the same pattern
E0418, // is not an enum variant, struct or const
E0419, // unresolved enum variant, struct or const
E0420, // is not an associated const
E0421, // unresolved associated const
E0422, // does not name a structure
E0423, // is a struct variant name, but this expression uses it like a
// function name
E0427, // cannot use `ref` binding mode with ...
E0429, // `self` imports are only allowed within a { } list
E0434, // can't capture dynamic environment in a fn item
E0435, // attempt to use a non-constant value in a constant
}
43 changes: 42 additions & 1 deletion src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,48 @@ fn main() {
```
"##,

E0102: r##"
You hit this error because the compiler lacks information to
determine a type for this variable. Erroneous code example:

```
fn demo(devil: fn () -> !) {
let x: &_ = devil();
// error: cannot determine a type for this local variable
}

fn oh_no() -> ! { panic!("the devil is in the details") }

fn main() {
demo(oh_no);
}
```

To solve this situation, constrain the type of the variable.
Examples:

```
fn some_func(x: &u32) {
// some code
}

fn demo(devil: fn () -> !) {
let x: &u32 = devil();
// Here we defined the type at the variable creation

let x: &_ = devil();
some_func(x);
// Here, the type is determined by the function argument type
}

fn oh_no() -> ! { panic!("the devil is in the details") }

fn main() {
demo(oh_no);
}
```
"##,

E0106: r##"
This error indicates that a lifetime is missing from a type. If it is an error
inside a function signature, the problem may be with failing to adhere to the
Expand Down Expand Up @@ -2303,7 +2345,6 @@ register_diagnostics! {
E0085,
E0086,
E0090,
E0102,
E0103,
E0104,
E0118,
Expand Down