class RuboCop::Cop::Sorbet::VoidCheckedTests
sig { void.checked(:never) }
sig { returns(T.anything).checked(:tests) }
sig { void }
# good
sig { void.checked(:tests) }
# bad
@example
earlier. Versions released after 2023-04-14 include ‘T.anything`.)
which does not have `T.anything` (meaning versions 0.5.10781 or
- Use `.void.checked(:never)` if you are on an older version of Sorbet
checking for the rest of the parameters.
- Use `.returns(T.anything).checked(:tests)` to keep the runtime type
falsy depending on the method’s implementation.
will be the truthy ‘VOID` value, while the non-test return value may be
result of a `.void` method, because the returned value in test code
environments. This is particularly troublesome if branching on the
will return different values in tests compared with non-test
runtime type checking is enabled for the method. Methods marked `.void`
Using `.void` changes the value returned from the method, but only if
Disallows the usage of `.void.checked(:tests)`.
def on_signature(node)
def on_signature(node) checked_send = checked_tests(node).first return unless checked_send if (parent = node.parent) && (sibling_index = node.sibling_index) later_siblings = parent.children[(sibling_index + 1)..] if (def_node = later_siblings.find { |sibling| sibling.is_a?(RuboCop::AST::DefNode) }) # Sorbet requires that `initialize` methods return `.void` # (A stylistic convention which happens to be enforced by Sorbet) return if def_node.method?(:initialize) end end void_send = top_level_void(node.body) return unless void_send add_offense( void_send.selector, message: MESSAGE, ) do |corrector| corrector.replace(void_send.selector, "returns(T.anything)") end end
def top_level_void(node)
def top_level_void(node) unless node.is_a?(RuboCop::AST::SendNode) e.method?(:void) (recv = node.receiver) level_void(recv)