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

class A extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  operator +(core::int value) → self::C
    return null;
  operator *(self::D value) → self::C
    return null;
}
class B extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  operator +(core::int value) → self::E
    return null;
  operator *(self::F value) → self::E
    return null;
}
class C extends self::B {
  synthetic constructor •() → void
    : super self::B::•()
    ;
}
class D extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
}
class E extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
}
class F extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
}
static method f<T extends core::Object = dynamic>() → self::f::T
  return null;
static get target() → self::A
  return null;
static set target(self::B value) → void {}
static method test1() → void {
  self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D);
  self::C x = self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D);
}
static method test2() → void {
  self::target = self::target.{self::A::+}(1);
  self::C x = self::target = self::target.{self::A::+}(1);
}
static method test3() → void {
  self::target = self::target.{self::A::+}(1);
  self::A x = let final self::A #t1 = self::target in let final self::C #t2 = self::target = #t1.{self::A::+}(1) in #t1;
}
static method main() → dynamic {}
