New Issue: 'Reflection.canResolveMethod' and formals with type 'this.type' don't get along well

16673, “e-kayrakli”, “‘Reflection.canResolveMethod’ and formals with type ‘this.type’ don’t get along well”, “2020-11-06T00:50:55Z”

There is a bug (quirk?) with canResolveMethod that these where clauses should remain or I should change this.type in the formal declaration to something more explicit.

use Reflection;

record R {
  var x;

  proc foo(r: this.type) {
    compilerWarning("Resolving foo. this.type: ", this.type:string, 
                                  " r.type: ", r.type:string);
  }

  proc bar(r: R(int(64))) {
    compilerWarning("Resolving foo. this.type: ", this.type:string, 
                                  " r.type: ", r.type:string);
  }

  proc baz(r: R(this.x.type)) {
    compilerWarning("Resolving foo. this.type: ", this.type:string, 
                                  " r.type: ", r.type:string);
  }
}

var r1 = new R(5);
var r2 = new R(5.2);

compilerWarning("Can resolve foo? ", canResolveMethod(r1, "foo", r2):string);
compilerWarning("Can resolve bar? ", canResolveMethod(r1, "bar", r2):string);
compilerWarning("Can resolve baz? ", canResolveMethod(r1, "baz", r2):string);

Generates:

$CHPL_HOME/canResolveBug.chpl:6: In method 'foo':
$CHPL_HOME/canResolveBug.chpl:7: warning: Resolving foo. this.type: R(int(64)) r.type: R(real(64))
  $CHPL_HOME/modules/standard/Reflection.chpl:290: called as R(int(64)).foo(r: R(real(64))) from function 'canResolveMethod'
  $CHPL_HOME/canResolveBug.chpl:1: called as canResolveMethod(obj: _any, param fname = "foo": string, args(0): _any)
note: generic instantiations are underlined in the above callstack
$CHPL_HOME/canResolveBug.chpl:1: In module 'canResolveBug':
$CHPL_HOME/canResolveBug.chpl:25: note: Can resolve foo? true
$CHPL_HOME/canResolveBug.chpl:26: warning: Can resolve bar? false
$CHPL_HOME/canResolveBug.chpl:27: warning: Can resolve baz? false

Where if the formal type is this.type we don’t match against the generic fields and try to resolve the function.

I think canResolveMethod should return false for foo and not try to resolve the function body.

Note that I can use this.type in the method body and it works as you’d expect:

record R {
  var x;

  proc generateNewR() {
    var r: this.type;
    return r;
  }
}

var r = new R(5);
writeln(r.generateNewR().type:string);  // prints R(int(64))