dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.93k stars 788 forks source link

FSharpType.Format(displayContext) should take into account flexible types #17915

Open DedSec256 opened 1 month ago

DedSec256 commented 1 month ago

There is an API (FSharpType.Format(displayContext)) that provides a common way to present F# types to show in the editor. But for flexible types (where generic parameters with the constraint are just compiler/runtime implementation details), Format returns the name of the generic parameter, which can be confusing, since the code explicitly specifies the type written as #IDisposable ( & ... & ... ), so the name of the generic parameter appears out of nowhere and at the moment does not reflect the expected type information (especially suitable for the editor) in any way.

Repro steps

Enable inlay type hints in editor

open System

let f (disposables: #IDisposable list) =
    for x in disposables do () 

Expected behavior

For x provided expected type as #IDisposable

Actual behavior

Rider Image

VS Code Image

Visual Studio Image

Example of FSharpType for #IDisposable Image

I would expect that this API fully formats the flexible type, providing ready information for the editor

T-Gro commented 1 month ago

I don't thing globally moving from short names to (potentially) very long names can work at all places. But given a displayContext switch, a long name could be assembled from the generic constraints.

vzarytovskii commented 1 month ago

I don't thing globally moving from short names to (potentially) very long names can work at all places. But given a displayContext switch, a long name could be assembled from the generic constraints.

Important question would be to which extent we want to reassemble it from constraint? Only type constraints? What about nullness constraints (do we do it already?)?

T-Gro commented 1 month ago

The nullable annotation is added to each variable if the generic typar is not nullable, but some usages are using `T | null' :

Image