-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RBS additions #1
Conversation
rb_class_new_instance() automatically passes the block forward to the initialize method. That way the block of a callback is forwarded to the Struct initializer, like here in the specs: s = LibTest::S8F32S32.new ret = LibTest.testCallbackVrT { s } Struct#initialize ignores the block, so that the code works, but it doesn't make sense. This stood up when enabling rbs type checks, which complained about an unspecified block to Struct#initialize.
They stood up when running with rbs type checks enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By Struct#layout
you meant Struct.layout
(AKA Struct::layout
).
Test failures show that a [Symbol, Integer]
2-tuple is also valid to come after a member name. This wasn’t documented.
layout :a, :int, :c, :test_enum, :d, [ TestEnum, TestEnum.symbols.length ]layout( :a, [:char, 10], :i, :int, :f, :float, :d, :double, :s, :short, :l, :long, :j, :long_long, :c, :char )
It’d be more consistent (to type check with, as well) if the array form has each entry be a 2–3 tuple in the form [Symbol name, layout_type type, ?Integer offset]
.
[Update]
I thought the integer in the 2-tuple is the offset, but the tuple actually stands for an array, with the first element as the field type and the interger the array size.
This is documented in “Char arrays” in the wiki, though the array can be of any type.
def []: (Symbol query) -> Integer | ||
| (Integer query) -> Symbol | ||
| (Integer query) -> Symbol? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If so, may as well?
def []: (Symbol query) -> Integer | |
| (Integer query) -> Symbol | |
| (Integer query) -> Symbol? | |
def []: (Symbol query) -> Integer? | |
| (Integer query) -> Symbol? |
RBS for Ruby Core classes like ::Array
does it like this:
def []: (Symbol query) -> Integer | |
| (Integer query) -> Symbol | |
| (Integer query) -> Symbol? | |
def []: %a{implicitly-returns-nil} (Symbol query) -> Integer | |
| %a{implicitly-returns-nil} (Integer query) -> Symbol |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please decide on your own? I only read a crash course about RBS and static typing...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
%a{implicitly-returns-nil}
doesn’t work with RBS Tests.
) -> self | ||
|
||
# ?blocking: boolish?, ?convention: Library::convention?, ?enums: Enums? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See ruby/rbs#1639
For now, it’s more intuitive if there isn’t a blank line gapping #initialize
and this comment.
@@ -28,7 +27,6 @@ module FFI | |||
def read_string_length: (Integer len) -> String | |||
def read_string_to_null: () -> String | |||
def slice: (Integer offset, Integer length) -> Pointer | |||
def to_ptr: () -> self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to indicate that Pointer#to_ptr
returns self
(which is a Pointer
).
@@ -159,6 +159,6 @@ module FFI | |||
def write_array_of_long_long: (Array[Integer] ary) -> self | |||
def write_array_of_float: (Array[Numeric] ary) -> self | |||
def write_array_of_double: (Array[Numeric] ary) -> self | |||
def write_array_of_pointer: (Array[Pointer::_ToPtr] ary) -> self | |||
def write_array_of_pointer: (Array[Pointer::_ToPtr?] ary) -> self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that nil
is also accepted whereëver _ToPtr
is, would type pointer = _ToPtr?
in Pointer
RBS be a valuable addition?
RBS builtins has things like type int = Integer | _ToInt
, albeit they’re redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please decide on your own?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s implicit, but #(put|write)_array_of_pointer
also accepts Integer elements (but not #to_int
s since they share the conversion implementation with #(put|write)_pointer
.
While FFI currently only mention #to_ptr
in AbstractMemory
, the _ToPtr?|Integer
pattern is useful in user libraries’ (i.e., bindings based on FFI) RBS as well, so I’ll surface the type alias to the FFI
namespace.
# TODO: leads to a endless recursion when used with -rrbs/test/setup | ||
# def attach: (Module mod, String name) -> self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps porting Function#attach
to Ruby (similar to its cousin, VariadicInvoker#attach
) and flatten the RegisterAttach
private module away would solve/workaround this problem.
Did you know that even CRuby is migrating some implementations from C to Ruby?
With all the JIT improvements, Ruby code’s performance is rivaling that of C itself!
In fact, it makes sense to me if Function
and VariadicInvoker
share some implementations with a common ancestor module, or even (if past design decisions aren’t in the way) have VariadicInvoker
inherit from Function
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened an issue regarding the stack level too deep.
For better readability. And add some comments.
Similar to commit 5b4b406 rb_class_new_instance() automatically passes the block forward to the initialize method. That way the block of an array function is forwarded to the Struct initializer. Struct#initialize ignores the block, so that the code works, but it doesn't make sense. This stood up when enabling rbs type checks, which complained about an unspecified block to Struct#initialize.
11) MemoryPointer allows writing as a sized int Failure/Error: put(type, 0, value) RBS::Test::Tester::TypeError: TypeError: [FFI::AbstractMemory#put] ArgumentTypeError: expected `bot` (value) but given `1`
11) MemoryPointer allows writing as a sized int Failure/Error: m.write :uint32, 1 RBS::Test::Tester::TypeError: TypeError: [FFI::Pointer#write] ArgumentTypeError: expected `bot` (value) but given `1` # /home/lars/.rvm/gems/ruby-3.3.0/gems/rbs-3.4.1/lib/rbs/test/tester.rb:158:in `call' # /home/lars/.rvm/gems/ruby-3.3.0/gems/rbs-3.4.1/lib/rbs/test/observer.rb:10:in `notify' # /home/lars/.rvm/gems/ruby-3.3.0/gems/rbs-3.4.1/lib/rbs/test/hook.rb:178:in `ensure in write__with__RBS_TEST_eb5149_4888829b' # /home/lars/.rvm/gems/ruby-3.3.0/gems/rbs-3.4.1/lib/rbs/test/hook.rb:178:in `write__with__RBS_TEST_eb5149_4888829b' # ./spec/ffi/rbx/memory_pointer_spec.rb:65:in `block (2 levels) in <top (required)>' # ------------------ # --- Caused by: --- # RBS::Test::Tester::TypeError: # TypeError: [FFI::AbstractMemory#put] ArgumentTypeError: expected `bot` (value) but given `1` # /home/lars/.rvm/gems/ruby-3.3.0/gems/rbs-3.4.1/lib/rbs/test/tester.rb:158:in `call'
By convention as discussed in ParadoxV5#1 (comment)
Happy new year as well @ParadoxV5 !
I did some minor adjustments to the CI to make it green. Then I checked the RBS files against the specs and was surprised about the many failures. So I went further to fix them in the subsequent commits.
I used the following command line:
I was able to fix most RBS issues, but a few specs fail with mismatch in
Struct#layout
. I wasn't able to fix it properly. AndFunction#attach
fails with endless recursion. Probably an incompatibility withsuper
call and theprepend
methodCould you please check my additions?