New Issue: Using operator methods instead of standalone operator functions may thwart out intent optimizations?

17429, "lydia-duncan", "Using operator methods instead of standalone operator functions may thwart out intent optimizations?", "2021-03-18T20:04:52Z"

Summary of Problem

When trying to adjust the following program to use an operator method instead of an operator function, the output generated by the program greatly increased.

Here is the output for the simplified program when the operator is defined as a standalone function:

test1
init 1 1
(x = 1, ptr = {xx = 1})
deinit 1 1

And here is the increased output when the operator is defined as a method:

test1
init (default)
init (default)
init 1 1
lhs(0 0) = rhs(1 1)
deinit 1 1
lhs(0 0) = rhs(1 1)
deinit 1 1
(x = 1, ptr = {xx = 1})
deinit 1 1

Steps to Reproduce

Here's the shorter version of the modified program. The program contains other variations with out intents and at a quick glance they seem similarly impacted. Similar programs that used in or inout intents did not seem impacted.

Source Code:

class C {
  var xx: int = 0;
}

record R {
  var x: int = 0;
  var ptr: shared C = new shared C(0);
  proc init() {
    this.x = 0;
    this.ptr = new shared C(0);
    writeln("init (default)");
  }
  proc init(arg:int) {
    this.x = arg;
    this.ptr = new shared C(arg);
    writeln("init ", arg, " ", arg);
  }
  proc init=(other: R) {
    this.x = other.x;
    this.ptr = new shared C(other.ptr.xx);
    writeln("init= ", other.x, " ", other.ptr.xx);
  }
  proc deinit() {
    writeln("deinit ", x, " ", ptr.xx);
  }
  proc toString() {
    return "(" + this.x:string + " " + this.ptr.xx:string + ")";
  }
  proc set1() {
    this.x = 1;
    this.ptr.xx = 1;
    return this;
  }
}
operator R.=(ref lhs:R, rhs:R) { // This line causes the difference in output, though maybe indirectly
  writeln("lhs", lhs.toString(), " = rhs", rhs.toString());
  lhs.x = rhs.x;
  lhs.ptr = new shared C(rhs.ptr.xx);
}

proc makeR() {
  return new R(1);
}
proc makeR(arg: int) {
  return new R(arg);
}

proc out1(out arg: R) {
  arg = makeR();
}

proc test1() {
  writeln("test1");
  var x: R;
  out1(x);
  writeln(x);
}
test1();

Compile command:
chpl foo.chpl

Execution command:
./foo

Associated Future Test(s):
This prevented the update of test/types/records/intents/out-intent.chpl to use operator methods instead of standalone operator functions. It may also be responsible for mismatches when updating the following programs in similar ways:

  • test/types/records/split-init/inner-fn.chpl
  • test/types/records/split-init/split-init-global1.chpl
  • test/types/records/split-init/split-init-out-on.chpl
  • test/library/standard/Types/copyable-custom-records.chpl
  • test/types/chplhashtable/test-chpl-hashtable.chpl

Configuration Information

  • Output of chpl --version: chapel 1.25 (pre-release)