library test;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
import "dart:_internal" as _in;

class A extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
}
class B extends self::A {
  synthetic constructor •() → void
    : super self::A::•()
    ;
}
static method f<T extends core::Object = dynamic>() → self::f::T
  return null;
static method test() → dynamic /* originally async */ {
  final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
  asy::FutureOr<dynamic> :return_value;
  dynamic :async_stack_trace;
  dynamic :async_op_then;
  dynamic :async_op_error;
  dynamic :await_jump_var = 0;
  dynamic :await_ctx_var;
  dynamic :saved_try_context_var0;
  dynamic :saved_try_context_var1;
  dynamic :exception0;
  dynamic :stack_trace0;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L1:
      {
        core::Iterable<self::A> iterable;
        asy::Stream<self::A> stream;
        self::A a;
        self::B b;
        core::int i;
        for (final self::A #t1 in iterable) {
          a = #t1;
        }
        {
          dynamic :stream = stream;
          asy::_asyncStarListenHelper(:stream, :async_op);
          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(:stream);
          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
          try
            #L2:
            while (true) {
              dynamic #t2 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
              [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
              if(_in::unsafeCast<core::bool>(:result)) {
                final self::A #t4 = :for-iterator.{asy::_StreamIterator::current};
                {
                  a = #t4;
                }
              }
              else
                break #L2;
            }
          finally
            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
              [yield] let dynamic #t5 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
              :result;
            }
        }
        for (final self::A #t6 in iterable) {
          b = #t6 as{TypeError} self::B;
        }
        {
          dynamic :stream = stream;
          asy::_asyncStarListenHelper(:stream, :async_op);
          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(:stream);
          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
          try
            #L3:
            while (true) {
              dynamic #t7 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
              [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
              if(_in::unsafeCast<core::bool>(:result)) {
                final self::A #t9 = :for-iterator.{asy::_StreamIterator::current};
                {
                  b = #t9 as{TypeError} self::B;
                }
              }
              else
                break #L3;
            }
          finally
            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
              [yield] let dynamic #t10 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
              :result;
            }
        }
        for (final self::A #t11 in iterable) {
          i = let<BottomType> _ = null in let final dynamic #t12 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:26:55: Error: A value of type 'test::A' can't be assigned to a variable of type 'dart.core::int'.
Try changing the type of the variable.
  for (i /*@error=ForInLoopElementTypeNotAssignable*/ in iterable) {}
                                                      ^" in let final self::A #t13 = #t11 in null;
        }
        {
          dynamic :stream = stream;
          asy::_asyncStarListenHelper(:stream, :async_op);
          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(:stream);
          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
          try
            #L4:
            while (true) {
              dynamic #t14 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
              [yield] let dynamic #t15 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
              if(_in::unsafeCast<core::bool>(:result)) {
                final self::A #t16 = :for-iterator.{asy::_StreamIterator::current};
                {
                  i = let<BottomType> _ = null in let final dynamic #t17 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:27:61: Error: A value of type 'test::A' can't be assigned to a variable of type 'dart.core::int'.
Try changing the type of the variable.
  await for (i /*@error=ForInLoopElementTypeNotAssignable*/ in stream) {}
                                                            ^" in let final self::A #t18 = #t16 in null;
                }
              }
              else
                break #L4;
            }
          finally
            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
              [yield] let dynamic #t19 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
              :result;
            }
        }
        for (final self::A #t20 in self::f<core::Iterable<self::A>>()) {
          a = #t20;
        }
        {
          dynamic :stream = self::f<asy::Stream<self::A>>();
          asy::_asyncStarListenHelper(:stream, :async_op);
          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(:stream);
          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
          try
            #L5:
            while (true) {
              dynamic #t21 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
              [yield] let dynamic #t22 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
              if(_in::unsafeCast<core::bool>(:result)) {
                final self::A #t23 = :for-iterator.{asy::_StreamIterator::current};
                {
                  a = #t23;
                }
              }
              else
                break #L5;
            }
          finally
            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
              [yield] let dynamic #t24 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
              :result;
            }
        }
      }
      asy::_completeOnAsyncReturn(:async_completer, :return_value);
      return;
    }
    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
    }
  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
  asy::Future::microtask<dynamic>(:async_op);
  return :async_completer.{asy::Completer::future};
}
static method main() → dynamic {}
