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.87k stars 779 forks source link

Symbols API: Request: Make it easier to detect measureable type definitions #5992

Open alfonsogarciacaro opened 5 years ago

alfonsogarciacaro commented 5 years ago

If I get the typed AST of let value = 0.7833263478179128134089M, the type of value becomes "Microsoft.FSharp.Core.decimal`1", whose .AbbreviatedType is "System.Decimal". But if I check .IsAbbreviation this evals to false, which makes it difficult to know whether I should check the abbreviation or not.

realvictorprm commented 5 years ago

Definitely a bug. @alfonsogarciacaro Does this affect Fable anywhere critical?

alfonsogarciacaro commented 5 years ago

Yes. These two statements print different values in Fable but not in dotnet:

let value = 0.5M
value.GetType().FullName |> printfn "%s" // Microsoft.FSharp.Core.decimal`1
typeof<decimal>.FullName |> printfn "%s" // System.Decimal

But I've found a workaround for now, not sure how correct it is.

alfonsogarciacaro commented 4 years ago

Recently we've found the problem is aggravated with measure annotated abbreviations outside FSharp.Core, like the ones in FSharp.UMX. In that case I haven't found a way to access the abbreviated type, the work around linked in the previous comment doesn't work, not sure why (though I guess it's because the measure annotated abbreviations are hard-coded somewhere in the F# compiler).

dsyme commented 2 years ago

You should look for MeasureAnnotatedAbbreviation attribute (MeasureAnnotatedAbbreviationAttribute) in the attributes of the type definition. In this case, the type represents a new type definition that is a measure-annotated version of the existing type definition. It acts like a new type, and is not automatically expanded to the underlying type except when instantiated with the unit-of-measure "1"