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
175 changes: 166 additions & 9 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,102 @@ 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`
}
```

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 {}
// or:
trait Foo {
type N;

fn bar(Self::N);
}
```
"##,

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, make sure declarations do not shadow any enum variants or
structures in the scope. Please also verify that neither name was misspelled.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think talking about misspelling is appropriate here - after all, the problem is an accidental match. Maybe "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!
}
```
"##,

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

Expand Down Expand Up @@ -425,6 +521,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 +727,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 +815,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
}
31 changes: 30 additions & 1 deletion src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,36 @@ fn main() {
```
"##,

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

```
fn main() {
let x: &_; // error: cannot determine a type for this local variable
}
```

You have two possibilities to solve this situation:
* Give an explicit definition of the variable
* Infer the variable
Copy link
Member

Choose a reason for hiding this comment

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

This is an error about compiler being unable to infer the type. This makes no sense to suggest inferring it as a solution.

Copy link
Member Author

Choose a reason for hiding this comment

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

Inferring a variable by passing it to a context with a defined type is what I (and @Manishearth) had in mind.

Copy link
Member

Choose a reason for hiding this comment

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

Then:

“Help the compiler to infer the variable” or somehing.


Basically to infer a variable an explicit type definition has to occur somewhere anyway (even if it is in a function parameter list; notable exception being integral variables which have a default of i32), so I don’t see much reason to add this alternative.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it is inferring since we didn't directly defined the variable. ;)

Copy link
Contributor

Choose a reason for hiding this comment

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

this should be changed (e.g. "constrain the type of the variable", maybe an example involving collect - actually that ends up causing E0282 for "doesn't implement Sized", but still).

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, what exactly do you want ? You're loosing me here ^^'


Examples:

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

fn main() {
let x = 0u32; // ok!
// or:
let x = 0;
some_func(x);
}
```
"##,

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 +2333,6 @@ register_diagnostics! {
E0085,
E0086,
E0090,
E0102,
E0103,
E0104,
E0118,
Expand Down