dotnet / dotnet/fsharp

Cannot assign to byref-returning type functions

Open
#18,313 0 comments 0 reactions 0 assignees View on GitHub
Area-Compiler-Checking Area-Compiler-Checking-Byref Bug Impact-Low
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 22h
Merged PRs (30d)
144

Description

When a `let`-bound value with type parameters is of a `byref` type, assignment to this value incorrectly requires a `byref` value.

**Repro steps**

```fs
type Storage<'T> =
static let mutable value = Unchecked.defaultof<'T>
static member public ValueRef = &value

[]
let cached<'T>: byref<_> = &Storage<'T>.ValueRef

do
cached <- 1
()
```

**Expected behavior**

The assignment succeeds and results in a modification to `Storage.value`.

**Actual behavior**

The assignment fails to compile:
```
error FS0001: This expression was expected to have type
'byref'
but here has type
'int'
```

The compiler can detect that the value is mutable (otherwise there would be an error about assignment to non-mutable location), but a wrong type is required.

**Known workarounds**

Turning the value into a normal function (i.e. `let cached<'T>()` and `cached() <-` works fine.

**Related information**

It seems this issue affects all uses of `cached<'T>` that involve byrefs or assignments, for example:
```fs
do
let mutable r: byref<_> = &cached // Expecting a 'byref>' but given a 'inref>'

let mutable a = 1
a <- cached // expected to have type 'int' but here has type 'byref'

cached <- &a // Type 'byref>' is illegal because in byref, T cannot contain byref types.
```

Environment: https://sharplab.io/#v2:DYLgZgzgPgLgngBwKYAIDKMD2AnAhgcyQB4ByAFQD4UBeAWACgUUIZcYBLAYxWCRhQC2AV1YAjXigBuuYENTUUAVQB2nABZJOAayQATAHS6kYXEOBYwpSgyYs2XQUgGik2FAiHiHANRlyASsY0KABk0rJIDAwA2kQA4kjKrjLsAF644ki+ERQAugy8/Jy46npWFCAoonDYxkQA+lQKIRg4BMTkFPrZAcZR9LqYNijFpbpE7MowVEQAtCgAjMMAFACUDEA===

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.