| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
With the removal of the splatted argument when using an empty
keyword splat, the autosplat code considered an empty keyword
splat the same as no argument at all. However, that results
in autosplat behavior changing dependent on the content of
the splatted hash, which is not what anyone would expect or
want. This change always skips an autosplat if keywords were
provided.
Fixes [Bug #16560]
|
|
|
|
|
|
|
|
|
| |
Keeping empty keyword splats for ruby2_keywords methods was
necessary in 2.7 to prevent the final positional hash being
treated as keywords. Now that keyword argument separation
has been committed, the final positional hash is never
treated as keywords, so there is no need to keep empty
keyword splats when using ruby2_keywords.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
http://ci.rvm.jp/results/trunk_gcc7@silicon-docker/2539622
```
/tmp/ruby/v2/src/trunk_gcc7/class.c: In function 'rb_scan_args_parse':
/tmp/ruby/v2/src/trunk_gcc7/class.c:1971:12: warning: unused variable 'tmp_buffer' [-Wunused-variable]
VALUE *tmp_buffer = arg->tmp_buffer;
^~~~~~~~~~
```
```
In file included from /tmp/ruby/v2/src/trunk_gcc7/vm_insnhelper.c:1895:0,
from /tmp/ruby/v2/src/trunk_gcc7/vm.c:349:
/tmp/ruby/v2/src/trunk_gcc7/vm_args.c:212:1: warning: 'args_stored_kw_argv_to_hash' defined but not used [-Wunused-function]
args_stored_kw_argv_to_hash(struct args_info *args)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This removes the warnings added in 2.7, and changes the behavior
so that a final positional hash is not treated as keywords or
vice-versa.
To handle the arg_setup_block splat case correctly with keyword
arguments, we need to check if we are taking a keyword hash.
That case didn't have a test, but it affects real-world code,
so add a test for it.
This removes rb_empty_keyword_given_p() and related code, as
that is not needed in Ruby 3. The empty keyword case is the
same as the no keyword case in Ruby 3.
This changes rb_scan_args to implement keyword argument
separation for C functions when the : character is used.
For backwards compatibility, it returns a duped hash.
This is a bad idea for performance, but not duping the hash
breaks at least Enumerator::ArithmeticSequence#inspect.
Instead of having RB_PASS_CALLED_KEYWORDS be a number,
simplify the code by just making it be rb_keyword_given_p().
|
|
|
|
| |
warnings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before this commit, Kernel#lambda can't tell the difference between a
directly passed literal block and one passed with an ampersand.
A block passed with an ampersand is semantically speaking already a
non-lambda proc. When Kernel#lambda receives a non-lambda proc, it
should simply return it.
Implementation wise, when the VM calls a method with a literal block, it
places the code for the block on the calling control frame and passes a
pointer (block handler) to the callee. Before this commit, the VM
forwards block arguments by simply forwarding the block handler, which
leaves the slot for block code unused when a control frame forwards its
block argument. I use the vacant space to indicate that a frame has
forwarded its block argument and inspect that in Kernel#lambda to detect
forwarded blocks.
This is a very ad-hoc solution and relies *heavily* on the way block
passing works in the VM. However, it's the most self-contained solution
I have.
[Bug #15620]
|
|
|
|
|
|
|
|
|
|
| |
(old)
test.rb:4: warning: The last argument is used as the keyword parameter
test.rb:1: warning: for `foo' defined here; maybe ** should be added to the call?
(new)
test.rb:4: warning: The last argument is used as keyword parameters; maybe ** should be added to the call
test.rb:1: warning: The called method `foo' is defined here
|
| |
|
| |
|
|
|
|
| |
It produced a warning about type cast in LLP64 (i.e., windows).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(This is the second try of 036bc1da6c6c9b0fa9b7f5968d897a9554dd770e.)
If iseq is GC'ed, the pointer of iseq may be reused, which may hide a
deprecation warning of keyword argument change.
http://ci.rvm.jp/results/trunk-test1@phosphorus-docker/2474221
```
1) Failure:
TestKeywordArguments#test_explicit_super_kwsplat [/tmp/ruby/v2/src/trunk-test1/test/ruby/test_keyword.rb:549]:
--- expected
+++ actual
@@ -1 +1 @@
-/The keyword argument is passed as the last hash parameter.* for `m'/m
+""
```
This change ad-hocly adds iseq_unique_id for each iseq, and use it
instead of iseq pointer. This covers the case where caller is GC'ed.
Still, the case where callee is GC'ed, is not covered.
But anyway, it is very rare that iseq is GC'ed. Even when it occurs, it
just hides some warnings. It's no big deal.
|
|
|
|
|
|
|
|
|
| |
This reverts commit 036bc1da6c6c9b0fa9b7f5968d897a9554dd770e.
This caused a failure on iseq_binary mode.
http://ci.rvm.jp/results/trunk-iseq_binary@silicon-docker/2474587
Numbering iseqs is not trivial due to dump/load.
|
|
|
|
| |
This reverts commit 751a9b32e5a53336768eb878de1827245a3292bf.
|
|
|
|
| |
The function assumed that the LSB of `callee` was 0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If iseq is GC'ed, the pointer of iseq may be reused, which may hide a
deprecation warning of keyword argument change.
http://ci.rvm.jp/results/trunk-test1@phosphorus-docker/2474221
```
1) Failure:
TestKeywordArguments#test_explicit_super_kwsplat [/tmp/ruby/v2/src/trunk-test1/test/ruby/test_keyword.rb:549]:
--- expected
+++ actual
@@ -1 +1 @@
-/The keyword argument is passed as the last hash parameter.* for `m'/m
+""
```
This change ad-hocly adds iseq_unique_id for each iseq, and use it
instead of iseq pointer. This covers the case where caller is GC'ed.
Still, the case where callee is GC'ed, is not covered.
But anyway, it is very rare that iseq is GC'ed. Even when it occurs, it
just hides some warnings. It's no big deal.
|
|
|
|
|
|
|
|
| |
```
$ ./miniruby -e 'def foo(kw: 1); end; h = {kw: 1}; foo(h)'
-e:1: warning: The last argument is used as the keyword parameter
-e:1: warning: for `foo' defined here; maybe ** should be added to the call?
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
By this change, the following code prints only one warning.
```
def foo(**opt); end
100.times { foo({kw:1}) }
```
A global variable `st_table *caller_to_callees` is a map from caller to
a set of callee methods. It remembers that a warning is already printed
for each pair of caller and callee.
[Feature #16289]
|
|
|
|
|
|
| |
Previously, the rest array was modified, but it turns out that is
not necessary. Not modifying the rest array fixes cases when the
rest array is used more than once.
|
|
|
|
|
|
| |
`rb_resolve_refined_method_callable` is referenced in
`refine_sym_proc_call`, even when pre-compiling mjit header on
mswin.
|
|
|
|
|
|
|
| |
These functions are used from within a compilation unit so we can
make them static, for better binary size. This changeset reduces
the size of generated ruby binary from 26,590,128 bytes to
26,584,472 bytes on my macihne.
|
|
|
|
|
|
| |
Previously, the keyword hash was duped (which results in a regular
hash), but the dup was not marked as a keyword hash, causing the
hash not to be marked as keyword hash even though it should be.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When ruby2_keywords is used on a method, keywords passed to the method
are flagged. When the hash is passed as the last element of an
argument splat to another method, the hash should be treated as a
keyword splat. When keyword splatting a hash, a duplicate of the
hash is made. So when auto-splatting the hash with the keyword
flag, a duplicate of the hash should also be made.
This fixes cases where the hash is later passed to another method
and would be treated as keywords there:
class Object
ruby2_keywords def foo(*a) bar(*a) end
def bar(*a) baz(*a) end
def baz(*a, **kw) [a, kw] end
end
foo(:a=>1)
Previously, this would pass the :a=>1 as keywords to bar and also as
keywords to baz. Now it only passes :a=>1 as keywords to bar, but bar
passes :a=>1 as a positional hash to baz (which in this case
generates a warning in 2.7).
|
|
|
|
|
| |
VM_NO_KEYWORDS was introduced first in vm_core.h, but it is best
to only use a single definition for this.
|
| |
|
|
|
|
|
| |
We are calling this in a few other files, it is better to have it
in a header than adding prototypes to the other files.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This approach uses a flag bit on the final hash object in the regular splat,
as opposed to a previous approach that used a VM frame flag. The hash flag
approach is less invasive, and handles some cases that the VM frame flag
approach does not, such as saving the argument splat array and splatting it
later:
ruby2_keywords def foo(*args)
@args = args
bar
end
def bar
baz(*@args)
end
def baz(*args, **kw)
[args, kw]
end
foo(a:1) #=> [[], {a: 1}]
foo({a: 1}, **{}) #=> [[{a: 1}], {}]
foo({a: 1}) #=> 2.7: [[], {a: 1}] # and warning
foo({a: 1}) #=> 3.0: [[{a: 1}], {}]
It doesn't handle some cases that the VM frame flag handles, such as when
the final hash object is replaced using Hash#merge, but those cases are
probably less common and are unlikely to properly support keyword
argument separation.
Use ruby2_keywords to handle argument delegation in the delegate library.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Make sure that vm_yield_with_cfunc can correctly set the empty keyword
flag by passing 2 as the kw_splat value when calling it in
vm_invoke_ifunc_block. Make sure calling.kw_splat is set to 1 and not
128 in vm_sendish, so we can safely check for different kw_splat values.
vm_args.c needs to call add_empty_keyword, and to make JIT happy, the
function needs to be exported. Rename the function to
rb_adjust_argv_kw_splat to more accurately reflect what it does, and
mark it as MJIT exported.
|
|
|
|
|
|
|
|
| |
This makes method_missing take a flag for whether keyword arguments
were passed.
Adds tests both for rb_call_super_kw usage as well as general usage
of super calling method_missing in Ruby methods.
|
|
|
|
|
|
|
|
|
| |
Previously, the warning functions skipped warning in these cases.
This removes the skipping, and uses a less descriptive warning
instead.
This affected both last argument to keyword warnings and keyword
split warnings.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This removes an invalid keyword argument separation warning for
code such as:
```ruby
def foo(arg)
arg
end
kw = {}
foo(*[1], **kw)
```
This warning was caused because the remove_empty_keyword_hash
was set based on a comparison with two variables, and in this
case, one of the variables was updated after the check and we
need to use the updated variable.
Simplify things by just inlining the comparison.
|
|
|
|
|
|
| |
Previously, Ruby did not warn in these cases, and in some cases
did not have the same behavior. This makes calls from C handled
the same way as calls from Ruby.
|
|
|
|
| |
mame pointed out that vm_args.c is included in vm_insnhelper.c.
|
|
|
|
| |
Hopefully this fixes MJIT errors on AppVeyor.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In general, we want to ignore empty keyword hashes. The only case
where we want to allow them for backwards compatibility is when
they are necessary to satify the final required positional argument.
In that case, we want to not ignore them, but we do want to warn,
as that will be going away in Ruby 3.
This commit implements this support for regular methods and
attr_writer methods.
In order to allow send to forward arguments correctly, send no
longer removes empty keyword hashes. It is the responsibility of
the final method to remove the empty keyword hashes now. This
change was necessary as otherwise send could remove the empty
keyword hashes before the regular or attr_writer methods could
move them to required positional arguments.
For completeness, add tests for keyword handling regular
methods calls.
This makes rb_warn_keyword_to_last_hash non-static in vm_args.c
so it can be reused in vm_insnhelper.c, and also moves declarations
before statements in the rb_warn_* functions in vm_args.c.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There are two styles that argv contains keyword arguments: one is
VM_CALL_KWARG which contains value elements in argv (to avoid a hash
object creation if possible), and the other is VM_CALL_KW_SPLAT which
contains one last hash in argv.
vm_caller_setup_arg_kw translates argv from the VM_CALL_KWARG style to
the VM_CALL_KW_SPLAT style.
`calling->kw_splat` means that argv is the VM_CALL_KW_SPLAT style.
So, instead of setting `calling->kw_splat` at many places, it would be
better to do so when vm_caller_setup_arg_kw is called.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is needed for C functions to call methods with keyword arguments.
This is a copy of rb_funcall_with_block with an extra argument for
the keyword flag.
There isn't a clean way to implement this that doesn't involve
changing a lot of function signatures, because rb_call doesn't
support a way to mark that the call has keyword arguments. So hack
this in using a CALL_PUBLIC_KW call_type, which we switch for
CALL_PUBLIC later in the call stack.
We do need to modify rm_vm_call0 to take an argument for whether
keyword arguments are used, since the call_type is no longer
available at that point. Use the passed in value to set the
appropriate keyword flag in both calling and ci_entry.
|
|
|
|
|
|
|
| |
The kw_splat flag is whether the original call passes keyword or not.
Some types of methods (e.g., bmethod and sym_proc) drops the
information. This change tries to propagate the flag to the final
callee, as far as I can.
|
| |
|
|
|
|
| |
This wraps iseq_location and should fix the leaked global test.
|
|
|
|
|
|
|
|
| |
This shows locations in places it didn't before, such as for
proc calls, and fixes the location for super calls.
This requires making iseq_location non-static and MJIT exported,
which I hope will not cause problems.
|
|
|
|
|
|
|
|
|
| |
parameters
Previously, there was no warning in this case, even though we will
be changing the behavior in Ruby 3.
Fixes [Bug #14130]
|
|
|
|
| |
This warns about a case that we will continue to support.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
For methods that accept keyword arguments but do not accept a
keyword splat, if a keyword splat is passed, or keywords are
used with a non-symbol key, check the hash. If the hash contains
all symbols, keep the same behavior as before. If the hash
contains all non-symbols, move the hash to the last positional
hash and warn. If the hash contains symbols and non-Symbols, split
the hash and use the symbol keys for the keyword hash and non-symbol
keys for the positional hash and warn.
|
| |
|
|
|
|
|
|
|
|
|
| |
This syntax means the method should be treated as a method that
uses keyword arguments, but no specific keyword arguments are
supported, and therefore calling the method with keyword arguments
will raise an ArgumentError. It is still allowed to double splat
an empty hash when calling the method, as that does not pass
any keyword arguments.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This restores compatibility with Ruby 2.6, splitting the last
positional hash into positional and keyword arguments if it
contains both symbol and non-symbol keys. However, in this case
it will warn, as the behavior in Ruby 3 will be to not split the
hash and keep it as a positional argument.
This does not affect the handling of mixed symbol and non-symbol
keys in bare keywords. Those are still treated as keywords now,
as they were before this patch. This results in different
behavior than Ruby 2.6, which would split the bare keywords and
use the non-Symbol keys as a positional arguments.
|
|
|
|
|
|
|
|
| |
If all keys are not symbols, then the non-symbol keys would not
be treated as keywords in previous versions. It doesn't make
sense to treat these hashes as keywords to break compatibility and
warn about behavior changes in Ruby 2.7 when the Ruby 3.0 behavior
will be the same as the Ruby 2.6 for these hashes.
|
|
|
|
|
| |
Previously, it only applied if the call had more positional
arguments than the method it was calling accepted.
|