Reproduction Steps
In addition to this report I made earlier: Return of the "Unknown require" ghost warning in Team Create
I am seeing ghost warnings related to for loops in strict mode, which disappear the moment you open a script.
I cannot create a consistent repro for this, as these ghost warnings only show up some of the time.
These warnings appear on random scripts sometimes when I open a team create place (linked privately):
My interpretation of the first ghost warning
The line of code emitting this warning pertains to a variable interiorId_Symbol
which initialized in a for loop with no annotation, meaning its type should be inferred
Here is where it is initialized:
The type of the table being iterated over is
{[string]: number}
; therefore the inferred type of interiorId_Symbol
as a key of this table should be string
.However, there seems to be some kind of race condition or something, because
interiorId_Symbol
is inferred to be of type string?
due to what happens later in the for loop:Quite simply, a variable
interiorId
is initialized with a type annotation string?
, and on a certain conditions, interiorId
is assigned to interiorId_Symbol
. Therefore, since interiorId_Symbol
is not annotated, it overrides the inference in the for loop, and instead infers it as string?
since that’s the type of interiorId
.
The for loop should take precedence in inferring the type here as per bidirectional typechecking.
My interpretation of the second two ghost warnings
This example has much simpler code:
--!strict
local SoundService = game:GetService('SoundService')
local RunService = game:GetService("RunService")
local FETCH_ASSET_TIMEOUT = 2
local playingEmitters: {[any]: {any}} = {}
RunService.RenderStepped:Connect(
function()
for emitter, data in pairs(playingEmitters) do
local sound = data[1]
local startTime = data[2]
local hasLoaded = data[3]
local shouldDestroy = false
if hasLoaded then
if (sound.TimePosition == 0) then
shouldDestroy = true
end
else
if sound.TimeLength > 0 then
data[3] = true
elseif os.clock() - startTime > FETCH_ASSET_TIMEOUT then
shouldDestroy = true
end
end
if shouldDestroy then
sound:Stop()
emitter:Destroy()
playingEmitters[emitter] = nil
end
end
end
)
In this case, data
should be typed as {any}
, but instead it tries to infer the type as (a verbose/partial version of) {Sound}
from the local sound = data[1]
line.
The for loop should take precedence with bidirectional typechecking here, but it seems to try to infer this type twice through two different means, the for loop sometimes not winning out.
Here is a repro with both modules, although it is very hard to get this bug to consistently show up—I see this happen from 1-2 random scripts every time I open my team create place, and always from a for loop with inferred control variable types:
ghostforloopwarningrepro.rbxl (35.3 KB)
Expected Behavior
The type of the table being iterated over in a pairs
for loop should take precedence when inferring the types of the control variables.
Actual Behavior
Some kind of race condition (possibly related to this team create issue?) causes the proper type inference to be overridden.
Workaround
Clicking on the scripts gets rid of these warnings; however, it’s still super annoying to have to deal with this every time I open my team create place. Just adds unnecessary waste to my workflow.
Issue Area: Studio
Issue Type: Other
Impact: Moderate
Frequency: Constantly
Date First Experienced: 2022-01-14 00:01:00 (-07:00)
Date Last Experienced: 2022-01-16 00:01:00 (-07:00)
A private message is associated with this bug report