Skip to content

Commit 2e9286e

Browse files
Fix Integer#div returning wrong type with a Rational divisor.
Co-authored-by: Simon LeVasseur <simon.levasseur@shopify.com>
1 parent 63e2696 commit 2e9286e

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Bug fixes:
1818
* Fix `Range#bsearch` and raise `TypeError` when range boundaries are non-numeric and block not passed (@andrykonchin).
1919
* Fix using the `--cpusampler` profiler when there are custom unblock functions for `rb_thread_call_without_gvl()` (#3013, @eregon).
2020
* Fix recursive raising `FrozenError` exception when redefined `#inspect` modifies an object (#3388, @andrykonchin).
21+
* Fix `Integer#div` returning the wrong object type when the divisor is a `Rational` (@simonlevasseur, @nirvdrum).
2122

2223
Compatibility:
2324

spec/ruby/core/integer/div_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,12 @@
143143
-> { @bignum.div(-0) }.should raise_error(ZeroDivisionError)
144144
end
145145
end
146+
147+
context "rational" do
148+
it "returns self divided by the given argument as an Integer" do
149+
2.div(6/5r).should == 1
150+
1.div(6/5r).should == 0
151+
5.div(6/5r).should == 4
152+
end
153+
end
146154
end

src/main/java/org/truffleruby/core/numeric/IntegerNodes.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.truffleruby.language.NoImplicitCastsToLong;
5050
import org.truffleruby.language.NotProvided;
5151
import org.truffleruby.language.RubyBaseNode;
52+
import org.truffleruby.language.RubyGuards;
5253
import org.truffleruby.language.WarnNode;
5354
import org.truffleruby.language.control.RaiseException;
5455
import org.truffleruby.language.dispatch.DispatchNode;
@@ -495,15 +496,18 @@ public abstract static class IDivNode extends CoreMethodArrayArgumentsNode {
495496
@Specialization
496497
Object idiv(Object a, Object b,
497498
@Cached InlinedConditionProfile zeroProfile,
498-
@Cached FloatToIntegerNode floatToIntegerNode) {
499+
@Cached FloatToIntegerNode floatToIntegerNode,
500+
@Cached DispatchNode floorNode) {
499501
Object quotient = divNode.executeDiv(a, b);
500502
if (quotient instanceof Double) {
501503
if (zeroProfile.profile(this, (double) b == 0.0)) {
502504
throw new RaiseException(getContext(), coreExceptions().zeroDivisionError(this));
503505
}
504506
return floatToIntegerNode.execute(this, Math.floor((double) quotient));
505-
} else {
507+
} else if (RubyGuards.isRubyInteger(quotient)) {
506508
return quotient;
509+
} else {
510+
return floorNode.call(quotient, "floor");
507511
}
508512
}
509513

0 commit comments

Comments
 (0)