ceylon / ceylon-js

DEPRECATED
Apache License 2.0
54 stars 9 forks source link

exists & destructuring & integer value of zero fails #620

Closed jvasileff closed 9 years ago

jvasileff commented 9 years ago

For example:

    Integer[4]? example1 = [1,2,3,4];
    assert (exists [a,b,c,d] = example1); // ok

    Integer[4]? example2 = [1,2,3,0];
    assert (exists [e,f,g,h] = example2); // boom
    // Error: Assertion failed: 'exists [e,f,g,h] = example2' at run.ceylon (52:11-52:39)
lucaswerkmeister commented 9 years ago

Generated code:

var $2=m$1.tpl$([0]);
var $3;
m$1.asrt$((function($4){if(!m$1.nn$($4))return false;return($3=$4.$_get(0));}($2)),"Assertion failed: \'exists [i] = ti\' at run.ceylon (3:11-3:27)",'3:4-3:28','run.ceylon');

m$1 is the language module. asrt$ is defined in runtime-js/core_functions.js:

//for shorter assert
function asrt$(cond,msg,loc,file) {
  if (!cond)throw wrapexc(AssertionError(msg),loc,file);
}

Since 0 is falseish, !cond is true, and the assertion is thrown. I think the inline function should instead be

function($4){if(!m$1.nn$($4))return false;$3=$4.$_get(0);return true;}
jvasileff commented 9 years ago

Yeah, if I understand those hieroglyphics, example2 should be tested, but not its contents. So, this should also work:

    Integer?[4]? example2 = [1,2,3,null];
    assert (exists [e,f,g,h] = example2);
    assert (!exists h);
chochos commented 9 years ago

and the funny part is, this only happens when the last element is 0; if any other element is 0 it works fine.

lucaswerkmeister commented 9 years ago

I imagine it also happens for [true,true,false], no?

chochos commented 9 years ago

probably, yeah.

chochos commented 9 years ago

This might be the shortest modification I've ever made to fix a bug

lucaswerkmeister commented 9 years ago

Nice :D You’ve never had to turn a == into a ===?

chochos commented 9 years ago

not for a bugfix... this could have been a ,1 btw but I prefer to keep it cleaner with true.