Conditionals in repeat and while loops should refine types like if statements

Take a look at these code snippets:

local goingToHaveValue: boolean?
while goingToBeTrue == nil do
    task.wait()
end
goingToHaveValue = not goingToHaveValue --> invalid (might be nil)
local goingToHaveValue: boolean?
repeat
    task.wait()
until goingToBeTrue ~= nil
goingToHaveValue = not goingToHaveValue --> invalid (might be nil)

In both snippets above, a loop is run until a conditional has a value. Now, the conditional will always have a value after the loop completes. There are zero cases in which goinToHaveValue will have no value after the execution of the shown repeat and while loops. Thus, goingToHaveValue should correctly be typed as boolean instead of boolean? after the loops.

However, I understand there are edge cases, such as when break is involved:

local goingToHaveValue: boolean?
while goingToBeTrue == nil do
    task.wait()
    if someValue == true then
        break --> broke out of the loop early!
    end
end
goingToHaveValue = not goingToHaveValue --> invalid (might be nil)

In this case, goingToHaveValue obtaining the inferred type boolean? is valid.

4 Likes