//  T1 <: S1      S2 <: T2
//  ----------------------
//  S1 -> S2  <:  T1 -> T2

class T2 { }

class S2 extends T2 { int bla() { return 0; } }

class S1 { S2 m() { return new S2(); } }

class T1 extends S1 { int bla() { return 1; } }

class C { T2 f(T1 o) { return o.m(); }}

class Overload { 
    int g(T2 x) { return 2; }
    int g(S2 x) { return x.bla() + 3; }
} 

interface T1toT2 { T2 apply(T1 x); }

// does not compile:
class S1toS2 implements T1toT2 { 
    public S2 apply(S1 x) { return x.m(); }
}

class testSubtypeArrow {
    public static void main(String[] argv) {
        // test of arrow subtyping with self
	C c = new C();
	S1 o = new S1();
        T2 r = c.f(o); // does not compile

        S1toS2 f = new S1toS2();
        T1 x = new T1();
        T2 r_ = f.apply (x);
    }
}
