// Copyright 2012-4 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Tests that type assignability is used to search for instances when
// making method calls, but only if there aren't any matches without
// it.


#![feature(unboxed_closures)]

trait iterable<A> {
    fn iterate<F>(&self, blk: F) -> bool where F: FnMut(&A) -> bool;
}

impl<'a,A> iterable<A> for &'a [A] {
    fn iterate<F>(&self, f: F) -> bool where F: FnMut(&A) -> bool {
        self.iter().all(f)
    }
}

impl<A> iterable<A> for Vec<A> {
    fn iterate<F>(&self, f: F) -> bool where F: FnMut(&A) -> bool {
        self.iter().all(f)
    }
}

fn length<A, T: iterable<A>>(x: T) -> usize {
    let mut len = 0;
    x.iterate(|_y| {
        len += 1;
        true
    });
    return len;
}

pub fn main() {
    let x: Vec<isize> = vec!(0,1,2,3);
    // Call a method
    x.iterate(|y| { assert_eq!(x[*y as usize], *y); true });
    // Call a parameterized function
    assert_eq!(length(x.clone()), x.len());
    // Call a parameterized function, with type arguments that require
    // a borrow
    assert_eq!(length::<isize, &[isize]>(&*x), x.len());

    // Now try it with a type that *needs* to be borrowed
    let z = [0,1,2,3];
    // Call a parameterized function
    assert_eq!(length::<isize, &[isize]>(&z), z.len());
}
