Skip to content

Incorrect TailCall warning on async recursive functions  #17237

@kdurkin77

Description

@kdurkin77

When we use the TailCall attribute on an async recursive function, that actually has an async call, we get a warning that it's not being used in a tail recursive way, but it should be

Examples below:

[<TailCall>] //Has Warning
let rec f'1 (g: bool Async) = async {
    match! g with
    | false -> ()
    | true -> return! f'1 g
    }


[<TailCall>] //Has Warning
let rec f'2 (g: bool Async) = async {
    let! x = g
    match x with
    | false -> ()
    | true -> return! f'2 g
    }

[<TailCall>] //No Warning
let rec f'3 (g: bool) = async {
    match g with
    | false -> ()
    | true -> return! f'3 g
    }

Repro steps

  1. Create an f# project
  2. Create a recursive function that has an async call and use the TailCall attribute.
  3. Build, and notice the warning

Sample sln:
TailCallTest.zip

Expected behavior
No warnings

Actual behavior
Warnings display in output

warning FS3569: The member or function 'f'1' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way.
warning FS3569: The member or function 'f'2' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way.

Known workarounds
Remove the TailCall attribute, but I am unsure if this is actually running as a TailCall

Related information

Provide any related information (optional):
Occurs in .net8.0, .net6.0, .net5.0
Visual Studio 17.9.7 and 17.10.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-Compiler-CheckingType checking, attributes and all aspects of logic checkingBugImpact-Low(Internal MS Team use only) Describes an issue with limited impact on existing code.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions