@NotNull
  public KotlinType getBodyExpressionType(
      @NotNull BindingTrace trace,
      @NotNull LexicalScope outerScope,
      @NotNull DataFlowInfo dataFlowInfo,
      @NotNull KtDeclarationWithBody function,
      @NotNull FunctionDescriptor functionDescriptor) {
    KtExpression bodyExpression = function.getBodyExpression();
    assert bodyExpression != null;
    LexicalScope functionInnerScope =
        FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);

    ExpressionTypingContext context =
        ExpressionTypingContext.newContext(
            trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE);
    KotlinTypeInfo typeInfo =
        expressionTypingFacade.getTypeInfo(bodyExpression, context, function.hasBlockBody());

    KotlinType type = typeInfo.getType();
    if (type != null) {
      return type;
    } else {
      return ErrorUtils.createErrorType("Error function type");
    }
  }
  /*package*/ void checkFunctionReturnType(
      KtDeclarationWithBody function, ExpressionTypingContext context) {
    KtExpression bodyExpression = function.getBodyExpression();
    if (bodyExpression == null) return;

    boolean blockBody = function.hasBlockBody();
    ExpressionTypingContext newContext =
        blockBody ? context.replaceExpectedType(NO_EXPECTED_TYPE) : context;

    expressionTypingFacade.getTypeInfo(bodyExpression, newContext, blockBody);
  }
 public void checkFunctionReturnType(
     @NotNull LexicalScope functionInnerScope,
     @NotNull KtDeclarationWithBody function,
     @NotNull FunctionDescriptor functionDescriptor,
     @NotNull DataFlowInfo dataFlowInfo,
     @Nullable KotlinType expectedReturnType,
     BindingTrace trace) {
   if (expectedReturnType == null) {
     expectedReturnType = functionDescriptor.getReturnType();
     if (!function.hasBlockBody() && !function.hasDeclaredReturnType()) {
       expectedReturnType = NO_EXPECTED_TYPE;
     }
   }
   checkFunctionReturnType(
       function,
       ExpressionTypingContext.newContext(
           trace,
           functionInnerScope,
           dataFlowInfo,
           expectedReturnType != null ? expectedReturnType : NO_EXPECTED_TYPE));
 }