diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3769e9fa0f36a..169c4f6649739 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3033,8 +3033,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); @@ -3048,7 +3048,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); } } @@ -3268,7 +3268,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); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index ea872d1014425..abe91c51e15d3 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -19,6 +19,51 @@ methods that do not have default implementations), as well as any required trait items like associated types or constants. "##, +E0049: r##" +This error indicates that an attempted implementation of a trait method +has the wrong number of type parameters. + +For example, the trait below has a method `foo` with a type parameter `T`, +but the implementation of `foo` for the type `Bar` is missing this parameter: + +``` +trait Foo { + fn foo(x: T) -> Self; +} + +struct Bar; + +// error: method `foo` has 0 type parameters but its trait declaration has 1 +// type parameter +impl Foo for Bar { + fn foo(x: bool) -> Self { Bar } +} +``` +"##, + +E0050: r##" +This error indicates that an attempted implementation of a trait method +has the wrong number of function parameters. + +For example, the trait below has a method `foo` with two function parameters +(`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits +the `u8` parameter: + +``` +trait Foo { + fn foo(&self, x: u8) -> bool; +} + +struct Bar; + +// error: method `foo` has 1 parameter but the declaration in trait `Foo::foo` +// has 2 +impl Foo for Bar { + fn foo(&self) -> bool { true } +} +``` +"##, + 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: @@ -46,6 +91,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, @@ -63,6 +118,22 @@ LinkedList::new() += 1; ``` "##, +E0069: r##" +This error means that the compiler found a function whose body contains a +`return;` statement but whose return type is not `()`. For example: + +``` +// error +fn foo() -> u8 { + return; +} +``` + +When you omit the value from a `return` expression (that is, when you use +`return;` instead of `return x;`), the value `()` gets returned. So `return;` +is always incorrect for a function whose return type is not `()`. +"##, + 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, @@ -138,6 +209,88 @@ enum Empty {} ``` "##, +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 +lifetime elision rules (see below). + +Here are some simple examples of where you'll run into this error: + +``` +struct Foo { x: &bool } // error +struct Foo<'a> { x: &'a bool } // correct + +enum Bar { A(u8), B(&bool), } // error +enum Bar<'a> { A(u8), B(&'a bool), } // correct + +type MyStr = &str; // error +type MyStr<'a> = &'a str; //correct + +``` + +Lifetime elision is a special, limited kind of inference for lifetimes in +function signatures which allows you to leave out lifetimes in certain cases. +For more background on lifetime elision see [the book][book-le]. + +The lifetime elision rules require that any function signature with an elided +output lifetime must either have + + - exactly one input lifetime + - or, multiple input lifetimes, but the function must also be a method with a + `&self` or `&mut self` receiver + +In the first case, the output lifetime is inferred to be the same as the unique +input lifetime. In the second case, the lifetime is instead inferred to be the +same as the lifetime on `&self` or `&mut self`. + +Here are some examples of elision errors: + +``` +// error, no input lifetimes +fn foo() -> &str { ... } + +// error, `x` and `y` have distinct lifetimes inferred +fn bar(x: &str, y: &str) -> &str { ... } + +// error, `y`'s lifetime is inferred to be distinct from `x`'s +fn baz<'a>(x: &'a str, y: &str) -> &str { ... } +``` + +[book-le]: http://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision +"##, + +E0107: r##" +This error means that an incorrect number of lifetime parameters were provided +for a type (like a struct or enum) or trait. + +Some basic examples include: + +``` +struct Foo<'a>(&'a str); +enum Bar { A, B, C } + +struct Baz<'a> { + foo: Foo, // error: expected 1, found 0 + bar: Bar<'a>, // error: expected 0, found 1 +} +``` + +Here's an example that is currently an error, but may work in a future version +of Rust: + +``` +struct Foo<'a>(&'a str); + +trait Quux { } +impl Quux for Foo { } // error: expected 1, found 0 +``` + +Lifetime elision in implementation headers was part of the lifetime elision +RFC. It is, however, [currently unimplemented][iss15872]. + +[iss15872]: https://github.com/rust-lang/rust/issues/15872 +"##, + E0131: r##" It is not possible to define `main` with type parameters, or even with function parameters. When `main` is present, it must take no arguments and return `()`. @@ -152,6 +305,20 @@ fn(isize, *const *const u8) -> isize ``` "##, +E0166: r##" +This error means that the compiler found a return expression in a function +marked as diverging. A function diverges if it has `!` in the place of the +return type in its signature. For example: + +``` +fn foo() -> ! { return; } // error +``` + +For a function that diverges, every control path in the function must never +return, for example with a `loop` that never breaks or a call to another +diverging function (such as `panic!()`). +"##, + E0184: r##" Explicitly implementing both Drop and Copy for a type is currently disallowed. This feature can make some sense in theory, but the current implementation is @@ -161,6 +328,24 @@ it has been disabled for now. [iss20126]: https://github.com/rust-lang/rust/issues/20126 "##, +E0201: r##" +It is an error to define a method--a trait method or an inherent method--more +than once. + +For example, + +``` +struct Foo(u8); + +impl Foo { + fn bar() {} + + // error: duplicate method + fn bar(&self) -> bool { self.0 > 5 } +} +``` +"##, + E0204: r##" An attempt to implement the `Copy` trait for a struct failed because one of the fields does not implement `Copy`. To fix this, you must implement `Copy` for the @@ -292,6 +477,13 @@ const B: [u32; foo()] = []; use std::{f64, u8}; const C: [u32; u8::MAX + f64::EPSILON] = []; ``` +"##, + +E0322: r##" +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. "## } @@ -313,17 +505,13 @@ register_diagnostics! { E0040, // explicit use of destructor method E0044, // foreign items may not have type parameters E0045, // variadic function must have C calling convention - E0049, - E0050, 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, @@ -346,8 +534,6 @@ register_diagnostics! { E0102, E0103, E0104, - E0106, - E0107, E0116, E0117, E0118, @@ -365,7 +551,6 @@ register_diagnostics! { E0159, E0163, E0164, - E0166, E0167, E0168, E0172, @@ -391,7 +576,6 @@ register_diagnostics! { E0198, // negative implementations are not unsafe E0199, // implementing trait is not unsafe E0200, // trait requires an `unsafe impl` declaration - E0201, // duplicate method in trait impl E0202, // associated items are not allowed in inherent impls E0203, // type parameter has more than one relaxed default bound, // and only one is supported @@ -422,7 +606,7 @@ register_diagnostics! { E0231, // only named substitution parameters are allowed E0232, // this attribute must have a value E0233, - E0234, // `for` loop expression has type which does not implement the `Iterator` trait + E0234, E0235, // structure constructor specifies a structure of type but E0236, // no lang item for range syntax E0237, // no lang item for range syntax @@ -439,7 +623,6 @@ register_diagnostics! { E0319, // trait impls for defaulted traits allowed just for structs/enums E0320, // recursive overflow during dropck E0321, // extended coherence rules for defaulted traits violated - E0322, // cannot implement Sized explicitly E0323, // implemented an associated const when another trait item expected E0324, // implemented a method when another trait item expected E0325, // implemented an associated type when another trait item expected diff --git a/src/test/compile-fail/issue-14084.rs b/src/test/compile-fail/issue-14084.rs index 92e0dd3ad0e52..003c6644f7f02 100644 --- a/src/test/compile-fail/issue-14084.rs +++ b/src/test/compile-fail/issue-14084.rs @@ -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 } diff --git a/src/test/compile-fail/ret-non-nil.rs b/src/test/compile-fail/ret-non-nil.rs index 4ee3cf4abac4e..6be98fbd82773 100644 --- a/src/test/compile-fail/ret-non-nil.rs +++ b/src/test/compile-fail/ret-non-nil.rs @@ -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; }