diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 8f2038ba3f6..0f491fc6808 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -1,5 +1,6 @@ ### Fixed +* Fix a false positive of the `[]` analysis in combination with async. ([Issue #17237](https://github.com/dotnet/fsharp/issues/17237), [PR #17241](https://github.com/dotnet/fsharp/pull/17241)) * Extended #help directive in fsi to show documentation in the REPL. ([PR #17140](https://github.com/dotnet/fsharp/pull/17140)) * Fix internal error when dotting into delegates with multiple type parameters. ([PR #17227](https://github.com/dotnet/fsharp/pull/17227)) * Error for partial implementation of interface with static and non-static abstract members. ([Issue #17138](https://github.com/dotnet/fsharp/issues/17138), [PR #17160](https://github.com/dotnet/fsharp/pull/17160)) diff --git a/src/Compiler/Checking/TailCallChecks.fs b/src/Compiler/Checking/TailCallChecks.fs index 97bdc05680b..c373be9eb8a 100644 --- a/src/Compiler/Checking/TailCallChecks.fs +++ b/src/Compiler/Checking/TailCallChecks.fs @@ -756,7 +756,18 @@ let CheckModuleBinding cenv (isRec: bool) (TBind _ as bind) = | Expr.Lambda(bodyExpr = bodyExpr) -> checkTailCall insideSubBindingOrTry bodyExpr | Expr.DebugPoint(_debugPointAtLeafExpr, expr) -> checkTailCall insideSubBindingOrTry expr | Expr.Let(binding = binding; bodyExpr = bodyExpr) -> - checkTailCall true binding.Expr + // detect continuation shapes like MakeAsync + let isContinuation = + match bodyExpr with + | Expr.App(funcExpr = Expr.Val(valRef = valRef)) -> + match valRef.GeneralizedType with + | [ _ ], + TType_fun(domainType = TType_fun(domainType = TType_app _; rangeType = TType_app _); rangeType = TType_app _) -> + true + | _ -> false + | _ -> false + + checkTailCall (not isContinuation) binding.Expr let warnForBodyExpr = insideSubBindingOrTry diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs index e3ff4102f7c..e1208481308 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs @@ -1683,3 +1683,42 @@ module M = Message = "The member or function 'traverseSequentials' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way." } ] + + [] + let ``Don't warn for rec call of async func that evaluates an async parameter in a match!`` () = + """ +namespace N + +module M = + + [] + let rec f (g: bool Async) = async { + match! g with + | false -> () + | true -> return! f g + } + """ + |> FSharp + |> withLangVersion80 + |> compile + |> shouldSucceed + + [] + let ``Don't warn for rec call of async func that evaluates an async parameter in a let!`` () = + """ +namespace N + +module M = + + [] + let rec f (g: bool Async) = async { + let! x = g + match x with + | false -> () + | true -> return! f g + } + """ + |> FSharp + |> withLangVersion80 + |> compile + |> shouldSucceed