library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
import "dart:_internal" as _in;

import "dart:async";

class A<X extends core::Object? = dynamic> extends core::Object {
  synthetic constructor •() → self::A<self::A::X%>
    : super core::Object::•()
    ;
}
static method foo<X extends core::Object?>(self::A<self::foo::X%> x) → asy::Future<self::foo::X?>
  return throw 42;
static method bar(core::String? y) → dynamic {}
static method test(self::A<core::String> a) → dynamic /* futureValueType= dynamic */ /* originally async */ {
  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
  core::bool* :is_sync = false;
  dynamic :return_value;
  (dynamic) → dynamic :async_op_then;
  (core::Object, core::StackTrace) → dynamic :async_op_error;
  core::int :await_jump_var = 0;
  dynamic :await_ctx_var;
  dynamic :saved_try_context_var0;
  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
    try {
      #L1:
      {
        [yield] let dynamic #t1 = asy::_awaitHelper((() → asy::Future<core::String?> /* futureValueType= core::String? */ /* originally async */ {
          final asy::_Future<core::String?> :async_future = new asy::_Future::•<core::String?>();
          core::bool* :is_sync = false;
          FutureOr<core::String?>? :return_value;
          (dynamic) → dynamic :async_op_then;
          (core::Object, core::StackTrace) → dynamic :async_op_error;
          core::int :await_jump_var = 0;
          dynamic :await_ctx_var;
          function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
            try {
              #L2:
              {
                :return_value = self::foo<core::String>(a);
                break #L2;
              }
              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
              return;
            }
            on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
            }
          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
          :async_op(null, null){() → dynamic};
          :is_sync = true;
          return :async_future;
        })(){() → asy::Future<core::String?>}, :async_op_then, :async_op_error) in null;
        final core::String? x = _in::unsafeCast<core::String?>(:result_or_exception);
        self::bar(x);
      }
      asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
      return;
    }
    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
    }
  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
  :async_op(null, null){() → dynamic};
  :is_sync = true;
  return :async_future;
}
static method test2(self::A<core::String> a) → dynamic /* futureValueType= dynamic */ /* originally async */ {
  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
  core::bool* :is_sync = false;
  FutureOr<dynamic>? :return_value;
  (dynamic) → dynamic :async_op_then;
  (core::Object, core::StackTrace) → dynamic :async_op_error;
  core::int :await_jump_var = 0;
  dynamic :await_ctx_var;
  function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
    try {
      #L3:
      {
        :return_value = self::foo<core::String>(a);
        break #L3;
      }
      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
      return;
    }
    on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
    }
  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
  :async_op(null, null){() → dynamic};
  :is_sync = true;
  return :async_future;
}
static method test3(self::A<core::String> a) → dynamic {
  return self::foo<core::String>(a);
}
static method main() → dynamic {}
