More support for record type
Problem
class RecordWithHint
type record = { foo: String, bar: Integer?, baz: Symbol? }
def test_send: () -> record
def test_csend: () -> record?
def test_block: () -> record
def test_numblock: () -> record
def test_begin: () -> record
def test_in_block: () -> Array[record]
end
class RecordWithHint
def test_send
{ foo: "hello", bar: 42, baz: nil }.itself
end
def test_csend
{ foo: "hello", bar: 42, baz: nil }&.itself
end
def test_block
{ foo: "hello", bar: 42, baz: nil }.tap{}
end
def test_numblock
{ foo: "hello", bar: 42, baz: nil }.tap{_1}
end
def test_begin
a = { foo: "hello", bar: 42, baz: nil }
a
end
def test_in_block
[1].map { { foo: "hello", bar: 42, baz: nil } }
end
end
Currently all methods are Ruby::MethodBodyTypeMismatch.
It appears that steep has lost the record type information and is interpreting it as a Hash type (::Hash[::Symbol, (::String | ::Integer | nil)]).
Expect
I hope all or some of the patterns do not result in errors.
Research
From what I have looked into, it seems difficult to support test_begin and test_in_block.
Could the other patterns be supported by giving a type hint?
This is related to the limitation of literal/tuple/record typing.
Steep type checks these special types, not Integer, Record, nor Hash, based on the context (== variable type declaration here), but the context is lost by method calls.
# @type const x: 1
x = 1 # OK
x = 1.freeze # Error
One idea is to support method calls returning self type.
Duplication of https://github.com/soutaro/steep/issues/363