Skip to content

Commit dc630d0

Browse files
committed
Auto merge of #24728 - GuillaumeGomez:type-mismatch, r=pnkfelix
Part of #24407.
2 parents 67ba6dc + 30f88c8 commit dc630d0

File tree

1 file changed

+136
-1
lines changed

1 file changed

+136
-1
lines changed

Diff for: src/librustc/diagnostics.rs

+136-1
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,142 @@ of a loop. Without a loop to break out of or continue in, no sensible action can
419419
be taken.
420420
"##,
421421

422+
E0271: r##"
423+
This is because of a type mismatch between the associated type of some
424+
trait (e.g. T::Bar, where T implements trait Quux { type Bar; })
425+
and another type U that is required to be equal to T::Bar, but is not.
426+
Examples follow.
427+
428+
Here is a basic example:
429+
430+
```
431+
trait Trait { type AssociatedType; }
432+
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
433+
println!("in foo");
434+
}
435+
impl Trait for i8 { type AssociatedType = &'static str; }
436+
foo(3_i8);
437+
```
438+
439+
Here is that same example again, with some explanatory comments:
440+
441+
```
442+
trait Trait { type AssociatedType; }
443+
444+
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
445+
// ~~~~~~~~ ~~~~~~~~~~~~~~~~~~
446+
// | |
447+
// This says `foo` can |
448+
// only be used with |
449+
// some type that |
450+
// implements `Trait`. |
451+
// |
452+
// This says not only must
453+
// `T` be an impl of `Trait`
454+
// but also that the impl
455+
// must assign the type `u32`
456+
// to the associated type.
457+
println!("in foo");
458+
}
459+
460+
impl Trait for i8 { type AssociatedType = &'static str; }
461+
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
462+
// | |
463+
// `i8` does have |
464+
// implementation |
465+
// of `Trait`... |
466+
// ... but it is an implementation
467+
// that assigns `&'static str` to
468+
// the associated type.
469+
470+
foo(3_i8);
471+
// Here, we invoke `foo` with an `i8`, which does not satisfy
472+
// the constraint `<i8 as Trait>::AssociatedType=32`, and
473+
// therefore the type-checker complains with this error code.
474+
```
475+
476+
Here is a more subtle instance of the same problem, that can
477+
arise with for-loops in Rust:
478+
479+
```
480+
let vs: Vec<i32> = vec![1, 2, 3, 4];
481+
for v in &vs {
482+
match v {
483+
1 => {}
484+
_ => {}
485+
}
486+
}
487+
```
488+
489+
The above fails because of an analogous type mismatch,
490+
though may be harder to see. Again, here are some
491+
explanatory comments for the same example:
492+
493+
```
494+
{
495+
let vs = vec![1, 2, 3, 4];
496+
497+
// `for`-loops use a protocol based on the `Iterator`
498+
// trait. Each item yielded in a `for` loop has the
499+
// type `Iterator::Item` -- that is,I `Item` is the
500+
// associated type of the concrete iterator impl.
501+
for v in &vs {
502+
// ~ ~~~
503+
// | |
504+
// | We borrow `vs`, iterating over a sequence of
505+
// | *references* of type `&Elem` (where `Elem` is
506+
// | vector's element type). Thus, the associated
507+
// | type `Item` must be a reference `&`-type ...
508+
// |
509+
// ... and `v` has the type `Iterator::Item`, as dictated by
510+
// the `for`-loop protocol ...
511+
512+
match v {
513+
1 => {}
514+
// ~
515+
// |
516+
// ... but *here*, `v` is forced to have some integral type;
517+
// only types like `u8`,`i8`,`u16`,`i16`, et cetera can
518+
// match the pattern `1` ...
519+
520+
_ => {}
521+
}
522+
523+
// ... therefore, the compiler complains, because it sees
524+
// an attempt to solve the equations
525+
// `some integral-type` = type-of-`v`
526+
// = `Iterator::Item`
527+
// = `&Elem` (i.e. `some reference type`)
528+
//
529+
// which cannot possibly all be true.
530+
531+
}
532+
}
533+
```
534+
535+
To avoid those issues, you have to make the types match correctly.
536+
So we can fix the previous examples like this:
537+
538+
```
539+
// Basic Example:
540+
trait Trait { type AssociatedType; }
541+
fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> {
542+
println!("in foo");
543+
}
544+
impl Trait for i8 { type AssociatedType = &'static str; }
545+
foo(3_i8);
546+
547+
// For-Loop Example:
548+
let vs = vec![1, 2, 3, 4];
549+
for v in &vs {
550+
match v {
551+
&1 => {}
552+
_ => {}
553+
}
554+
}
555+
```
556+
"##,
557+
422558
E0282: r##"
423559
This error indicates that type inference did not result in one unique possible
424560
type, and extra information is required. In most cases this can be provided
@@ -674,7 +810,6 @@ register_diagnostics! {
674810
E0266, // expected item
675811
E0269, // not all control paths return a value
676812
E0270, // computation may converge in a function marked as diverging
677-
E0271, // type mismatch resolving
678813
E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
679814
E0273, // rustc_on_unimplemented must have named format arguments
680815
E0274, // rustc_on_unimplemented must have a value

0 commit comments

Comments
 (0)