Type refinement by reference

local ShootForce:Vector3? = GunCalculator.GetShootForce(MuzzleVelocity,PrimaryPart.AssemblyLinearVelocity,MousePosition,GunPointer.Position,IndirectFire)
		
local OutOfRange = if ShootForce then false else true
OutOfRangeTracker.Value = OutOfRange
if OutOfRange then return end

local Angle = GunCalculator.AngleOfVector(ShootForce,PrimaryPart.CFrame)

The ShootForce vector3 is a vector3 when the shootpoint is in range, else it is nil. I am setting the OutOfRange bool to make this obvious, but then the final if OutOfRange then return end statement does not refine the ShootForce type, even though logically, after that line, the ShootForce must be a vector3.
The only solution I have found is by simply replacing that line with if not ShootForce then return end

Is it possible to refine a type by reference like this in one line of code? Keeping the clarity that the rest of the code should not run if it is out of range? Or is assert() the best alternative?



1 Like

I’m not knowledgeable enough about the system to know whether this is a bug or working as intended. Seems like a bug to me. You can take a look at the open GitHub type refinement issues and see if others hare experiencing what you are.

The solutions you’ve listed are pretty much all of them. If you don’t use ShootForce that often after the OutOfRange check, you could also just explicitly cast ShootForce to a Vector3

local Angle = GunCalculator.AngleOfVector(ShootForce :: Vector3, PrimaryPart.CFrame)

You can force a cast using this idiom:

v = v::Type

I hate this because it looks like it’ll waste CPU cycles, but it doesn’t. No opcodes are generated from this.

1 Like

The luau static analysis is not mature enough to pick up on these kinds of semantics.

My advice is to make your code as obvious as possible. Indirection is exactly where static analysis starts to breakdown.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.