Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"try with" within seq fails to capture exception variable #17930

Closed
Gradi opened this issue Oct 28, 2024 · 4 comments · Fixed by #17990
Closed

"try with" within seq fails to capture exception variable #17930

Gradi opened this issue Oct 28, 2024 · 4 comments · Fixed by #17990
Assignees
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Bug
Milestone

Comments

@Gradi
Copy link

Gradi commented Oct 28, 2024

F# code like

seq {
    try
        ...
    with
    | :? SomeException as exc when (exc.InnerException :? Some2Exception)
}

fails to be compiled because exc is not available in (exc.InnerException :? Some2Exception) environment.

This probably happens somewhere within part of compiler which transforms computational expressions into calls to builder.

Repro steps

Here is minimal source code with bug.

module Program

open System

// This is OK
let sample () =
    try
        printfn "Hi"
    with
    | :? AggregateException as exc when (exc.InnerException :? OperationCanceledException) ->
        ()


// This is OK
let asyncSample () : Async<unit> =
    async {
        try
            printfn "Hi"
        with
        | :? AggregateException as exc when (exc.InnerException :? OperationCanceledException) -> ()
    }

(*
** This fails with
** 0>Program.fs(26,9): Error FS0971 : Undefined value 'exc'
** 0>Program.fs(26,9): Error FS0971 : Undefined value 'exc'
** 0>Program.fs(26,9): Error FS0971 : Undefined value 'exc'
** 0>Program.fs(26,9): Error FS0971 : Undefined value 'exc'
** 0>Program.fs(26,9): Error FS0971 : Undefined value 'exc'
*)
let seqSample () : int seq =
    seq {
        try
            printfn "Hi"
        with
        | :? AggregateException as exc when (exc.InnerException :? OperationCanceledException) -> ()
    }


// This is OK
let seqSample2 () : int seq =
    seq {
        try
            printfn "Hi"
        with
        | :? AggregateException as exc when (true) -> ()
    }

[<EntryPoint>]
let main argv =
    0

Expected behavior

  • Code compiles, when cases of try with within seq can access exception variable;
  • OR As far as I remember, F# didn't have support for try with within seq before version 8.0. If my case is not allowed by design, then a good readable warning by compiler;

Actual behavior

Compilation fails with Undefined value 'exc'.

Related information

  • dotnet version 8.0.403;
  • F# version 12.8.401.0 for F# 8.0;
  • Rider and Visual Studio(Ionide) code show no red lines near problematic lines;
@T-Gro
Copy link
Member

T-Gro commented Oct 29, 2024

This is indeed a bug related to how try-with in seq gets lowered during compilation into a state machine.

As a workaround, you can accomplish the goal by abstracting the check into an active pattern:

open System


let (|AggCanceled|_|) (exn:Exception) =
    match exn with
    | :? AggregateException as exc  when (exc.InnerException :? OperationCanceledException)  -> Some exc
    | _ -> None

let seqSample () : int seq =
    seq {
        try
            printfn "Hi"
        with
        | AggCanceled ac  -> yield ac.InnerExceptions.GetHashCode()
    }

https://sharplab.io/#v2:DYLgZgzgPg9gDgUwHYAIDKBPCAXBBbAWAChjjgFsUAKKAQQHN6BhAQyQGMFyATKAfSgBKaggAeSEAFFRnONgCWMJMIC8xFBpR4W2dgAsUY1AHd52Pes1QUIAPwoG9AE4J6OhNNkKlKFhEMyGsZ6yCIyAHQAkkhICE6eCHKKqHYoAPKITjrJrBxcCNwJSUrCKAC0AHzoMHgIAeyWGtZ85VUAckoIpETklBAIAI5oLHhw5NTCICjySH2DKGpEmij9AygA3o3LKNhOGFvbmnBOM9hgqABEABLyFweapub3TQ6MuZw8vuwalSgY8lxuF8ojE4kVvEgIOEAOIUK5+PRMGDcBBUQRbAC+QA===

Will this help in your use case?

@Gradi
Copy link
Author

Gradi commented Oct 29, 2024

@T-Gro This probably can help me, but I have already rewrote code to something different to get job done. But this is still a bug which will be fixed at some point in time, right?

@T-Gro
Copy link
Member

T-Gro commented Oct 29, 2024

Yes, it is a bug and needs fixing.

@T-Gro T-Gro modified the milestones: Backlog, November-2024 Oct 29, 2024
@vzarytovskii
Copy link
Member

Disregard my (now deleted) comment.

In .NET 6 we had the following:

dotnet build
MSBuild version 17.3.2+561848881 for .NET
  Determining projects to restore...
  Restored /Users/u/code/issues/gh/17930/17930.fsproj (in 134 ms).
/Users/u/code/issues/gh/17930/Program.fs(33,9): error FS0796: 'try'/'with' cannot be used within sequence expressions [/Users/u/code/issues/gh/17930/17930.fsproj]
/Users/u/code/issues/gh/17930/Program.fs(43,9): error FS0796: 'try'/'with' cannot be used within sequence expressions [/Users/u/code/issues/gh/17930/17930.fsproj]

Build FAILED.

/Users/u/code/issues/gh/17930/Program.fs(33,9): error FS0796: 'try'/'with' cannot be used within sequence expressions [/Users/u/code/issues/gh/17930/17930.fsproj]
/Users/u/code/issues/gh/17930/Program.fs(43,9): error FS0796: 'try'/'with' cannot be used within sequence expressions [/Users/u/code/issues/gh/17930/17930.fsproj]
    0 Warning(s)
    2 Error(s)

Time Elapsed 00:00:01.58

Which has changed in #14540

In rc2 we fail to bind exc

@T-Gro T-Gro self-assigned this Nov 7, 2024
@T-Gro T-Gro moved this from New to In Progress in F# Compiler and Tooling Nov 11, 2024
@T-Gro T-Gro added Area-Compiler-Checking Type checking, attributes and all aspects of logic checking and removed Needs-Triage help wanted labels Nov 11, 2024
@github-project-automation github-project-automation bot moved this from In Progress to Done in F# Compiler and Tooling Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Bug
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants