Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.400.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Fixed

* Fix a false positive of the `[<TailCall>]` 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))
Expand Down
13 changes: 12 additions & 1 deletion src/Compiler/Checking/TailCallChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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." }
]

[<FSharp.Test.FactForNETCOREAPP>]
let ``Don't warn for rec call of async func that evaluates an async parameter in a match!`` () =
"""
namespace N

module M =

[<TailCall>]
let rec f (g: bool Async) = async {
match! g with
| false -> ()
| true -> return! f g
}
"""
|> FSharp
|> withLangVersion80
|> compile
|> shouldSucceed

[<FSharp.Test.FactForNETCOREAPP>]
let ``Don't warn for rec call of async func that evaluates an async parameter in a let!`` () =
"""
namespace N

module M =

[<TailCall>]
let rec f (g: bool Async) = async {
let! x = g
match x with
| false -> ()
| true -> return! f g
}
"""
|> FSharp
|> withLangVersion80
|> compile
|> shouldSucceed