dotnet / dotnet/fsharp

Calling a member inferred from a reference-typed generic constraint unnecessarily boxes the value.

Open
#10,499 0 comments 0 reactions 0 assignees View on GitHub
Area-Compiler-Optimization Feature Improvement
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

When calling a method on a generic value that is constrained to be a reference type, the compiler mistakenly emits a `box` and `unbox.any` sequence of commands.

**Repro steps**

Compile the following function:

``` fsharp
let getDelegateMethod<'TDelegate when 'TDelegate :> System.Delegate> (del: 'TDelegate) = del.Method
```

**Expected behavior**

The generated IL should be:

```
ldarg.0
callvirt instance class [System.Private.CoreLib]System.Reflection.MethodInfo [System.Private.CoreLib]System.Delegate::get_Method()
ret
```

**Actual behavior**

The generated IL is:

```
ldarg.0
box !!TDelegate
unbox.any [System.Private.CoreLib]System.Delegate
callvirt instance class [System.Private.CoreLib]System.Reflection.MethodInfo [System.Private.CoreLib]System.Delegate::get_Method()
ret
```

**Known workarounds**

None

**Related information**

Calling the method using `constrained.callvirt` is not necessary; we surely have a reference type and just a `callvirt` suffices.

* .NET Runtime kind: .NET SDK 5.0.100

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.