// Formatted problems:
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:14:46: Error: Declared type variables of 'D::m' doesn't match those on overridden method 'C::m'.
//   T /*@error=OverrideTypeVariablesMismatch*/ m<T>(
//                                              ^
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:9:24: Error: This is the overridden method ('m').
//   /*@topType=dynamic*/ m(/*@topType=dynamic*/ x) => x;
//                        ^
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:15:54: Error: The parameter 'x' of the method 'D::m' has type test::D::m::T, which does not match the corresponding type in the overridden method (dynamic).
// Change to a supertype of dynamic (or, for a covariant parameter, a subtype).
//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
//                                                      ^
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:9:24: Error: This is the overridden method ('m').
//   /*@topType=dynamic*/ m(/*@topType=dynamic*/ x) => x;
//                        ^
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:17:46: Error: Declared type variables of 'D::g' doesn't match those on overridden method 'C::g'.
//   T /*@error=OverrideTypeVariablesMismatch*/ g<T>(
//                                              ^
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Error: This is the overridden method ('g').
//   dynamic g(int x) => x;
//           ^
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:18:54: Error: The parameter 'x' of the method 'D::g' has type test::D::g::T, which does not match the corresponding type in the overridden method (dart.core::int).
// Change to a supertype of dart.core::int (or, for a covariant parameter, a subtype).
//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
//                                                      ^
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Error: This is the overridden method ('g').
//   dynamic g(int x) => x;
//           ^

// Unhandled errors:
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:14:46: Error: Declared type variables of 'D::m' doesn't match those on overridden method 'C::m'.
//   T /*@error=OverrideTypeVariablesMismatch*/ m<T>(
//                                              ^
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:15:54: Error: The parameter 'x' of the method 'D::m' has type test::D::m::T, which does not match the corresponding type in the overridden method (dynamic).
// Change to a supertype of dynamic (or, for a covariant parameter, a subtype).
//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
//                                                      ^
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:17:46: Error: Declared type variables of 'D::g' doesn't match those on overridden method 'C::g'.
//   T /*@error=OverrideTypeVariablesMismatch*/ g<T>(
//                                              ^
//
// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:18:54: Error: The parameter 'x' of the method 'D::g' has type test::D::g::T, which does not match the corresponding type in the overridden method (dart.core::int).
// Change to a supertype of dart.core::int (or, for a covariant parameter, a subtype).
//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
//                                                      ^

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

class C extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  method m(dynamic x) → dynamic
    return x;
  method g(core::int x) → dynamic
    return x;
}
class D extends self::C {
  synthetic constructor •() → void
    : super self::C::•()
    ;
  method m<T extends core::Object = dynamic>(self::D::m::T x) → self::D::m::T
    return x;
  method g<T extends core::Object = dynamic>(self::D::g::T x) → self::D::g::T
    return x;
}
static method main() → dynamic {
  core::int y = (new self::D::•() as self::C).{self::C::m}(42) as{TypeError} core::int;
  core::print(y);
}
