@@ -419,6 +419,142 @@ of a loop. Without a loop to break out of or continue in, no sensible action can
419419be 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+
422558E0282 : r##"
423559This error indicates that type inference did not result in one unique possible
424560type, 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