library test;
import self as self;
import "dart:core" as core;

typedef F<T extends core::Object = dynamic> = (T) → void;
class B extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  get x() → (core::int) → void {
    throw "Should not be reached";
  }
  set x(core::Object value) → void {
    throw "Should not be reached";
  }
}
abstract class I<T extends core::Object = dynamic> extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  abstract get x() → (self::I::T) → void;
  abstract set x(core::Object value) → void;
}
abstract class M<T extends core::Object = dynamic> extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  get x() → self::M::T
    return this.{self::M::f}();
  set x(core::Object value) → void {
    throw "Should not be reached";
  }
  abstract method f() → self::M::T;
}
abstract class C<T extends core::Object = dynamic> = self::B with self::M<(self::C::T) → void> implements self::I<self::C::T> {
  synthetic constructor •() → void
    : super self::B::•()
    ;
}
class D extends self::C<core::int> {
  synthetic constructor •() → void
    : super self::B::•()
    ;
  method f() → (core::int) → void
    return (core::int i) → core::Null {
      self::expect(i, 1);
    };
}
static method expectTypeError(() → void callback) → void {
  try {
    callback.call();
    throw "Expected TypeError, did not occur";
  }
  on core::TypeError catch(no-exception-var) {
  }
}
static method expect(core::Object value, core::Object expected) → void {
  if(!value.{core::Object::==}(expected)) {
    throw "Expected ${expected}, got ${value}";
  }
}
static method test(self::I<core::Object> iObj, self::I<core::int> iInt) → void {
  self::expectTypeError(() → core::Null {
    (core::Object) → void x = iObj.{self::I::x} as{TypeError} (core::Object) → void;
  });
  (core::int) → void x = iInt.{self::I::x} as{TypeError} (core::int) → void;
  x.call(1);
}
static method main() → void {
  self::D d = new self::D::•();
  self::test(d, d);
}
