luau icon indicating copy to clipboard operation
luau copied to clipboard

Solver fails in case of narrowing known type against truthy values

Open OverHash opened this issue 1 year ago • 3 comments

Using the new type solver fails on degenerate cases when type checking

For example, in Roblox, the following code causes a type error:

--!strict

local function foo(player: Player)
	if player and player.Character and player.Character:FindFirstChild("Humanoid") then
		local humanoid = player.Character:FindFirstChildWhichIsA("Humanoid")
		assert(humanoid, `Failed to find {player.Character:GetFullName()}.Humanoid`)

		if player.Character:HasTag("someTag") then
			player.Character:FindFirstChild("RagdollConstraints"):Destroy()
		end
	end
end

Hovering over player inside the innermost if statement indicates the type is inferred as

A type error of
refine<never, {
Character: blocked-5951724
}>
Cannot call a value of type 'blocked-5951699'

refine<never, {
	Character: *blocked-5951724*
}>
Cannot call a value of type 'blocked-5951699'

OverHash avatar Sep 18 '24 07:09 OverHash

Hope the title is somewhat reasonable to describe the case, feel free to update.

OverHash avatar Sep 18 '24 07:09 OverHash

A similar example. If you call a function with a variable given as a parameter in an if condition, then that variable becomes never in the body of the if statement.

Note that if I swap out Item for a primitive such as string, it works fine. If I swap the condition from predicate(value) to any of predicate(), predicate(true), value or true, it works fine.

type Item = {}

local function predicate(value: Item): bool
	return true
end

local function checkValue(value: Item)
	if predicate(value) then
		print(value) -- value: never
	end
end

JohnnyMorganz avatar Feb 15 '25 19:02 JohnnyMorganz

Sounds like the issue is specifically using the result of function calls in if statements directly then?

OverHash avatar Feb 17 '25 04:02 OverHash

Fixed in release 663

OverHash avatar Jun 10 '25 23:06 OverHash