Skip to content

Debug: FS2014 duplicate <f>__debug@N in method table for an inline call inside a resumable CE whose Run has caller-info parameters (regression in 11.0.100-rc.2) #20836

Open

Description

@jbtule

Repro

Lib.fs, in a net10.0 library, built with dotnet build -c Debug on SDK 11.0.100-rc.2.26504.105:

module Lib
#nowarn "3513"
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
open Microsoft.FSharp.Core.CompilerServices
open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers

[<Struct; NoEquality; NoComparison>]
type D<'T> = { mutable Result: 'T }

type B() =
    member inline _.Delay([<InlineIfLambda>] f: unit -> ResumableCode<'D, 'T>) =
        ResumableCode<'D, 'T>(fun sm -> (f ()).Invoke(&sm))
    member inline _.Return(v: 'T) = ResumableCode<D<'T>, 'T>(fun sm -> sm.Data.Result <- v; true)
    member inline _.Run(code: ResumableCode<D<'T>, 'T>,
                        [<CallerLineNumber; Optional; DefaultParameterValue(0)>] line: int) : 'T =
        if __useResumableCode then
            __stateMachine<D<'T>, 'T>
                (MoveNextMethodImpl<D<'T>>(fun sm -> __resumeAt sm.ResumptionPoint; code.Invoke(&sm) |> ignore))
                (SetStateMachineMethodImpl<D<'T>>(fun _ _ -> ()))
                (AfterCode<D<'T>, 'T>(fun sm -> sm.Data.Result))
        else
            let mutable sm = ResumableStateMachine<D<'T>>()
            code.Invoke(&sm) |> ignore
            sm.Data.Result

let b = B()
let f () : int = b { return [ 3 ] |> List.sum }

Result

error FS2014: A problem occurred writing the binary 'obj/Debug/net10.0/refint/repro.dll': Error in pass2 for type Lib, error: duplicate entry '<sum>__debug@28' in method table

Narrowing

Variation rc.2 Debug
As above FS2014
-p:ProduceReferenceAssembly=false FS2014 (on the main dll instead of refint)
Run without the [<CallerLineNumber>] parameter builds
Body without an inline call (b { return 3 }) builds
task { return [ 3 ] |> List.sum } builds
Non-resumable builder with the same caller-info Run builds
Release builds
Same repro on SDK 11.0.100-rc.1.26425.128 (Debug) builds

In a builder of the same shape (no inline call in the body), rc.2 Debug now emits the state-machine struct and the dynamic-path closures for one CE, where rc.1 Debug emitted only the closure. So both branches of if __useResumableCode seem to survive, and an inline call in the body is specialized once per branch, under the same <f>__debug@<line> name. This looks related to #20469 ("Preserve resumable state-machine lowering in Debug"), merged between rc.1 and rc.2.

Found in https://github.com/ekonbenefits/FSharp.Interop.Dlr (its dlr { } builder has this Run shape), where any dlr { } that calls an inline function fails to build in Debug on rc.2: ekonbenefits/FSharp.Interop.Dlr#235.

Activity

  1. added this to the Backlog milestone on Oct 21, 2026
  2. auduchinok commented on Oct 21, 2026

    @auduchinok
    Member

    I'll look at it.

  3. added
    Area-Debugstepping, debug points, stacks and more
    and removed on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-Debugstepping, debug points, stacks and more

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions