Skip to content

Exception raised during pretty printing #20860

Open

Description

@ingted

Please provide a succinct description of the issue.

Repro steps

open System
open System.Reflection

type InvocableAdapter =
    static member ToFunc (f: Func<'Input[], 'Output>) =
        printfn "[Match] Single Func"
        Func<obj, 'Input[], 'Output>(fun _ args -> f.Invoke(args))

    static member ToFunc (f: Func<'Sender, 'Input[], 'Output>) =
        printfn "[Match] Double Func"
        f

type FSharpFunc<'Input, 'Output> with
    static member ToFunc (f: FSharpFunc<'Input[], 'Output >) =
        printfn "[Match] FSharpFunc"
        Func<obj, 'Input[], 'Output>(fun _ args -> f args)

type InvocableHelper =
    static member inline toInvocable (x: ^T) =
        printfn "12321"
        ((^T or InvocableAdapter) : (static member ToFunc : ^T -> _) x)

let f1 = fun (args: obj[]) -> box (String.concat ", " (args |> Seq.map string))
let f2 = fun _ (args: obj[]) -> box args.Length

let fc1 = Func<obj[], obj>(f1)
let fc2 = Func<obj, obj[], obj>(f2)

let inv2 = InvocableHelper.toInvocable fc2
inv2.Invoke(null, [| 1; 2; 3 |]) |> printfn "fc2: %A"

let inv1 = InvocableHelper.toInvocable fc1
inv1.Invoke(null, [| "A"; "B" |]) |> printfn "fc1: %A"

let invF1 = InvocableHelper.toInvocable f1
invF1.Invoke(null, [| "A"; "B" |]) |> printfn "f1: %A"

Expected behavior

No excpetions.

Actual behavior

> 
12321
[Match] FSharpFunc


Exception raised during pretty printing.
Please report this so it can be fixed.
Trace: System.InvalidCastException: Unable to cast object of type 'System.Func`3[System.Object,System.Object[][],System.Object]' to type 'System.Func`3[System.Object,System.Object[],System.Object]'.
   at FSharp.Compiler.Interactive.Shell.Utilities.AnyToLayoutSpecialization`1.FSharp.Compiler.Interactive.Shell.Utilities.IAnyToLayoutCall.FsiAnyToLayout(FormatOptions options, Object o, Type ty) in D:\a\_work\1\s\src\fsharp\src\Compiler\Interactive\fsi.fs:line 101
   at FSharp.Compiler.Interactive.Shell.FsiValuePrinter.PrintValue(FsiValuePrinterMode printMode, FormatOptions opts, Object x, Type ty) in D:\a\_work\1\s\src\fsharp\src\Compiler\Interactive\fsi.fs:line 727
val invF1: Func<obj,obj array,objnull> = 

> 

Known workarounds

No.

Related information

  • Operating system: Win server 2019
  • .NET Runtime kind (.NET Core, .NET Framework, Mono): F# Interactive version 15.2.101.0 for F# 11.0
  • Editing Tools (e.g. Visual Studio Version, Visual Studio): Visual Studio 2026 Insiders.

Activity

  1. added theissue type on Oct 24, 2026
  2. added this to the Backlog milestone on Oct 24, 2026
  3. ingted commented on Oct 24, 2026

    @ingted
    ContributorAuthor

    PS. The code works even the assignment of invF1. If you run and stop at let invF1 = xxxx. After the exception shows, the last expression still works.

    invF1.Invoke(null, [| "A"; "B" |]) |> printfn "f1: %A"
    

    leads

    > 
    f1: "A, B"
    val it: unit = ()
    
    > 
    
  4. ingted commented on Oct 24, 2026

    @ingted
    ContributorAuthor

    PS. The same code doesn't work in older fsi, e.g. version F# Interactive version 15.2.203.0 for F# 10.0

    > let invF1 = InvocableHelper.toInvocable f1
    -
    - invF1.Invoke(null, [| "A"; "B" |]) |> printfn "f1: %A"
    -
    - ;;
    
      let invF1 = InvocableHelper.toInvocable f1
      ------------^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    stdin(70,13): error FS0043: No overloads match for method 'ToFunc'.
    
    Known return type: 'a
    
    Known type parameter: < (obj array -> objnull) >
    
    Available overloads:
     - static member InvocableAdapter.ToFunc: f: Func<'Input array,'Output> -> Func<obj,'Input array,'Output> // Argument 'f' doesn't match
     - static member InvocableAdapter.ToFunc: f: Func<'Sender,'Input array,'Output> -> Func<'Sender,'Input array,'Output> // Argument 'f' doesn't match
    
    
      invF1.Invoke(null, [| "A"; "B" |]) |> printfn "f1: %A"
      ^^^^^^^^^^^^
    
    stdin(72,1): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
    
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

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions