This repository was archived by the owner on Aug 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
This repository was archived by the owner on Aug 23, 2020. It is now read-only.
Invalid mutation for a bare rescue inside a method with a kwarg splat signature #85
Copy link
Copy link
Open
Labels
Description
Minimal code to reproduce
def foo(**bar)
rescue Baz
endAST of original code
(def :foo
(args
(kwrestarg :bar))
(rescue nil
(resbody
(array
(const nil :Baz)) nil nil) nil))Invalid AST
(def :foo
(args
(kwrestarg :bar))
(begin
(lvasgn :bar
(hash))
(rescue nil
(resbody
(array
(const nil :Baz)) nil nil) nil)))Error
$ bundle exec ruby example.rb
warning: parser/current is loading parser/ruby24, which recognizes
warning: HEAD-compliant syntax, but you are running 2.4.1.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
/Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/literal/primitive.rb:39: warning: constant ::Fixnum is deprecated
/Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/literal/primitive.rb:40: warning: constant ::Bignum is deprecated
/Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:128:in `emitter': undefined method `type' for nil:NilClass (NoMethodError)
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:256:in `emitter'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:198:in `visit_plain'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/rescue.rb:58:in `emit_standalone'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/rescue.rb:28:in `dispatch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:104:in `write_to_buffer'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `call'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `block (3 levels) in create_memoized_method'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:63:in `block (3 levels) in fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/thread_safe-0.3.5/lib/thread_safe/cache.rb:58:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:62:in `block (2 levels) in fetch'
from /Users/johnbackus/.rubies/ruby-2.4.1/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:61:in `block in fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/thread_safe-0.3.5/lib/thread_safe/cache.rb:58:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:60:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:116:in `block (2 levels) in create_memoized_method'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:199:in `visit_plain'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/begin.rb:19:in `block in emit_inner'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/begin.rb:18:in `each'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/begin.rb:18:in `each_with_index'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/begin.rb:18:in `emit_inner'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/begin.rb:53:in `dispatch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:104:in `write_to_buffer'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `call'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `block (3 levels) in create_memoized_method'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:63:in `block (3 levels) in fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/thread_safe-0.3.5/lib/thread_safe/cache.rb:58:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:62:in `block (2 levels) in fetch'
from /Users/johnbackus/.rubies/ruby-2.4.1/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:61:in `block in fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/thread_safe-0.3.5/lib/thread_safe/cache.rb:58:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:60:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:116:in `block (2 levels) in create_memoized_method'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:199:in `visit_plain'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:472:in `block in visit_indented'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:437:in `indented'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:472:in `visit_indented'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:457:in `emit_body'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter/def.rb:38:in `dispatch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser/emitter.rb:104:in `write_to_buffer'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `call'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `block (3 levels) in create_memoized_method'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:63:in `block (3 levels) in fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/thread_safe-0.3.5/lib/thread_safe/cache.rb:58:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:62:in `block (2 levels) in fetch'
from /Users/johnbackus/.rubies/ruby-2.4.1/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:61:in `block in fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/thread_safe-0.3.5/lib/thread_safe/cache.rb:58:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/memory.rb:60:in `fetch'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:116:in `block (2 levels) in create_memoized_method'
from /Users/johnbackus/.gem/ruby/2.4.1/gems/unparser-0.2.5/lib/unparser.rb:29:in `unparse'
from example.rb:14:in `block in <main>'
from /Users/johnbackus/.rubies/ruby-2.4.1/lib/ruby/2.4.0/set.rb:324:in `each_key'
from /Users/johnbackus/.rubies/ruby-2.4.1/lib/ruby/2.4.0/set.rb:324:in `each'
from example.rb:13:in `<main>'Invalid mutation
(def :foo
(args
(kwrestarg :bar))
(begin
(lvasgn :bar
(hash))
(rescue nil
(resbody
(array
(const nil :Baz)) nil nil) nil)))The faulty mutation is trying to insert bar = {} at the beginning of the mutation but it should be wrapping the body in a kwrestarg in this case which would look like
def foo(**bar)
begin
bar = {}
rescue Baz
end
endThe mutation emitted uses a normal begin which does not correspond to the begin keyword but instead parens. The closest source representing the invalid operation would be
def foo(**bar)
(
bar = {}
rescue Baz
)
endwhich is invalid due to the presence of the rescue.
This only happens in the cases where mutest thinks it can inline a default argument. Another reproduction is
mutate(<<-RUBY)
def foo(bar = 1)
rescue Baz
end
RUBYThanks @JTBooth for helping find this