Confused about the `@inline` decorator's mechanism

rescript version: 10.0.1
I have defined a module Utils in file Utils.res.

@inline
let selfAdd = v => {
  let value = v.contents
  v := value + 1
  value
}

And i called it’s function selfAdd in another file with this code below.
Demo.res

module UtilsInTheSameModule = {
  @inline
  let selfAdd = v => {
    let value = v.contents
    v := value + 1
    value
  }
}

let i = ref(0)
Js.log2(`i: `, i->Utils.selfAdd)
Js.log2(`i: `, i->UtilsInTheSameModule.selfAdd)

Here is the compiled js:
Utils.res

// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';


function selfAdd(v) {
  var value = v.contents;
  v.contents = value + 1 | 0;
  return value;
}

exports.selfAdd = selfAdd;
/* No side effect */

Demo.bs.js

// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var Utils = require("./Utils.bs.js");

function selfAdd(v) {
  var value = v.contents;
  v.contents = value + 1 | 0;
  return value;
}

var UtilsInTheSameModule = {
  selfAdd: selfAdd
};

var i = {
  contents: 0
};

console.log("i: ", Utils.selfAdd(i));

var value = i.contents;

console.log("i: ", (i.contents = value + 1 | 0, value));

exports.UtilsInTheSameModule = UtilsInTheSameModule;
exports.i = i;
/*  Not a pure module */

As you can see, the function selfAdd in module Utils is not inlined, but is inlined when it’s defined in the module UtilsInTheSameModule which is defined within the same file the calling code in.
Is it a bug of our compiler or it just has the mechanism that the inline function should be defined in the place it is called?

I think that’s the way it’s been implemented.
It would make sense to look into supporting the same behaviour across files (requiring storing some info in the compiler’s ast, as opposed to a simple preprocessing during a single file).

I created another relevant issue about function inlining, see the details here

Note the @inline serves as a heurisitc. Inlining across the files is a bit more complicated and may be addressed later

1 Like