Closed
Description
Example:
use std::vec::Vec;
use std::iter::Iterator;
use std::slice::{AsSlice, Split, SliceExt};
pub struct Path {
repr: Vec<u8>, // assumed to never be empty or contain NULs
}
pub type Components<'a> = Split<'a, u8, fn(&u8) -> bool>;
pub fn is_sep_byte(u: &u8) -> bool {
true
}
impl Path {
fn components<'a>(&'a self) -> Components<'a>
where fn(&u8) -> bool : FnMut(&u8) -> bool
{
let v = &self.repr[1..];
let is_sep_byte: fn(&u8) -> bool = is_sep_byte; // coerce to fn ptr
let mut ret = v.split(is_sep_byte);
if v.is_empty() {
ret.next();
}
ret
}
}
fn main() {
}
fails with
<anon>:21:25: 21:43 error: internal compiler error: coherence failed to report ambiguity: cannot locate the impl of the trait `for<'r> core::ops::FnMut<(&'r u8,)>` for the type `fn(&u8) -> bool`
<anon>:21 let mut ret = v.split(is_sep_byte);
^~~~~~~~~~~~~~~~~~
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libsyntax/diagnostic.rs:129
playpen: application terminated with error code 101
Program ended.
This is because the compiler considers both the bridging impl from Fn
to FnMut
is an option and the where-clause to be valid options. Choosing between where-clauses and impls seems to be tricky.
At minimum, the code that checks for overlap between the where-clause and the impl seems to have the subtyping relationship backwards. However, I am not sure whether it's a good idea to check anything, or maybe better to simply always prefer where-clauses.