@@ -3883,23 +3883,41 @@ func (c *Checker) checkReturnStatement(node *ast.Node) {
38833883 }
38843884 } else if c.getReturnTypeFromAnnotation(container) != nil {
38853885 unwrappedReturnType := core.OrElse(c.unwrapReturnType(returnType, functionFlags), returnType)
3886- unwrappedExprType := exprType
3887- if functionFlags&FunctionFlagsAsync != 0 {
3888- unwrappedExprType = c.checkAwaitedType(exprType, false /*withAlias*/, node, diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
3889- }
3890- if unwrappedReturnType != nil {
3891- // If the function has a return type, but promisedType is
3892- // undefined, an error will be reported in checkAsyncFunctionReturnType
3893- // so we don't need to report one here.
3894- c.checkTypeAssignableToAndOptionallyElaborate(unwrappedExprType, unwrappedReturnType, node, exprNode, nil, nil)
3895- }
3886+ c.checkReturnExpression(container, unwrappedReturnType, node, node.Expression(), exprType, false)
38963887 }
38973888 } else if !ast.IsConstructorDeclaration(container) && c.compilerOptions.NoImplicitReturns.IsTrue() && !c.isUnwrappedReturnTypeUndefinedVoidOrAny(container, returnType) {
38983889 // The function has a return type, but the return statement doesn't have an expression.
38993890 c.error(node, diagnostics.Not_all_code_paths_return_a_value)
39003891 }
39013892}
39023893
3894+ // When checking an arrow expression such as `(x) => exp`, then `node` is the expression `exp`.
3895+ // Otherwise, `node` is a return statement.
3896+ func (c *Checker) checkReturnExpression(container *ast.Node, unwrappedReturnType *Type, node *ast.Node, expr *ast.Node, exprType *Type, inConditionalExpression bool) {
3897+ unwrappedExprType := exprType
3898+ functionFlags := getFunctionFlags(container)
3899+ if expr != nil {
3900+ unwrappedExpr := ast.SkipParentheses(expr)
3901+ if ast.IsConditionalExpression(unwrappedExpr) {
3902+ whenTrue := unwrappedExpr.AsConditionalExpression().WhenTrue
3903+ whenFalse := unwrappedExpr.AsConditionalExpression().WhenFalse
3904+ c.checkReturnExpression(container, unwrappedReturnType, node, whenTrue, c.checkExpression(whenTrue), true /*inConditionalExpression*/)
3905+ c.checkReturnExpression(container, unwrappedReturnType, node, whenFalse, c.checkExpression(whenFalse), true /*inConditionalExpression*/)
3906+ return
3907+ }
3908+ }
3909+ inReturnStatement := node.Kind == ast.KindReturnStatement
3910+ if functionFlags&FunctionFlagsAsync != 0 {
3911+ unwrappedExprType = c.checkAwaitedType(exprType, false /*withAlias*/, node, diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
3912+ }
3913+ effectiveExpr := expr // The effective expression for diagnostics purposes.
3914+ if expr != nil {
3915+ effectiveExpr = c.getEffectiveCheckNode(expr)
3916+ }
3917+ errorNode := core.IfElse(inReturnStatement && !inConditionalExpression, node, effectiveExpr)
3918+ c.checkTypeAssignableToAndOptionallyElaborate(unwrappedExprType, unwrappedReturnType, errorNode, effectiveExpr, nil, nil)
3919+ }
3920+
39033921func (c *Checker) checkWithStatement(node *ast.Node) {
39043922 if !c.checkGrammarStatementInAmbientContext(node) {
39053923 if node.Flags&ast.NodeFlagsAwaitContext != 0 {
@@ -9775,13 +9793,7 @@ func (c *Checker) checkFunctionExpressionOrObjectLiteralMethodDeferred(node *ast
97759793 if returnType != nil {
97769794 returnOrPromisedType := c.unwrapReturnType(returnType, functionFlags)
97779795 if returnOrPromisedType != nil {
9778- effectiveCheckNode := c.getEffectiveCheckNode(body)
9779- if (functionFlags & FunctionFlagsAsyncGenerator) == FunctionFlagsAsync {
9780- awaitedType := c.checkAwaitedType(exprType, false /*withAlias*/, effectiveCheckNode, diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
9781- c.checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode, nil, nil)
9782- } else {
9783- c.checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode, nil, nil)
9784- }
9796+ c.checkReturnExpression(node, returnOrPromisedType, body, body, exprType, false)
97859797 }
97869798 }
97879799 }
0 commit comments