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

class Foo extends core::Object {
  field core::int bar = 42;
  synthetic constructor •() → self::Foo
    : super core::Object::•()
    ;
}
class Bar<T extends core::Iterable<core::String> = dynamic> extends core::Object {
  synthetic constructor •() → self::Bar<self::Bar::T>
    : super core::Object::•()
    ;
  method foo(generic-covariant-impl self::Bar::T t) → void {
    for (dynamic i in t) {
      core::int x = i;
    }
  }
}
class Baz<T extends core::Object = dynamic, E extends core::Iterable<self::Baz::T> = dynamic, S extends self::Baz::E = dynamic> extends core::Object {
  synthetic constructor •() → self::Baz<self::Baz::T, self::Baz::E, self::Baz::S>
    : super core::Object::•()
    ;
  method foo(generic-covariant-impl self::Baz::S t) → void {
    for (dynamic i in t) {
      core::int x = i;
      self::Baz::T y = i;
    }
  }
}
static method test() → dynamic {
  dynamic list = <self::Foo>[];
  for (dynamic x in list) {
    core::String y = x;
  }
  for (dynamic x in list) {
    core::String y = x;
  }
  for (core::String x in list) {
    core::String y = x;
  }
  dynamic z;
  for (final dynamic #t1 in list) {
    z = #t1;
    core::String y = z;
  }
  core::Iterable<dynamic> iter = list;
  for (self::Foo x in iter) {
    dynamic y = x;
  }
  dynamic iter2 = list;
  for (self::Foo x in iter2) {
    dynamic y = x;
  }
  dynamic map = <core::String, self::Foo>{};
  for (dynamic x in map) {
    core::String y = x;
  }
  for (dynamic x in map.keys) {
    core::String y = x;
  }
}
static method main() → dynamic {}
