Script analysis erroneously warns about implicit nil returns for unreachable code

It looks like some opinionated script analysis warnings have been enabled for warnings W016 and W009, related to functions that implicitly return nil and return a non-value in other places, as well as unused variables

However, I have a case in which this warning is incorrect (this is a binary search to calculate a weighted random which always terminates):

Because I am using repeat until false, all code following the until false statement should be unreachable EXCEPT in the case that the loop breaks (which it doesn’t); however, script analysis still complains about this because it doesn’t understand that this portion of code is unreachable.

Contrived example of the issue:

local function alwaysReturnsTrue()
    local x = 0
    repeat
        if x == 3 then
            return true
        end
        x = x + 1
    until false
end

Alternate form:

local function alwaysReturnsTrue()
    local x = 0
    while true do
        if x == 3 then
            return true
        end
        x = x + 1
    end
end

In this case, the code after while true do . . . end is also unreachable, but a similar error is produced.

It seems like these warnings were turned on a bit prematurely… especially the one about implicit returns, it has to know a bit about type inference and control flow to be able to make an opinion like this. However, since Luau isn’t released yet (I have not enabled strict mode, nor do I have the beta feature enabled), it seems like this shouldn’t be enabled yet unless it can actually whether code like this is reachable.

In a language like TypeScript, it will check for the same thing, but it can tell that the block is unreachable, because the condition in the repeat/while block is a literal boolean type, so it doesn’t emit a similar error.

Yeah, I noticing those type of warning too in this new update. I thought I was the only one, I went from having no warning to 84 of them after the update. And all of them are related to not returning a value right after something like a if statement even though I have a return statement at the end of the same function.

Can you share an example of this code?

I’m running into the same issue,

If it’s alright with you I can DM you it.

Thanks, that’s a bug in the analysis.

Note that this is not quite correct:

In that we don’t need type information to understand that in this case the implicit return point isn’t reachable.

We’ve disabled this for now since we’ll need to fix the functions with infinite loops.

1 Like
function coreFunctions.ServiceDescendant(object) -- First Parent
    local services = {
	    game:GetService('Workspace'),
	    game:GetService('Players'),
	    game:GetService('Lighting'),
	    game:GetService('ReplicatedFirst'),
	    game:GetService('ReplicatedStorage'),
	    --game:GetService('StarterGui'),
	    game:GetService('StarterPack'),
	    game:GetService('StarterPlayer'),
	    game:GetService('SoundService'),
	    game:GetService('HttpService'),
    }
	pcall(function()
	    for i,v in pairs(services) do
		    if object:IsDescendantOf(v) then return false end
	    end
    end)
    return true
end

^^Here is one out of the many warnings
This is a table that holds a function that looks at the descendants of specific services. When the For Loop ends it claims that this is a W016 warning, saying "Function can implicitly return no values even though there's an explicit return at line 40(referring to the if statement in the for loop); add explicit empty return to silence" The problem is that there no need for me to put a return at that part of the code because I already have a return at the end of it’s main function(coreFunctions.ServiceDescendant)

That warning seems correct to me. Your inner anonymous function (inside the pcall) is missing a return statement at the end. The return statement inside your pcall also only returns out of the inner function and doesn’t return false from coreFunctions.ServiceDescendant which looks to be a mistake.