Skip to content

"error FS0192: internal error: duplicate entry in type index table" with simple code #19156

Description

@mlaily

Compiling the following snippet in a dotnet interactive session (either in Visual Studio Code or with the command line dotnet fsi) fails with an error similar to error FS0192: internal error: duplicate entry 'f@6' in type index table (with an entry name that is not constant):

open System

let f (start: DateTime) (stop: DateTime) (input: (DateTime * 'a) list) =
    [
        for i in start.Ticks .. stop.Ticks ->
            input |> List.where (fun (k, v) -> true)
    ]

I wasn't able to isolate the problem further.

This is also failing in a Polyglot Notebook with error input.fsx (1,1)-(1,1) interactive error internal error: Duplicate type name within an assembly....

Known workarounds

I couldn't find any.

Related information

Provide any related information (optional):

I'm running Windows 11, and I just updated my .NET SDK version just in case:

> dotnet --info
.NET SDK:
 Version:           10.0.101
 Commit:            fad253f51b
 Workload version:  10.0.100-manifests.9f71effe
 MSBuild version:   18.0.6+fad253f51

[...]

Activity

  1. added theissue type on Dec 12, 2025
  2. majocha commented on Dec 13, 2025

    @majocha
    Contributor

    workaround is to materialize the range:

    let range = [ start.Ticks .. stop.Ticks ]
    for i in range -> ...

    As for the fix:
    Claude Opus with some guidance found the error and wrote a working solution. Remarkable.

    The cause is duplicating body expression in mkOptimizedRangeLoop and the fix is to copy the expression in mkCond to not emit lambda with same stamp twice.

    I have no time atm to make a proper PR but this change to mkOptimizedRangeLoop does the trick:

            | RangeCount.PossiblyOversize calc ->
                calc (fun count wouldOvf ->
                    buildLoop count (fun mkBody ->
                        // mkBody creates expressions that may contain lambdas with unique stamps.
                        // We need to copy the expression for the second branch to avoid duplicate type names.
                        let mkBodyCopied idxVar loopVar = copyExpr g CloneAll (mkBody idxVar loopVar)
                        mkCond
                            DebugPointAtBinding.NoneAtInvisible
                            mIn
                            g.unit_ty
                            wouldOvf
                            (mkCountUpInclusive mkBody (tyOfExpr g count))
                            (mkCompGenLetIn mIn (nameof count) (tyOfExpr g count) count (fun (_, count) -> mkCountUpExclusive mkBodyCopied count))))
  3. brianrourkeboll commented on Dec 13, 2025

    @brianrourkeboll
    Contributor

    FWIW, another workaround until this is fixed should be to set the language version to 8 (or lower). That will make the compiler use the older way of lowering ranges + comprehensions.

  4. mlaily commented on Dec 15, 2025

    @mlaily
    Author

    That was very quick! Thanks!

  5. added a commit that references this issue on Dec 15, 2025
    7a09e87
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions