Auto merge of #24728 - GuillaumeGomez:type-mismatch, r=pnkfelix
Part of #24407.
This commit is contained in:
commit
dc630d01e3
1 changed files with 136 additions and 1 deletions
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue