Auto merge of #24728 - GuillaumeGomez:type-mismatch, r=pnkfelix

Part of #24407.
This commit is contained in:
bors 2015-05-09 16:48:11 +00:00
commit dc630d01e3

View file

@ -419,6 +419,142 @@ of a loop. Without a loop to break out of or continue in, no sensible action can
be taken. be taken.
"##, "##,
E0271: r##"
This is because of a type mismatch between the associated type of some
trait (e.g. T::Bar, where T implements trait Quux { type Bar; })
and another type U that is required to be equal to T::Bar, but is not.
Examples follow.
Here is a basic example:
```
trait Trait { type AssociatedType; }
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
println!("in foo");
}
impl Trait for i8 { type AssociatedType = &'static str; }
foo(3_i8);
```
Here is that same example again, with some explanatory comments:
```
trait Trait { type AssociatedType; }
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
// ~~~~~~~~ ~~~~~~~~~~~~~~~~~~
// | |
// This says `foo` can |
// only be used with |
// some type that |
// implements `Trait`. |
// |
// This says not only must
// `T` be an impl of `Trait`
// but also that the impl
// must assign the type `u32`
// to the associated type.
println!("in foo");
}
impl Trait for i8 { type AssociatedType = &'static str; }
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// | |
// `i8` does have |
// implementation |
// of `Trait`... |
// ... but it is an implementation
// that assigns `&'static str` to
// the associated type.
foo(3_i8);
// Here, we invoke `foo` with an `i8`, which does not satisfy
// the constraint `<i8 as Trait>::AssociatedType=32`, and
// therefore the type-checker complains with this error code.
```
Here is a more subtle instance of the same problem, that can
arise with for-loops in Rust:
```
let vs: Vec<i32> = vec![1, 2, 3, 4];
for v in &vs {
match v {
1 => {}
_ => {}
}
}
```
The above fails because of an analogous type mismatch,
though may be harder to see. Again, here are some
explanatory comments for the same example:
```
{
let vs = vec![1, 2, 3, 4];
// `for`-loops use a protocol based on the `Iterator`
// trait. Each item yielded in a `for` loop has the
// type `Iterator::Item` -- that is,I `Item` is the
// associated type of the concrete iterator impl.
for v in &vs {
// ~ ~~~
// | |
// | We borrow `vs`, iterating over a sequence of
// | *references* of type `&Elem` (where `Elem` is
// | vector's element type). Thus, the associated
// | type `Item` must be a reference `&`-type ...
// |
// ... and `v` has the type `Iterator::Item`, as dictated by
// the `for`-loop protocol ...
match v {
1 => {}
// ~
// |
// ... but *here*, `v` is forced to have some integral type;
// only types like `u8`,`i8`,`u16`,`i16`, et cetera can
// match the pattern `1` ...
_ => {}
}
// ... therefore, the compiler complains, because it sees
// an attempt to solve the equations
// `some integral-type` = type-of-`v`
// = `Iterator::Item`
// = `&Elem` (i.e. `some reference type`)
//
// which cannot possibly all be true.
}
}
```
To avoid those issues, you have to make the types match correctly.
So we can fix the previous examples like this:
```
// Basic Example:
trait Trait { type AssociatedType; }
fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> {
println!("in foo");
}
impl Trait for i8 { type AssociatedType = &'static str; }
foo(3_i8);
// For-Loop Example:
let vs = vec![1, 2, 3, 4];
for v in &vs {
match v {
&1 => {}
_ => {}
}
}
```
"##,
E0282: r##" E0282: r##"
This error indicates that type inference did not result in one unique possible This error indicates that type inference did not result in one unique possible
type, and extra information is required. In most cases this can be provided type, and extra information is required. In most cases this can be provided
@ -674,7 +810,6 @@ register_diagnostics! {
E0266, // expected item E0266, // expected item
E0269, // not all control paths return a value E0269, // not all control paths return a value
E0270, // computation may converge in a function marked as diverging E0270, // computation may converge in a function marked as diverging
E0271, // type mismatch resolving
E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
E0273, // rustc_on_unimplemented must have named format arguments E0273, // rustc_on_unimplemented must have named format arguments
E0274, // rustc_on_unimplemented must have a value E0274, // rustc_on_unimplemented must have a value