Description
I stumbled upon this trying to write a function that generically takes a range (or something else with which str
can be indexed), and slices a str with that range. I got that to work, this bug comes into play when the str is produced by slicing another string with a RangeFrom
or another concrete type (in the same function).
Here's a simpler (no lifetimes, no associated types) and self-contained example (playpen):
trait Frobnicate<I> {
fn frob(&self, i: I) -> Self;
}
struct Thing;
struct IA;
struct IB;
impl Frobnicate<IA> for Thing {
fn frob(&self, _i: IA) -> Thing { Thing }
}
impl Frobnicate<IB> for Thing {
fn frob(&self, _i: IB) -> Thing { Thing }
}
fn delegate_frob<I>(t: Thing, i: I) -> Thing
where Thing : Frobnicate<I> {
let t2: Thing = t.frob(IA);
t2.frob(i)
}
fn main() {}
This seems innocent enough. There's a impl Frobnicate<IA> for Thing
, so the .frob(IA)
call should work, and it's known to return Thing
again, so via the where
clause the .frob(i)
call is good as well. However, I get this error message:
<anon>:20:28: 20:30 error: mismatched types:
expected `I`,
found `IA`
(expected type parameter,
found struct `IA`) [E0308]
<anon>:20 let t2: Thing = t.frob(IA);
^~
It appears that the where clause makes the compiler forget that there are other impls.
Adding a Thing : Frobnicate<IA>
bound only makes the compiler (rightly) complain that that's not a bound at all, since it doesn't involve any type parameters.
UFCS makes it compile, though:
let t2: Thing = <Thing as Frobnicate<IA>>::frob(&t, IA);
Edit: Besides playpen, I can also reproduce this locally:
rustc 1.0.0-beta (9854143cb 2015-04-02) (built 2015-04-02)
binary: rustc
commit-hash: 9854143cba679834bc4ef932858cd5303f015a0e
commit-date: 2015-04-02
build-date: 2015-04-02
host: x86_64-pc-windows-gnu
release: 1.0.0-beta
But I already noticed it a couple of weeks ago, so it can't be a recent regression.