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

class C extends core::Object {
  final field core::int? _f2;
  final field core::int? _f3;
  final field core::int? _f4;
  constructor •(core::int? i) → self::C
    : self::C::_f2 = i, self::C::_f3 = i, self::C::_f4 = i, super core::Object::•()
    ;
}
class A extends core::Object {
  constructor •(core::int? i) → self::A
    : super core::Object::•()
    ;
}
abstract class M3 extends core::Object /*isMixinDeclaration*/  {
}
abstract class _D&A&M3 extends self::A implements self::M3 /*isAnonymousMixin,isEliminatedMixin*/  {
  synthetic constructor •(core::int? i) → self::_D&A&M3
    : super self::A::•(i)
    ;
}
abstract class D extends self::_D&A&M3 {
  final field core::int? _f4;
  constructor •(core::int? i) → self::D
    : self::D::_f4 = i, super self::_D&A&M3::•(i)
    ;
}
abstract class M1 extends core::Object /*isMixinDeclaration*/  {
  late field core::int? _f2;
  late final [setter] field core::int? _f3;
  late final field core::int? _f4 = 0;
}
class B extends core::Object {
  constructor •(core::int? i) → self::B
    : super core::Object::•()
    ;
}
abstract class _E&B&M1 extends self::B implements self::M1 /*isAnonymousMixin,isEliminatedMixin*/  {
  late field core::int? _f2;
  late final [setter] field core::int? _f3;
  late final field core::int? _f4 = 0;
  synthetic constructor •(core::int? i) → self::_E&B&M1
    : super self::B::•(i)
    ;
}
class E extends self::_E&B&M1 implements self::D {
  constructor •(core::int? i) → self::E
    : super self::_E&B&M1::•(i)
    ;
  @#C1
  method noSuchMethod(core::Invocation invocation) → dynamic
    return super.{core::Object::noSuchMethod}(invocation);
}
static method acceptsInt(core::int x) → void {}
static method testConflictWithNoSuchMethodForwarderIfImplementedInMixin(self::C c) → void {
  if(!(c.{self::C::_f2}{core::int?} == null)) {
    core::int? x = c.{self::C::_f2}{core::int?};
    x = null;
  }
}
static method testNoConflictWithNoSuchMethodForwarderIfImplementedInMixin1(self::C c) → void {
  if(!(c.{self::C::_f3}{core::int?} == null)) {
    core::int x = let core::int? #t1 = c.{self::C::_f3}{core::int?} in #t1 == null ?{core::int} #t1 as{Unchecked} core::int : #t1{core::int};
    self::acceptsInt(x);
  }
}
static method testNoConflictWithNoSuchMethodForwarderIfImplementedInMixin2(self::C c) → void {
  if(!(c.{self::C::_f4}{core::int?} == null)) {
    core::int x = let core::int? #t2 = c.{self::C::_f4}{core::int?} in #t2 == null ?{core::int} #t2 as{Unchecked} core::int : #t2{core::int};
    self::acceptsInt(x);
  }
}
static method main() → dynamic {
  {
    synthesized core::Iterator<self::C> :sync-for-iterator = core::_GrowableList::_literal2<self::C>(new self::C::•(null), new self::C::•(0)).{core::Iterable::iterator}{core::Iterator<self::C>};
    for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
      self::C c = :sync-for-iterator.{core::Iterator::current}{self::C};
      {
        self::testConflictWithNoSuchMethodForwarderIfImplementedInMixin(c);
        self::testNoConflictWithNoSuchMethodForwarderIfImplementedInMixin1(c);
        self::testNoConflictWithNoSuchMethodForwarderIfImplementedInMixin2(c);
      }
    }
  }
}

constants  {
  #C1 = core::_Override {}
}
