[Verse] listenable .Await() in loop not recognized as async - false positive 3538/3579

Summary

Verse static analysis incorrectly reports error 3538 (“All the top level expressions in a ‘race’ macro must be async… and not immediate”) and error 3579 (“loop must have one or more subexpressions that are either async… or a jump out”) on a loop whose first, unconditional expression is a suspending .Await() on a scene-graph mesh_component.EntityEnteredEvent / EntityExitedEvent. These events are listenable(entity), and awaitable.Await() is <suspends>, so the loop already contains an async subexpression. Adding a redundant Sleep(0.0) to the loop body suppresses both errors, confirming the analyzer only recognizes Sleep and not the listenable .Await() as async. Note that this is an editor-time diagnostic only (surfaced in VS Code) and does not block compilation. Building Verse code succeeds as expected, so the reported “errors” are false positives from the static analyzer rather than genuine compilation failures.

Please select what you are reporting on:

Verse

What Type of Bug are you experiencing?

Scene Graph

Steps to Reproduce

  1. In a <suspends> context, get a mesh_component reference (Mesh).
  2. Write a race containing two loop blocks, each whose first expression awaits a scene-graph event with no Sleep. Example:
race:
    loop:
        Ent := Mesh.EntityEnteredEvent.Await()
        #Sleep(0.0)
    loop:
        Ent := Mesh.EntityExitedEvent.Await()
        #Sleep(0.0)
  1. Observe the diagnostics on each loop block.
  2. Uncomment Sleep(0.0) in both loops and the errors clear.

Expected Result

The code compiles with no diagnostics. mesh_component.EntityEnteredEvent / EntityExitedEvent are listenable(entity); listenable := interface(awaitable, subscribable) and awaitable.Await()<suspends>. Each loop’s first expression is therefore async, satisfying both the race async-top-level requirement (3538) and the loop non-immediate-iteration requirement (3579). No Sleep should be needed.

Observed Result

Errors 3538 and 3579 are raised on each loop block:

code 3538: All the top level expressions in a `'race' macro` must be async (such as a coroutine call) and not immediate.
code 3579: To prevent infinite immediate iteration, `loop` must have one or more subexpressions that are either async (such as a coroutine) or a jump out (such as `break` or `return`).

Both fire on each loop’s line range. Adding Sleep(0.0) as the last expression in each loop clears both errors, confirming the analyzer does not treat the listenable .Await() as suspending.

Platform(s)

Windows (UEFN editor / Verse static analysis). Editor-time diagnostic only.

FORT-1124468 has been created and its status is ‘Unconfirmed’. This is now in a queue to be reproduced and confirmed.