Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions core/src/main/java/org/jruby/ir/builder/IRBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2604,15 +2604,29 @@ protected Operand buildRange(U beginNode, U endNode, boolean isExclusive) {
end = build(endNode);
}

if (begin instanceof ImmutableLiteral && end instanceof ImmutableLiteral) {
if (begin instanceof ImmutableLiteral b && end instanceof ImmutableLiteral e && isValidRange(b, e)) {
// endpoints are free of side effects, cache the range after creation
return new Range((ImmutableLiteral) begin, (ImmutableLiteral) end, isExclusive);
return new Range(b, e, isExclusive);
}

// must be built every time
return addResultInstr(new BuildRangeInstr(temp(), begin, end, isExclusive));
}

// Whether a range of these literals can be built without raising. A Range operand is built wherever its value is
// used, which can be outside a rescue or after the scope has popped its frame, so one that raises (like 1.."3",
// whose endpoints aren't comparable) has to be built by an instruction instead.
private static boolean isValidRange(ImmutableLiteral begin, ImmutableLiteral end) {
if (begin instanceof Nil || end instanceof Nil) return true;
if (isRealNumber(begin) && isRealNumber(end)) return true;
if (begin instanceof FrozenString && end instanceof FrozenString) return true;
return begin instanceof Symbol && end instanceof Symbol;
}

private static boolean isRealNumber(ImmutableLiteral literal) {
return literal instanceof Fixnum || literal instanceof Bignum || literal instanceof org.jruby.ir.operands.Float || literal instanceof Rational;
}

protected Operand buildRational(U numerator, U denominator) {
return new Rational((ImmutableLiteral) build(numerator), (ImmutableLiteral) build(denominator));
}
Expand Down
12 changes: 12 additions & 0 deletions spec/compiler/general_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@
end
end

it "raises from building a range of incomparable literals where the range appears" do
run('begin; (1.."3"); rescue ArgumentError; :rescued; end') do |x|
expect(x).to eq :rescued
end
run('def __range_error = yield rescue $!.class; [__range_error { (1.."3") }, __range_error { (:a..1) }, __range_error { (true..false) }]') do |x|
expect(x).to eq [ArgumentError, ArgumentError, ArgumentError]
end
run('[(:a..:c), (1r..2), (nil.."a"), ("a"..nil)]') do |x|
expect(x).to eq [:a..:c, 1r..2, nil.."a", "a"..nil]
end
end

it "compiles calls" do
run("'bar'.capitalize") {|result| expect(result).to eq 'Bar' }
run("rand(10)") {|result| expect(result).to be_a_kind_of Integer }
Expand Down Expand Up @@ -749,7 +761,7 @@
run(<<~'RUBY') do |x|
module RefineEqqForSplat; refine(String) { def ===(other) = other == :hit }; end
class SplatWhenWithUsing
using RefineEqqForSplat

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

already initialized constant SplatWhenWithUsing::WORDS

Check warning on line 764 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

already initialized constant SplatWhenWithUsing::WORDS
WORDS = ["x"]
def self.go(v) = case v; when *WORDS then :matched; else :unmatched; end
end
Expand Down Expand Up @@ -1350,9 +1362,9 @@

it "handles nested [], loops, and break" do
run('def foo
while 1

Check warning on line 1365 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

literal in condition

Check warning on line 1365 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

literal in condition

Check warning on line 1365 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

literal in condition

Check warning on line 1365 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

literal in condition

Check warning on line 1365 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

literal in condition

Check warning on line 1365 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

literal in condition
"x"[0]
while 1

Check warning on line 1367 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

literal in condition

Check warning on line 1367 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

literal in condition

Check warning on line 1367 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

literal in condition

Check warning on line 1367 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

literal in condition

Check warning on line 1367 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

literal in condition

Check warning on line 1367 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

literal in condition
raise "ok"
break
end
Expand Down Expand Up @@ -1626,8 +1638,8 @@
end

it "calls struct field methods" do
run('StructTest1 = Struct.new(:foo); st1 = StructTest1.new; st1.foo = 1; st1.foo') {|x| expect(x).to eq(1)}

Check warning on line 1641 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

already initialized constant StructTest1

Check warning on line 1641 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

already initialized constant StructTest1

Check warning on line 1641 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

already initialized constant StructTest1

Check warning on line 1641 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

already initialized constant StructTest1

Check warning on line 1641 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

already initialized constant StructTest1

Check warning on line 1641 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

already initialized constant StructTest1
run('StructTest2 = Struct.new(:foo); class StructTest2; def do_foo; self.foo = 1; foo; end; end; StructTest2.new.do_foo') {|x| expect(x).to eq(1)}

Check warning on line 1642 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

already initialized constant StructTest2

Check warning on line 1642 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

already initialized constant StructTest2

Check warning on line 1642 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

already initialized constant StructTest2

Check warning on line 1642 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

already initialized constant StructTest2

Check warning on line 1642 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

already initialized constant StructTest2

Check warning on line 1642 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

already initialized constant StructTest2
end

it "calls aref with string key" do
Expand Down Expand Up @@ -1726,7 +1738,7 @@
it "compiles debug chilled strings that can be modified without impacting other strings" do
JRuby.runtime.instance_config.debugging_frozen_string_literal = true
run(<<~CHILLED) {|val| expect(val).to eq("")}
str = ""

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

literal string will be frozen in the future, the string was created here: str = ""

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25)

literal string will be frozen in the future, the string was created here: /home/runner/work/jruby/jruby/spec/compiler/general_spec.rb:1741

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

literal string will be frozen in the future, the string was created here: str = ""

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27 -indy)

literal string will be frozen in the future, the string was created here: /home/runner/work/jruby/jruby/spec/compiler/general_spec.rb:1741

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

literal string will be frozen in the future, the string was created here: str = ""

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21 -indy)

literal string will be frozen in the future, the string was created here: /home/runner/work/jruby/jruby/spec/compiler/general_spec.rb:1741

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

literal string will be frozen in the future, the string was created here: str = ""

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 25 -indy)

literal string will be frozen in the future, the string was created here: /home/runner/work/jruby/jruby/spec/compiler/general_spec.rb:1741

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

literal string will be frozen in the future, the string was created here: str = ""

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 21)

literal string will be frozen in the future, the string was created here: /home/runner/work/jruby/jruby/spec/compiler/general_spec.rb:1741

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

literal string will be frozen in the future, the string was created here: str = ""

Check warning on line 1741 in spec/compiler/general_spec.rb

View workflow job for this annotation

GitHub Actions / rake spec:compiler (Java 27)

literal string will be frozen in the future, the string was created here: /home/runner/work/jruby/jruby/spec/compiler/general_spec.rb:1741
str << "hello"
""
CHILLED
Expand Down
Loading