Rescript-compiler: Short-circuiting of && fails due to extraction of variable

Created on 11 Mar 2018  路  1Comment  路  Source: rescript-lang/rescript-compiler

On the following code the compiler extracts an intermediate variable from the subexpression after && that is always evaluated, causing List.hd to fail even though there is a check for it's length earlier in the expression.

let enableMidGameHunting = false;
let len = List.length;
let nearestGroots = [];
let isEmpty = x => List.length(x) == 0;
let flt = List.filter;
let d = (a, b) => 0;
let head = x => List.hd(x);
let mapWidth = 1920;
let oppHeroes = [0, 0];
let myMelees = [];
let oppMelees = [];
let bothHealthPct = 0.0;
let forwardOpp = 0;
let myTower = 0;
let myHeroesClose = [];
let myHeroes = [];
let huntGrootCondition =
      enableMidGameHunting
      && len(nearestGroots) > 0
      && isEmpty(
           flt(h => d(h, head(nearestGroots)) <= mapWidth / 3, oppHeroes)
         )
      && (
        len(myMelees) >= len(oppMelees)
        || bothHealthPct < 0.25
        && d(forwardOpp, myTower) <= mapWidth
        / 2
      )
      && len(myHeroesClose) == len(myHeroes);
Js.log(huntGrootCondition);

See also https://reasonml.github.io/en/try.html?reason=DYUwLgBCB2CGBGoCyBLAJgcVgWxACQFdowVoBzCAXggDNZgBnEAbgChRJRoqIAZFBmAB0XMmAAWbDhGghYAJxCCM8gPaqwDHgG0AulPAQBAUWwAHMAE8eADyoA+PgOGiJAChsBKKtQAMByBpgSGp+QSEaFGCQeQCINB43WAAaCHhvSkd-dkNxOQTqO0yncPE0D0847FgzAHV0CR4ARgBOACZs6VUzMzwY1SUdX1TffRzIbEskEFBB6j047rNp2a15sel4DXE++gkABQBjEIhfIU7DGlV5AHcFNAB5Hp4LicsAFVUbmJeqyz61EoAMLAVRMHQbQyTAEDNYQBbjCDiIhgFTqMBA1TQNAoEhYqisCBE4kwBDIdBYXCEYikMiE4lEgBkjIgXDcsgUSlRag0DG8WXpDOZRgYpgsljcgoZDKCYDc4gc8XlqTysHKHMUyh5mk83gAPNRqnUGgqAPQQADMqSWMKUnil0vt0ogwslzqJbMmKxAdog9mobKW3rtDuJAB8w2ltrtguIjpA9achG0AKyhpks8pXW73J5mVKTT7feT6w01epoCTpiDmtqhp3S4We-79YGgpgZAMwNzQ1t8tgAKQYIlUZHlKLRGkx2NxKCxlSAA .

HIGH bug

Most helpful comment

Here's a minimal example:

let nearestGroots = [];
let isEmpty = x => List.length(x) == 0;
let oppHeroes = [0];
let huntGrootCondition =
      List.length(nearestGroots) > 0
      && isEmpty(
           List.filter(h => List.hd(nearestGroots) <= 1000, oppHeroes)
         );
Js.log(huntGrootCondition);

>All comments

Here's a minimal example:

let nearestGroots = [];
let isEmpty = x => List.length(x) == 0;
let oppHeroes = [0];
let huntGrootCondition =
      List.length(nearestGroots) > 0
      && isEmpty(
           List.filter(h => List.hd(nearestGroots) <= 1000, oppHeroes)
         );
Js.log(huntGrootCondition);
Was this page helpful?
0 / 5 - 0 ratings