Skip to content

F# 6, nullable and implicit upcasts  #12414

@NinoFloris

Description

@NinoFloris

Found while working on Giraffe, trying to set HttpContext.Response.ContentLength (which expects a Nullable<int64>) the F# compiler gladly accepts code like this:

let x: int = 0
ctx.Response.ContentLength <- x

Which then fails at runtime with System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.Int64'.

Difference at the IL level

Runtime exception:

      IL_001d: ldloc.0      // r
      IL_001e: ldarg.0      // this
      IL_001f: ldfld        unsigned int8[] App.Main/main@151::hw
      IL_0024: ldlen
      IL_0025: conv.i4
      IL_0026: conv.i8
      IL_0027: box          [System.Runtime]System.Int32
      IL_002c: unbox.any    [System.Runtime]System.Int64
      IL_0031: newobj       instance void valuetype [System.Runtime]System.Nullable`1<int64>::.ctor(!0/*int64*/)
      IL_0036: callvirt     instance void [Microsoft.AspNetCore.Http.Abstractions]Microsoft.AspNetCore.Http.HttpResponse::set_ContentLength(valuetype [System.Runtime]System.Nullable`1<int64>)

int64 cast inserted manually:

      IL_001d: ldloc.0      // r
      IL_001e: ldarg.0      // this
      IL_001f: ldfld        unsigned int8[] App.Main/main@151::hw
      IL_0024: ldlen
      IL_0025: conv.i4
      IL_0026: conv.i8
      IL_0027: newobj       instance void valuetype [System.Runtime]System.Nullable`1<int64>::.ctor(!0/*int64*/)
      IL_002c: callvirt     instance void [Microsoft.AspNetCore.Http.Abstractions]Microsoft.AspNetCore.Http.HttpResponse::set_ContentLength(valuetype [System.Runtime]System.Nullable`1<int64>)

Somehow the box + unbox is breaking things due to us boxing it as int32 again

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions