// Formatted problems:
//
// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Warning: Superclass has no method named 'foo'.
//   foo() => super.foo() + f();
//                  ^^^

library;
import self as self;
import "dart:core" as core;
import "./mixin_library.dart" as mix;

class Super<S extends core::Object = dynamic> extends core::Object {
  synthetic constructor •() → self::Super<self::Super::S>
    : super core::Object::•()
    ;
  method foo() → dynamic
    return 40;
  method f() → dynamic
    return 3;
}
abstract class _C&Super&Mixin<V extends core::Object = dynamic> = self::Super<self::_C&Super&Mixin::V> with mix::Mixin<self::_C&Super&Mixin::V> {
  synthetic constructor •() → self::_C&Super&Mixin<self::_C&Super&Mixin::V>
    : super self::Super::•()
    ;
}
class C<V extends core::Object = dynamic> extends self::_C&Super&Mixin<self::C::V> {
  synthetic constructor •() → self::C<self::C::V>
    : super self::_C&Super&Mixin::•()
    ;
}
abstract class _D&Super&Mixin = self::Super<dynamic> with mix::Mixin<dynamic> {
  synthetic constructor •() → self::_D&Super&Mixin
    : super self::Super::•()
    ;
}
class D extends self::_D&Super&Mixin {
  synthetic constructor •() → self::D
    : super self::_D&Super&Mixin::•()
    ;
}
class C2<V extends core::Object = dynamic> = self::Super<self::C2::V> with mix::Mixin<self::C2::V> {
  synthetic constructor •() → self::C2<self::C2::V>
    : super self::Super::•()
    ;
}
class D2 = self::Super<dynamic> with mix::Mixin<dynamic> {
  synthetic constructor •() → self::D2
    : super self::Super::•()
    ;
}
static method main() → dynamic {
  core::print(new self::C::•<dynamic>().foo());
  core::print(new self::C2::•<dynamic>().foo());
}
