dotnet / dotnet/fsharp

Units of Measure - non-Measure type parameter can be passed as a Measure parameter

Open
#10,824 10 comments 1 reaction 1 assignee Claimed by @dsyme View on GitHub
Area-Compiler-Checking Area-UoM Bug Impact-Low
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

The following code compiles and works fine in debug mode, however in release mode it compiles, but then throws a `MissingMethodException` when run.

Given a file in project `Lib`:
```fsharp
module Lib

open System

type Id<[] 'T> =
private
{ Id: Guid }

static member Create<'T> id: Id<'T> =
if id = Guid.Empty then
invalidArg (nameof (id)) "ID cannot be empty"
else
{ Id = id }

static member New<'T>(): Id<'T> = { Id = Guid.NewGuid() }

member this.Value = this.Id
```

And the following file in project `App` with a reference to project `Lib`:
```fsharp
module App

open System
open Lib

[] type product

type Product = { Id: Id; Name: string }

let displayProduct p = printfn $"{p.Id.Value} - {p.Name}"

[]
let main argv =

let bananas = { Id = Id.New(); Name = "bananas" }
displayProduct bananas

let pancakes = { Id = Guid("47367575-1ea9-49b8-9720-9f9b869ddf17") |> Id.Create; Name = "pancakes" }
displayProduct pancakes
0
```

Provide the steps required to reproduce the problem:

1. You can successfully compile this code with the debug or release configuration:
```
dotnet build App --configuration Release
Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

Determining projects to restore...
All projects are up-to-date for restore.
Lib -> C:\Code\uom-issue\Lib\bin\Release\net5.0\Lib.dll
App -> C:\Code\uom-issue\App\bin\Release\net5.0\App.dll

Build succeeded.
0 Warning(s)
0 Error(s)
```
2. You can also run the code in debug mode without issues:
```
C:\Code\uom-issue> dotnet run --project App --configuration Debug
c94d0902-7476-454e-bfac-e0cddd42372b - bananas
47367575-1ea9-49b8-9720-9f9b869ddf17 - pancakes
```
3. However in release mode it throws an exception:
```
C:\Code\uom-issue> dotnet run --project App --configuration Release
Unhandled exception. System.MissingMethodException: Method not found: 'Id Id.New()'.
at App.main(String[] argv)
```

[Sample.zip](https://github.com/dotnet/fsharp/files/5755639/Sample.zip)

**Expected behavior**

I would expect the code to either fail to compile in both configuration OR run fine in both configurations.

**Known workarounds**

When the type annotations on the `Create` and `New` method are removed everything works fine, i.e. when the code in the library is changed to this:

```fsharp
module Lib

open System

type Id<[] 'T> =
private
{ Id: Guid }

static member Create id =
if id = Guid.Empty then
invalidArg (nameof (id)) "ID cannot be empty"
else
{ Id = id }

static member New() = { Id = Guid.NewGuid() }

member this.Value = this.Id
```

**Related information**

Provide any related information (optional):

* Operating system: Windows 10 20H2
* .NET 5.0.101

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.