Issue 1:
Some days ago, I wrote some code involving char as HashMap key. At that time, char didn't implement the IterBytes trait, so I implemented it locally myself. After updating rust, my code failed to compile with a somewhat less than obvious error.

Example:

extern mod std;
use std::map::HashMap;
use to_bytes::{IterBytes, Cb};

impl char: IterBytes {
pure fn iter_bytes(lsb0: bool, f: Cb) {
(self as i32).iter_bytes(lsb0, f);
}
}

fn main() {
let h = HashMap();
h.insert('a', ());
io::println(h.contains_key('a').to_str());
}

Produces the following errors:

minimal.rs:12:12: 12:19 error: multiple applicable methods in scope
minimal.rs:12 let h = HashMap();
^~~~~~~
minimal.rs:12:12: 12:19 error: multiple applicable methods in scope
minimal.rs:12 let h = HashMap();
^~~~~~~
minimal.rs:13:4: 13:12 error: multiple applicable methods in scope
minimal.rs:13 h.insert('a', ());
^~~~~~~~
minimal.rs:13:4: 13:12 error: multiple applicable methods in scope
minimal.rs:13 h.insert('a', ());
^~~~~~~~
minimal.rs:14:16: 14:30 error: multiple applicable methods in scope
minimal.rs:14 io::println(h.contains_key('a').to_str());
^~~~~~~~~~~~~~
minimal.rs:14:16: 14:30 error: multiple applicable methods in scope
minimal.rs:14 io::println(h.contains_key('a').to_str());
^~~~~~~~~~~~~~
error: aborting due to 6 previous errors

Note that there is no way to know that the problem is the duplicate implementation of IterBytes.

Issue 2:
The following code compiles:

struct Foo<'a>(&'a uint);

impl<'a> Foo<'a> {
fn bar<'a>(self, other:Foo<'a>) {}
}

However, in the event of a lifetime mismatch, this can lead to confusing error messages.

use std::kinds::marker::ContravariantLifetime;
// Using a Contravariant lifetime because #[deriving] doesn't seem to work well
// with &-ptrs. Example holds with a covariant one as well.

#[deriving(PartialEq)]
struct Foo<'a>(ContravariantLifetime<'a>, uint);

impl<'a> Foo<'a> {
fn bar<'a>(self, other: Foo<'a>) -> bool {
self == other
}
}

This gives a tautological recommendation along with a confusing error:

test.rs:8:2: 11:3 help: consider using an explicit lifetime parameter as shown: fn bar<'a>(self, other: Foo<'a>) -> bool
test.rs:8 fn bar<'a>(self, other: Foo<'a>) -> bool {
test.rs:9 //baz(self, other)
test.rs:10 self == other
test.rs:11 }
test.rs:10:12: 10:17 error: mismatched types: expected `Foo<'a>`, found `Foo<'a>` (lifetime mismatch)
test.rs:10 self == other

It's not really the error's fault for being so confusing, after all, we have shadowed the 'a from the impl with a 'a from the definition of baz(). This should probably be disallowed or at least linted.

The recommendation is flawed in two ways

Firstly, it recommended 'a, a lifetime which is already being used there (twice, actually). That's adding to the confusion. It clearly means to recommend a new lifetime ('b?)

It's wrong, even if you change the signature of bar() to use 'b, it's still wrong, but then it gives the correct recommendation to use fn bar(self, other: Foo<'a>) -> bool on recompiling.

This probably needs better error reporting (don't recommend lifetimes which are already being used in that context)

@glennw came across this in Servo, getting tautological errors like this and this. The former is due to lifetime shadowing (and can be fixed by disallowing shadowing). I'm not yet sure what prompted the latter one, one of the lifetimes is elided but the other one is named 'a in the surrounding impl and should have turned up in the error message instead of being underscored.