Skip to content

Commit 310f055

Browse files
committed
[GR-29828] Fix Kernel#raise argument handling using *args
PullRequest: truffleruby/2497
2 parents cc02ab8 + 44c3afa commit 310f055

File tree

5 files changed

+47
-1
lines changed

5 files changed

+47
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Bug fixes:
2121
* Fix usage of `Thread.handle_interrupt` in `MonitorMixin#mon_synchronize`.
2222
* Fixed `TruffleRuby.synchronized` to handle guest safepoints (#2277).
2323
* Fix control flow bug when assigning constants using ||= (#1489).
24+
* Fix `Kernel#raise` argument handling for hashes (#2298).
2425

2526
Compatibility:
2627

spec/ruby/shared/kernel/raise.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,28 @@
1212
ScratchPad.recorded.should be_nil
1313
end
1414

15+
it "accepts an exception that implements to_hash" do
16+
custom_error = Class.new(StandardError) do
17+
def to_hash
18+
{}
19+
end
20+
end
21+
error = custom_error.new
22+
-> { @object.raise(error) }.should raise_error(custom_error)
23+
end
24+
25+
it "allows the message parameter to be a hash" do
26+
data_error = Class.new(StandardError) do
27+
attr_reader :data
28+
def initialize(data)
29+
@data = data
30+
end
31+
end
32+
-> { @object.raise(data_error, {:data => 42}) }.should raise_error(data_error) do |ex|
33+
ex.data.should == {:data => 42}
34+
end
35+
end
36+
1537
it "raises RuntimeError if no exception class is given" do
1638
-> { @object.raise }.should raise_error(RuntimeError, "")
1739
end

spec/tags/core/fiber/raise_tags.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ fails:Fiber#raise does not accept only error message and backtrace information
2222
fails:Fiber#raise raises a FiberError if invoked from a different Thread
2323
fails:Fiber#raise kills Fiber
2424
fails:Fiber#raise raises a FiberError if invoked on a transferring Fiber
25+
fails:Fiber#raise accepts an exception that implements to_hash
26+
fails:Fiber#raise allows the message parameter to be a hash

src/main/ruby/truffleruby/core/kernel.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,8 @@ def warn(*messages, uplevel: undefined)
688688
end
689689
module_function :warn
690690

691-
def raise(exc = undefined, msg = undefined, ctx = nil, cause: undefined)
691+
def raise(*args)
692+
exc, msg, ctx, cause = Truffle::KernelOperations.extract_raise_args(args)
692693
cause_given = !Primitive.undefined?(cause)
693694
cause = cause_given ? cause : $!
694695

src/main/ruby/truffleruby/core/truffle/kernel_operations.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,26 @@ def self.normalize_backtrace_args(omit, length)
210210
[omit, length]
211211
end
212212

213+
def self.extract_raise_args(args)
214+
# exc = undefined, msg = undefined, ctx = nil, cause: undefined
215+
cause = undefined
216+
unless args.empty?
217+
last_arg = args.last
218+
if Primitive.object_kind_of?(last_arg, Hash) &&
219+
last_arg.key?(:cause)
220+
cause = last_arg.delete(:cause)
221+
args.pop if last_arg.empty?
222+
end
223+
end
224+
Truffle::Type.check_arity(args.size, 0, 3)
225+
[
226+
args.size >= 1 ? args[0] : undefined,
227+
args.size >= 2 ? args[1] : undefined,
228+
args[2],
229+
cause
230+
]
231+
end
232+
213233
KERNEL_FROZEN = Kernel.instance_method(:frozen?)
214234
private_constant :KERNEL_FROZEN
215235

0 commit comments

Comments
 (0)