Skip to content

Unnecessary(?) breaking change in FSharp.Core 9.0.100: ofObj now requires not struct as well as null #18320

Description

@pleaseletmesearch

This code works with FSharp.Core 8.0.100:

moduleFoo =letfailIfNull<'awhen'a:null>(a :'a):'a =
a |> Option.ofObj |> Option.orFail "hi"

In FSharp.Core 9.0.100, it does not compile:

error FS0001: Type mismatch. Expecting a� ''a -> 'b' �but given a� ''a -> 'a option' �A type parameter is missing a constraint 'when 'a: not struct'

The null constraint should surely already imply not struct? The docs at https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/generics/constraints say "This [not null] generic constraint does allow value types, since those can never be null.", which suggests that the null constraint logically implies the not struct constraint.

Repro steps

Thing.fsproj

<ProjectSdk="Microsoft.NET.Sdk">
<PropertyGroup><TargetFramework>netstandard2.0</TargetFramework></PropertyGroup>
<ItemGroup><CompileInclude="Thing.fs" /></ItemGroup>
<ItemGroup><PackageReferenceUpdate="FSharp.Core"Version="9.0.100" /></ItemGroup>
</Project>

Thing.fs

namespaceBlahmoduleFoo =let inlineorFail(err:string)(option :'a Option)=match option with| Some a -> a
| None -> failwith err
letfailIfNull<'awhen'a:null>(a :'a):'a =
a |> Option.ofObj |> orFail "hi"

Observe the compile error; then downgrade FSharp.Core to 8.0.100 and observe the compile success.

Known workarounds

  • Edit user code to add the (apparently redundant?) constraint not struct.
  • Don't upgrade FSharp.Core.

Provide a description of any known workarounds.

Related information

I'm using SDK 9.0.200 on linux-x64.

Metadata

Metadata

Assignees

Type

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions