Lints
Updatedalloy flux and alloy lint run them. The [lint] table in alloy.toml sets deny, warn, and allow lists by lint or by group, and strict = true turns the pedantic group on. A lint whose rewrite keeps the program the same carries that rewrite, and alloy flux --fix applies it. The language server shows the same lints as warnings.
correctness 18
Code that is wrong, or cannot run.
optional_accessA value that may be nil is indexed without a guard.needless_assertA
! on a value the file types as never nil.dropped_resultA call of a Result function whose value nothing reads.static_callA static of an impl called with :.argument_countA call passes more arguments than the function takes.unreachable_defaultA default arm after arms that cover every variant.empty_defaultA default arm with an empty body.unused_importAn imported name the file never uses.self_assignmentx = x, an assignment that changes nothing.unreachable_codeA statement after return, break, or continue.constant_conditionif true, if false, or if nil.duplicate_keyA table constructor that sets one key twice.misplaced_notnot a == b, which compares not a to b.identical_branchesAn if whose then and else bodies are the same.private_accessA private field or method read outside its struct's impl.duplicate_functionOne name given a function body twice.identity_compare== or ~= with a new payload variant or a new struct of a type that derives no Eq.circular_importTwo files that import each other.suspicious 12
Code that is probably not what the author meant.
single_angle_callA call that writes its type arguments in one
<...>.deprecated_namespaceA use of a namespace declared @deprecated.stale_exportA write to an exported local inside a function.deprecated_callA : call of an impl method declared @deprecated.and_or_ternaryc and a or b in place of a ternary.unused_variableA local that nothing reads.unused_functionA function that nothing calls.empty_blockAn if, else, or loop body with nothing in it.bool_comparisonx == true or x == false.needless_boolif c then return true else return false end.array_long_stringA long string whose text reads like a nested array.pattern_shadows_localA match pattern that binds the name of a local in scope.style 22
A Luau habit with an Alloy form.
prefer_destroy
delete part on a plain Instance, where destroy part says it.manual_safe_accessa and a.b, the guard written by hand.manual_coalesceif x == nil then x = v end, a coalescing assignment by hand.nil_check_callif f then f(...) end, an optional call by hand.manual_type_testtypeof(x) == "T" in place of x is T.prefer_constA local that nothing assigns again.redundant_asas before a declaration body on the next line.match_guard_andA match guard written with and.legacy_iteratorpairs or ipairs around a for ... in table.manual_floor_divmath.floor(a / b) in place of a // b.manual_pushtable.insert or table.remove on a value typed as an Array.concat_interpolationA .. chain that joins literals and values.raw_pcallA pcall or xpcall.raw_requireA require where an import would do.game_alias"game" or "game:X", the service path before the alias.manual_classX.__index = X, the class idiom by hand.prefer_newX.new(...) in place of new X(...).manual_ternary_returnif c then return a else return b end.redundant_returnA bare return at the end of a function.local_then_returnlocal x = v followed by return x.numeric_for_indexfor i = 1, #t do local v = t[i].missing_reasonAn --@alloy-expect-error with no reason.complexity 6
A simple thing done in a hard way; the limits sit in [flux].
too_many_argumentsA function with more parameters than
[flux] too_many_arguments.too_many_linesA function longer than [flux] too_many_lines.deep_nestingBlocks nested deeper than [flux] max_nesting.cognitive_complexityA function whose branches score past [flux] cognitive_complexity.collapsible_ifif a then if b then ... end end.collapsible_else_ifelse if ... end end in place of elseif.perf 3
Code that runs slower than the plain form.
roblox 5
A Roblox API that is deprecated or misused.
deprecated_globalA call to
wait, spawn, delay, or unpack.manual_child_lookup:FindFirstChild("X") or :WaitForChild("X") with a literal name.deprecated_methodA lowercase Roblox method: :connect, :wait, :remove, :clone.instance_new_parentInstance.new(class, parent) or new Instance(class, parent), the parent as an argument.deprecated_body_moverBodyVelocity, BodyPosition, BodyGyro, and the other body movers.pedantic 8
Strict rules, off until [lint] strict = true.
explicit_anyAn annotation of
any.implicit_anyA named function parameter, or an empty array literal, with no type.missing_return_typeA public function with no return type.todo_commentA TODO, FIXME, XXX, or HACK comment.print_debugA print call.const_mutationA write into the value a const holds.missing_docAn exported declaration with no comment above it.missing_doc_typeAn exported type alias or interface with no comment above it.naming 1
The case of names, off until [lint] warn = ["naming"].
alx 1
Markup in .alx files that does not do what it reads as.
