Skip to content

Add 8 more error explanations. #25398

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 4 commits into from
May 14, 2015
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 84 additions & 6 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,88 @@ about what constitutes an Item declaration and what does not:
http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
pub struct baz;
}

mod bar {
pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
pub struct baz;
}

mod bar {
pub mod baz {}
}
```
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use foo::FOO; // error, do `use foo::FOO as BAR` instead
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this could be something like

use bar::foo;

fn foo() {}

mod bar {
     pub fn foo() {}
}

(I just find the upper-case FOO slightly strange.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, that's a much better.


fn FOO() {}

mod foo {
pub const FOO: bool = true;
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

struct Bar;
Copy link
Member

Choose a reason for hiding this comment

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

unit structs put a name into both the value and type namespace.

Since each of these examples seems to be trying to illustrate each specific conflict, it might be better to use an example that only inserts into the type namespace. A non-unit struct would work for that, but I think type Bar = u32; would work too, and might be even clearer.

(But, just to be clear: No need to block landing this PR on this suggestion alone.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, great point.


mod foo {
pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.
Expand Down Expand Up @@ -122,14 +204,10 @@ http://doc.rust-lang.org/reference.html#types
register_diagnostics! {
E0157,
E0153,
E0251, // a named type or value has already been imported in this module
E0252, // a named type or value has already been imported in this module
E0253, // not directly importable
E0254, // import conflicts with imported crate in this module
E0255, // import conflicts with value in this module
E0256, // import conflicts with type in this module
E0257, // inherent implementations are only allowed on types defined in the current module
E0258, // import conflicts with existing submodule
E0257,
E0258,
E0364, // item is private
E0365 // item is private
}
9 changes: 5 additions & 4 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3082,8 +3082,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
let mut checked = false;
opt_place.as_ref().map(|place| match place.node {
ast::ExprPath(None, ref path) => {
// FIXME(pcwalton): For now we hardcode the two permissible
// places: the exchange heap and the managed heap.
// FIXME(pcwalton): For now we hardcode the only permissible
// place: the exchange heap.
let definition = lookup_full_def(tcx, path.span, place.id);
let def_id = definition.def_id();
let referent_ty = fcx.expr_ty(&**subexpr);
Expand All @@ -3097,7 +3097,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,

if !checked {
span_err!(tcx.sess, expr.span, E0066,
"only the managed heap and exchange heap are currently supported");
"only the exchange heap is currently supported");
fcx.write_ty(id, tcx.types.err);
}
}
Expand Down Expand Up @@ -3317,7 +3317,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
result_type, ty::mk_nil(fcx.tcx())) {
span_err!(tcx.sess, expr.span, E0069,
"`return;` in function returning non-nil");
"`return;` in a function whose return type is \
not `()`");
},
Some(ref e) => {
check_expr_coercable_to_type(fcx, &**e, result_type);
Expand Down
109 changes: 105 additions & 4 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,44 @@ impl Foo for Bar {
```
"##,

E0053: r##"
In a trait method implementation, the function signature must match exactly.
This error indicates a mutability mismatch between a trait method signature
and the signature of the implementation.

Here's an example where the mutability of the `self` parameter is wrong:

```
trait Foo { fn foo(&self); }

struct Bar;

impl Foo for Bar {
// error, the signature should be `fn foo(&self)` instead
fn foo(&mut self) { }
}

fn main() {}
```

Here's another example, this time for a non-`self` parameter:

```
trait Foo { fn foo(x: &mut bool) -> bool; }

struct Bar;

impl Foo for Bar {
// error, the type of `x` should be `&mut bool` instead
fn foo(x: &bool) -> bool { *x }
}

fn main() {}
```


"##,

E0054: r##"
It is not allowed to cast to a bool. If you are trying to cast a numeric type
to a bool, you can compare it with zero instead:
Expand Down Expand Up @@ -91,6 +129,16 @@ enum variant, one of the fields was not provided. Each field should be specified
exactly once.
"##,

E0066: r##"
Box placement expressions (like C++'s "placement new") do not support any
place expression except the exchange heap (i.e. `std::boxed::HEAP`).
Furthermore, the syntax is changing to use `in` instead of `box`. See [RFC
470][rfc470] and [RFC 809][rfc809] for more details.

[rfc470]: https://github.com/rust-lang/rfcs/pull/470
[rfc809]: https://github.com/rust-lang/rfcs/pull/809
"##,

E0067: r##"
The left-hand side of an assignment operator must be an lvalue expression. An
lvalue expression represents a memory location and includes item paths (ie,
Expand All @@ -108,6 +156,21 @@ LinkedList::new() += 1;
```
"##,

E0069: r##"
The compiler found a function whose body contains a `return;` statement but
whose return type is not `()`. An example of this is:

```
// error
fn foo() -> u8 {
return;
}
```

Since `return;` is just like `return ();`, there is a mismatch between the
function's return type and the value being returned.
"##,

E0081: r##"
Enum discriminants are used to differentiate enum variants stored in memory.
This error indicates that the same value was used for two or more variants,
Expand Down Expand Up @@ -458,6 +521,48 @@ The `Sized` trait is a special trait built-in to the compiler for types with a
constant size known at compile-time. This trait is automatically implemented
for types as needed by the compiler, and it is currently disallowed to
explicitly implement it for a type.
"##,

E0368: r##"
This error indicates that a binary assignment operator like `+=` or `^=` was
applied to the wrong types.

A couple examples of this are as follows:

```
let mut x: u16 = 5;
x ^= true; // error, `^=` cannot be applied to types `u16` and `bool`
x += (); // error, `+=` cannot be applied to types `u16` and `()`
```

Another problem you might be facing is this: suppose you've overloaded the `+`
operator for some type `Foo` by implementing the `std::ops::Add` trait for
`Foo`, but you find that using `+=` does not work, as in this example:

```
use std::ops::Add;

struct Foo(u32);

impl Add for Foo {
type Output = Foo;

fn add(self, rhs: Foo) -> Foo {
Foo(self.0 + rhs.0)
}
}

fn main() {
let mut x: Foo = Foo(5);
x += Foo(7); // error, `+= cannot be applied to types `Foo` and `Foo`
}
```

This is because the binary assignment operators currently do not work off of
traits, so it is not possible to overload them. See [RFC 953] for a proposal
to change this.

[RFC 953]: https://github.com/rust-lang/rfcs/pull/953
"##

}
Expand All @@ -478,15 +583,12 @@ register_diagnostics! {
E0040, // explicit use of destructor method
E0044, // foreign items may not have type parameters
E0045, // variadic function must have C calling convention
E0053,
E0055, // method has an incompatible type for trait
E0057, // method has an incompatible type for trait
E0059,
E0060,
E0061,
E0066,
E0068,
E0069,
E0070,
E0071,
E0072,
Expand Down Expand Up @@ -606,7 +708,6 @@ register_diagnostics! {
E0328, // cannot implement Unsize explicitly
E0366, // dropck forbid specialization to concrete type or region
E0367, // dropck forbid specialization to predicate not in struct/enum
E0368, // binary operation `<op>=` cannot be applied to types
E0369, // binary operation `<op>` cannot be applied to types
E0371, // impl Trait for Trait is illegal
E0372, // impl Trait for Trait where Trait is not object safe
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-14084.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

fn main() {
box ( () ) 0;
//~^ ERROR: only the managed heap and exchange heap are currently supported
//~^ ERROR: only the exchange heap is currently supported
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/ret-non-nil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern: `return;` in function returning non-nil
// error-pattern: `return;` in a function whose return type is not `()`

fn f() { return; }

Expand Down