JVM / JS behavior mismatch for `Range<Element>` satisfying `{Element+}`at runtime
Closed this issue · 3 comments
someth2say commented
The following code:
shared void run() {
value manual = {{1,2,3,4,5,6,7,8,9,10}};
value firstMan = manual.first;
if (is {Integer+} firstMan) {print ("ok");} else { print("Ups.."); } // Ok
if (is {{Integer+}+} manual) { print("ok"); } else { print("Ups.."); } // Ok
value range = { 1:10 };
value firstRan = range.first;
if (is {Integer+} firstRan) {print ("ok");} else { print("Ups.."); } // Ok
if (is {{Integer+}+} range) { print("ok"); } else { print("Ups.."); } // Ups...
}
Prints three Ok
and one Ups..
in JVM, but four Ok
in JS (Web Ide).
Seems related to the fact 1:10
is not just a {Integer+}
, but a []|{Integer+}
.
gavinking commented
This is a bug in the JS compiler. Here is a simple program that demonstrates unsoundness:
shared void run() {
assert (is {{Integer+}+} emptyRangeStream = { 1:-10 }); //should fail here, but doesn't
Integer i = emptyRangeStream.first.first;
print(i.string); //blows up here
}
This program should cause an assertion failure. But instead it blows up at the print()
statement.
chochos commented
Something in the is
function, apparently:
Object foo = {1:-10};
if (is {{Integer+}+} foo) { //shouldn't happen but we go in
Object bar = foo.first;
print(bar); //[]
print(className(bar)); //c.l::empty
print(bar is {Integer+}); //FALSE
}
Actually this even fails with foo = {[]}