library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/issue38253c.dart:6:3: Error: 'g' isn't a type.
//   g f1() {}
//   ^
//
// pkg/front_end/testcases/general/issue38253c.dart:7:3: Error: 'g' isn't a type.
//   g f2() async {}
//   ^
//
// pkg/front_end/testcases/general/issue38253c.dart:8:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
//   int f3() {}
//   ^
//
// pkg/front_end/testcases/general/issue38253c.dart:9:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
//   Future<int> f4() async {}
//   ^
//
import self as self;
import "dart:async" as asy;
import "dart:core" as core;

static field () → Null a = () → Null {
  function f1() → invalid-type {}
  function f2() → invalid-type /* 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;
    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
      try {
        #L1:
        {}
        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(){() → dynamic};
    :is_sync = true;
    return :async_future;
  }
  function f3() → core::int {
    return invalid-expression "pkg/front_end/testcases/general/issue38253c.dart:8:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
  int f3() {}
  ^" in null;
  }
  function f4() → asy::Future<core::int> /* originally async */ {
    final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
    core::bool* :is_sync = false;
    FutureOr<core::int>? :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, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
      try {
        #L2:
        {
          :return_value = invalid-expression "pkg/front_end/testcases/general/issue38253c.dart:9:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
  Future<int> f4() async {}
  ^" in null;
          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(){() → dynamic};
    :is_sync = true;
    return :async_future;
  }
};
static field (dynamic) → asy::Future<dynamic> b = (dynamic f) → asy::Future<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;
  dynamic :saved_try_context_var0;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L3:
      {
        [yield] let dynamic #t1 = asy::_awaitHelper(f, :async_op_then, :async_op_error, :async_op) in null;
        :return_value = :result;
        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(){() → dynamic};
  :is_sync = true;
  return :async_future;
};
static field (dynamic) → dynamic c = (dynamic f) → dynamic => f;
static method main() → dynamic {}
