Description
Hello! I've been coding in both Rust and Luau a lot recently, and I've found that the must_use rust lint has been very convenient, and I believe having it in my Luau code would also be beneficial. It's basically the inverse of the pre-existing Luau lint UnbalancedAssignment, and the natural companion to the ImplicitReturn lint.
I've encountered this issue a good number of times, but the most frequent is when working with custom immutable datatypes. Here's a simplified example of where things go wrong:
type Item= {
read Color: Color3
}
function setColor(item: Item, color: Color3): Item
if item.Color:ToHex() == color:ToHex() then
return item
end
local out = table.clone(item)
out.Color = color
table.freeze(out)
return out
end
-- mistake
setColor(item, Color3.new(1,0,0)) -- I've forgotten item isn't mutable
-- correct usage
item = setColor(item, Color3.new(1,0,0))
The only way I can catch this is through misbehavior at runtime, and even then the error is almost always silent - expressing itself through failed later on assertions / a general notice that the state isn't updating.
There are a few standard library usage patterns that this lint would make very obnoxious - for example, assert
and table.freeze
are commonly used without ever engaging with their returned values. Ideally, there would be some way to filter out functions. Alternatively, it could just be opt-in, something you apply to specific functions as needed.
With the "read" field attribute on the horizon when the new type-checker is ready, I think more developers than ever will work with immutable datatypes, and more than ever will encounter issues like this - this lint could save many of them headaches. Thank you for reading!