The interaction between implicit borrows and typeclasses is currently problematic and inconsistent.
Suppose we have the following interface, an implementation of it for vector slices, and a function that is parameterized over the typeclass:
iface iterable<A> {
fn iterate(blk: fn(A) -> bool);
}
impl vec/&<A> of iterable<A> for &[const A] {
fn iterate(f: fn(A) -> bool) {
vec::each(self, f);
}
}
fn print<A, T: iterable<A>>(x: T) {
for x.iterate() |x| { log(error, x); }
}
The following code works since x will be implicitly borrowed
fn main() {
let x = ~[1,2,3];
for x.iterate() |x| { log(error, x) }
}
This is because add_candidates_from_scope in method.rs uses can_mk_assignty when matching against impls, which will do a borrow to convert x to a slice.
However, the following code does not work:
fn main() {
let x = ~[1,2,3];
print(x);
}
It will fail to find an implementation of iterable for [int]/~. This is because lookup_vtable in vtable.rs uses mk_subty when matching against impls. I think that lookup_vtable basically has to use subtyping and not type assignability: typeclass constraints need not correspond to just the type of an argument expression that we can perform a borrow on.
To make matters worse, we can't work around this by just writing impls for ~[A], since then the first example would fail with an error about multiple methods in scope.
I think probably the right thing to do is to not do implicit borrows on method calls, but I'm not sure.
The interaction between implicit borrows and typeclasses is currently problematic and inconsistent.
Suppose we have the following interface, an implementation of it for vector slices, and a function that is parameterized over the typeclass:
The following code works since
xwill be implicitly borrowedThis is because
add_candidates_from_scopein method.rs usescan_mk_assigntywhen matching against impls, which will do a borrow to convertxto a slice.However, the following code does not work:
It will fail to find an implementation of
iterablefor[int]/~. This is becauselookup_vtablein vtable.rs usesmk_subtywhen matching against impls. I think thatlookup_vtablebasically has to use subtyping and not type assignability: typeclass constraints need not correspond to just the type of an argument expression that we can perform a borrow on.To make matters worse, we can't work around this by just writing
impls for~[A], since then the first example would fail with an error about multiple methods in scope.I think probably the right thing to do is to not do implicit borrows on method calls, but I'm not sure.