@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);
  }