Skip to content

Commit b687921

Browse files
@pnkfelix update and typo fix
1 parent 4f73467 commit b687921

File tree

1 file changed

+139
-2
lines changed

1 file changed

+139
-2
lines changed

src/librustc/diagnostics.rs

+139-2
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,142 @@ loop. Without a loop to break out of or continue in, no sensible action can be
329329
taken.
330330
"##,
331331

332+
E0271: r##"
333+
This is because of a type mismatch between the associated type of some
334+
trait (e.g. T::Bar, where T implements trait Quux { type Bar; })
335+
and another type U that is required to be equal to T::Bar, but is not.
336+
Examples follow.
337+
338+
Here is a basic example:
339+
340+
```
341+
trait Trait { type AssociatedType; }
342+
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
343+
println!("in foo");
344+
}
345+
impl Trait for i8 { type AssociatedType = &'static str; }
346+
foo(3_i8);
347+
```
348+
349+
Here is that same example again, with some explanatory comments:
350+
351+
```
352+
trait Trait { type AssociatedType; }
353+
354+
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
355+
// ~~~~~~~~ ~~~~~~~~~~~~~~~~~~
356+
// | |
357+
// This says `foo` can |
358+
// only be used with |
359+
// some type that |
360+
// implements `Trait`. |
361+
// |
362+
// This says not only must
363+
// `T` be an impl of `Trait`
364+
// but also that the impl
365+
// must assign the type `u32`
366+
// to the associated type.
367+
println!("in foo");
368+
}
369+
370+
impl Trait for i8 { type AssociatedType = &'static str; }
371+
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
372+
// | |
373+
// `i8` does have |
374+
// implementation |
375+
// of `Trait`... |
376+
// ... but it is an implementation
377+
// that assigns `&'static str` to
378+
// the associated type.
379+
380+
foo(3_i8);
381+
// Here, we invoke `foo` with an `i8`, which does not satisfy
382+
// the constraint `<i8 as Trait>::AssociatedType=32`, and
383+
// therefore the type-checker complains with this error code.
384+
```
385+
386+
Here is a more subtle instance of the same problem, that can
387+
arise with for-loops in Rust:
388+
389+
```
390+
let vs: Vec<i32> = vec![1, 2, 3, 4];
391+
for v in &vs {
392+
match v {
393+
1 => {}
394+
_ => {}
395+
}
396+
}
397+
```
398+
399+
The above fails because of an analogous type mismatch,
400+
though may be harder to see. Again, here are some
401+
explanatory comments for the same example:
402+
403+
```
404+
{
405+
let vs = vec![1, 2, 3, 4];
406+
407+
// `for`-loops use a protocol based on the `Iterator`
408+
// trait. Each item yielded in a `for` loop has the
409+
// type `Iterator::Item` -- that is,I `Item` is the
410+
// associated type of the concrete iterator impl.
411+
for v in &vs {
412+
// ~ ~~~
413+
// | |
414+
// | We borrow `vs`, iterating over a sequence of
415+
// | *references* of type `&Elem` (where `Elem` is
416+
// | vector's element type). Thus, the associated
417+
// | type `Item` must be a reference `&`-type ...
418+
// |
419+
// ... and `v` has the type `Iterator::Item`, as dictated by
420+
// the `for`-loop protocol ...
421+
422+
match v {
423+
1 => {}
424+
// ~
425+
// |
426+
// ... but *here*, `v` is forced to have some integral type;
427+
// only types like `u8`,`i8`,`u16`,`i16`, et cetera can
428+
// match the pattern `1` ...
429+
430+
_ => {}
431+
}
432+
433+
// ... therefore, the compiler complains, because it sees
434+
// an attempt to solve the equations
435+
// `some integral-type` = type-of-`v`
436+
// = `Iterator::Item`
437+
// = `&Elem` (i.e. `some reference type`)
438+
//
439+
// which cannot possibly all be true.
440+
441+
}
442+
}
443+
```
444+
445+
To avoid those issues, you have to make the types match correctly.
446+
So we can fix the previous examples like this:
447+
448+
```
449+
// Basic Example:
450+
trait Trait { type AssociatedType; }
451+
fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> {
452+
println!("in foo");
453+
}
454+
impl Trait for i8 { type AssociatedType = &'static str; }
455+
foo(3_i8);
456+
457+
// For-Loop Example:
458+
let vs = vec![1, 2, 3, 4];
459+
for v in &vs {
460+
match v {
461+
&1 => {}
462+
_ => {}
463+
}
464+
}
465+
```
466+
"##,
467+
332468
E0296: r##"
333469
This error indicates that the given recursion limit could not be parsed. Ensure
334470
that the value provided is a positive integer between quotes, like so:
@@ -372,7 +508,9 @@ borrows were allowed:
372508
373509
match Some(()) {
374510
None => { },
375-
option if option.take().is_none() => { /* impossible, option is `Some` */ },
511+
option if option.take().is_none() => {
512+
/* impossible, option is `Some` */
513+
},
376514
Some(_) => { } // When the previous match failed, the option became `None`.
377515
}
378516
"##,
@@ -456,7 +594,6 @@ register_diagnostics! {
456594
E0266, // expected item
457595
E0269, // not all control paths return a value
458596
E0270, // computation may converge in a function marked as diverging
459-
E0271, // type mismatch resolving
460597
E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
461598
E0273, // rustc_on_unimplemented must have named format arguments
462599
E0274, // rustc_on_unimplemented must have a value

0 commit comments

Comments
 (0)