Parametric Event Compiles But Crashes Server

Summary

This Snippet Compiles Just Fine. Crashes Server On Begin

Please select what you are reporting on:

Verse

What Type of Bug are you experiencing?

Verse

Steps to Reproduce

Copy Snippet, Compile, Drag Device Into World, Start Session, Click Start Game

Expected Result

IDE to either detect errors or Code Runs Properly

Observed Result

Server Crashes

Platform(s)

Windows

Additional Notes

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

mutable_logic := class{var AllowInvoke : logic = true}
        
cancelable_callback(t:type) := class:
    Logic : mutable_logic = mutable_logic{}
    Cancel()<transacts>:void={set Logic.AllowInvoke = false}
    Callback : type{func(:t):void}
    Invoke(T:t):void={if(Logic.AllowInvoke?){Callback(T)}}

(Func:type{func(:t):void} where t:type).ToCallback()<transacts>:cancelable_callback(t)=
    cancelable_callback(t){Callback := Func}

generic_event(payload:type) := class:

    Callbacks : []cancelable_callback(payload) = array{}

    AwaitHandle : event(payload) = event(payload){}

    Subscribe(Callback:cancelable_callback(payload)):tuple(generic_event(payload), cancelable_callback(payload))=
        var NewCallbacks : []cancelable_callback(payload) = Callbacks
        set NewCallbacks += array{Callback}
        NewSelf := generic_event(payload){Callbacks := NewCallbacks}
        return (NewSelf, Callback)

    Signal(Payload:payload):void=
        AwaitHandle.Signal(Payload)
        for(Callback:Callbacks){Callback.Invoke(Payload)}

    Await()<suspends>:payload=
        Value := AwaitHandle.Await()
        return Value

TestClass := class(creative_device):

    var PlayerEvent : generic_event(player) = generic_event(player){}
    var PlayerEventSubs : []cancelable_callback(player) = array{}

    OnBegin<override>()<suspends>:void=
        NewSub := PlayerEvent.Subscribe(TestPlayerFunc.ToCallback())
        set PlayerEvent = NewSub(0)
        set PlayerEventSubs += array{NewSub(1)}

        for(Player:GetPlayspace().GetPlayers()){PlayerEvent.Signal(Player)}

        for(i := -5..-1){Print("Canceling in {Abs(i)}"); Sleep(1.0)}

        for(Sub:PlayerEventSubs){Sub.Cancel()}

        for(Player:GetPlayspace().GetPlayers()){PlayerEvent.Signal(Player)}

    TestPlayerFunc(Player:player):void=
        Print("Test", ?Duration := 5.0)

This is a bug, and will be fixed in a future release. The issue is the parametric type lattice join operator is too coarse, and thinks the result is []any when not used with a var (e.g. Callbacks + array{Callback} is considered to have type []any) and results in a crash when used with a var.

2 Likes

Thanks for the response!

Any timeline on when that fix might be merged?